Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
branch: master
Fetching contributors…

Cannot retrieve contributors at this time

352 lines (326 sloc) 38.669 kb
<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>sencjw: blog</title>
<link>http://sencjw.com</link>
<description><![CDATA[This feed is for blog entries]]></description>
<atom:link href="http://sencjw.com/feed.rss" rel="self"
type="application/rss+xml" />
<lastBuildDate>Thu, 08 Jan 2015 00:00:00 UT</lastBuildDate>
<item>
<title>The Quick Hack v. Developing Software</title>
<link>http://sencjw.com/posts/2015-01-08-the-quick-hack.html</link>
<description><![CDATA[<article>
<header>
<h1>The Quick Hack v. Developing Software</h1>
<p>
Posted on January 8, 2015
</p>
</header>
<p>I find that I operate in one of two <em>modes</em> when I’m writing software. I’m either approaching a project as <em>a quick hack</em> or as <em>developing software</em>. As much as anything else, this affects how I approach the project and what kinds of results that I get.</p>
<p>When I’m operating under the auspices of the quick hack, everything is moving toward and subordinate to the goal. The end product of the quick hack is everything. I approach the actual hacking in a fit of pique, it’s <em>annoying</em> that this thing isn’t done yet. I always take the way that’s most expedient and I’m always looking for a shortcut or quick fix.</p>
<p>When I set out to <em>develop software</em> my mindset is different. Here I’m nurturing a seed of an idea. I’m taking small pieces and building connections between them. I have the sense that I’m making something new, or at least I’m making something that’s <em>mine</em> – I feel ownership. I also assume that the thing that I’m building has to last.</p>
<p>The natural habitat of a quick hack is a framework. When I’m confronted with something that doesn’t fit, I look for that next StackOverflow answer that’ll tell me how to shoehorn it in among the Tetris pieces that I already have. The framework is not malleable, I must square-off my round peg.</p>
<p>Libraries are what support developing software. Properly in charge, I choose a subordinate library and apply its talents appropriately. There is no hint of having to make my design fit within the strictures of someone else’s plan. I have the skeleton, I merely need the flesh. If I find that a library no longer suits my needs, it is easily removed. Well-scoped libraries tend to match one another much more closely than frameworks do. The problem that the library solves, the abstraction that it grants, tends to be more universal than a framework. Two HTTP client libraries will tend to expose those actions that HTTP supports. With a framework, I must first accept its world-view before I can start using it.</p>
<p>As I’ve grown as a software developer, I’ve come to believe that whenever possible I should use libraries over frameworks. This has been said <a href="http://tom.lokhorst.eu/2010/09/why-libraries-are-better-than-frameworks">many</a> <a href="http://discuss.joelonsoftware.com/default.asp?joel.3.219431.12&amp;">times</a> <a href="http://blog.orderharmony.com/2011/07/libraries-vs-frameworks.html">before</a>, but now I’m <em>getting there</em> via my own experience. I’m beginning to see that the advantages of frameworks can be matched by a powerful language combined with a little sense about the high-level architecture that the application demands. Over time, I’ve developed my own palette of designs and code to accomplish most tasks. I can act as a <a href="http://en.wikipedia.org/wiki/Linker_(computing)#Static_linking">linker</a>, assembling only those functions that are needed to accomplish the task at hand.</p>
<p>Lastly, I worry that time and brainpower that I pour into frameworks goes unrewarded. When I don’t want to use a framework, the framework changes, or I want to do something that the framework doesn’t support, I’m left out in the cold. All of these scenarios play out often. Each time a new version of Rails comes out, it is infused with whatever OOP fashion is reigning at the time: concerns, presenters, etc. The way that I <em>used</em> to do something is rendered obsolete without warning and without recourse. The knowledge that I had about how to work with the framework has gone stale – like money, “you can’t take it with you.”</p>
<p>I think that it is time that we, as software developers, become responsible for our own fate. Make decisions, find out what works, learn! We have no excuse for being held hostage to decisions that we didn’t make just because we didn’t understand the nature of the decision. Software development is more than just filling in the blanks on some giant MadLibs of a framework. Software is the most infinitely pliable medium of design that the world has ever seen. Like a proof, if you can show your reasoning to be sound you can do it that way. There’s no limit, so go out and build!</p>
</article>
]]></description>
<pubDate>Thu, 08 Jan 2015 00:00:00 UT</pubDate>
<guid>http://sencjw.com/posts/2015-01-08-the-quick-hack.html</guid>
</item>
<item>
<title>Haskell Meetup!</title>
<link>http://sencjw.com/posts/2015-01-03-meetup.html</link>
<description><![CDATA[<article>
<header>
<h1>Haskell Meetup!</h1>
<p>
Posted on January 3, 2015
</p>
</header>
<div class="figure">
<img src="../images/mad_haskell.svg" alt="Haskell logo" /><p class="caption">Haskell logo</p>
</div>
<p>We’re doing a <a href="http://www.meetup.com/Madison-Haskell-Users-Group/">Haskell Meetup</a> in Madison! I’m really eager to see what comes out of this. I remember that I first heard about Bendyworks because of a Clojure meetup. Getting a bunch of like-minded people together will be fun. Besides, maybe I can find some more people to blab to about free monads.</p>
</article>
]]></description>
<pubDate>Sat, 03 Jan 2015 00:00:00 UT</pubDate>
<guid>http://sencjw.com/posts/2015-01-03-meetup.html</guid>
</item>
<item>
<title>Getting to write Haskell at work</title>
<link>http://sencjw.com/posts/2014-12-22-haskell-at-work.html</link>
<description><![CDATA[<article>
<header>
<h1>Getting to write Haskell at work</h1>
<p>
Posted on December 22, 2014
</p>
</header>
<p>Jon and I recently worked on a medium-sized Haskell project: <a href="https://github.com/bendyworks/api-server">https://github.com/bendyworks/api-server</a>. It has been immensely gratifying to be able to work on this sort of thing at work. It also makes me realize the current dismal state of things. I tend to not try to wade into “language wars” or say things like “my way of doing things is better…” But after having worked on this project, I’m a little bit sad to work on other things. Some of the things that I noticed:</p>
<ul>
<li>Getting something to build and run took more up-front effort</li>
<li>…but that was probably a good thing</li>
<li>Jumping back into the project was easier</li>
<li>Finding the bugs that did occur was straightforward</li>
<li>We wrote fewer tests than similar Ruby project</li>
<li>Tests were <em>much</em> more effective (e.g. simply round-tripping something through the database flushed out a bunch of errors)</li>
</ul>
<p>What I think gets lost in these sorts of commentaries or comparisons and what I don’t want to get lost here is that there’s a <em>clear-win</em> sense to it that people tend to miss. That is, I think that these sorts of posts <a href="http://en.wiktionary.org/wiki/bury_the_lede">bury the lede</a> by not starting with: <em>“Of course Haskell is the way to go, but here are some drawbacks…”</em></p>
<p>The above list omits things like the fact that even though it took longer to get something up and running, what that <em>means</em> is that if we ignored all the help that Haskell was providing us, we’d only succeed in getting something <em>incorrect</em> up and running sooner. Is it better to get the wrong answer faster? I don’t think so. But I admit that that position may be up to people’s personal taste. This experience has left me grappling with a sinking feeling, that the current development economy that I’m a part of: startups writing web apps, large companies wanting new features added to existing code, and other similar uses cases simply <em>does not or cannot support quality</em>. I’m suspect that using languages and techniques that squash most bugs and enable code to be reasonably bug-free are just too expensive. Quality isn’t a priority. We as an industry have chosen “give me the wrong answer, as long as it is quick.”</p>
<p>Don’t get me wrong, that’s a reasonable choice to make and it’s how engineering works. We have to build what the market will support. “Fast, good, and cheap; pick 2.” We seem to have pretty much given up on <em>good</em> and are just playing with variations on fast and cheap.</p>
<p>If that sounds bleak, I don’t mean it to. I <em>want</em> to inject quality as an option, but I realize that it’s going to have to happen by going through the system not around it. There’s no royal road to software nirvana. Perhaps we can frame the problem in a way that will make companies take notice. Michael Snoyman put it <a href="http://www.yesodweb.com/blog/2012/08/webinar-oreilly">this way</a>:</p>
<blockquote>
<p>Minimizing bugs is a feature that you can sell people on. If I’m comparing product A and product B, and I have some reason to believe product B will have less bugs, I’m very likely to buy it. It can win out over other aspects of the product, such as cost (do you really want to pay for bugs?), ease-of-use (it sure was easy to generate that invalid output), or extra capabilities (hey look, this product can do 50 things badly).</p>
</blockquote>
<p>Maybe that’s the tagline for developing code with Haskell: “do you really want to pay for bugs?” If desirable features have a positive cost (e.g. “how much would you pay for software that could do X?”) would bugs have a negative cost? (e.g. “how much would you pay for software that didn’t do X?”). It opens the possibility of getting hard numbers on the “negative feature cost” of bugs, (e.g. “I would pay an extra 10% if my software never did X”). And <em>that</em> in turn opens some headroom for using something like Haskell.</p>
<p>Put another way, I think that bugs are often <em>undervalued</em>. Bugs hurt “delivered value” a lot more than seems to be widely acknowledged. Sure it can be nice to be the first one to market, or have the biggest mindshare, but all that will fade fast if the fail whale persists.</p>
</article>
]]></description>
<pubDate>Mon, 22 Dec 2014 00:00:00 UT</pubDate>
<guid>http://sencjw.com/posts/2014-12-22-haskell-at-work.html</guid>
</item>
<item>
<title>Writing code that I'm not smart enough to write</title>
<link>http://sencjw.com/posts/2014-08-17-not-smart-enough.html</link>
<description><![CDATA[<article>
<header>
<h1>Writing code that I'm not smart enough to write</h1>
<p>
Posted on August 17, 2014
</p>
</header>
<p>I gave a short talk this week on my trip to <a href="http://www.lambdajam.com/">Lambda Jam</a> a few weeks ago. The topic grew out of a programming exercise/talk given by <a href="https://a.confui.com/-cv6PWx31">Runar Bjarnason</a> called “Let’s make a programming language.”</p>
<p>This talk is about how I was able (with some help) to write code that I didn’t really know how to write. It’s an enlightening experience when you can <em>figure out</em> code just by exploring and reasoning. It’s been one of the reasons why, even when I find it tough or confusing, that functional programming has continued to draw me in.</p>
<p><a href="/talks/not_smart_enough_to_write.pdf">Writing Code I’m Not Smart Enough to Write</a></p>
</article>
]]></description>
<pubDate>Sun, 17 Aug 2014 00:00:00 UT</pubDate>
<guid>http://sencjw.com/posts/2014-08-17-not-smart-enough.html</guid>
</item>
<item>
<title>BayHac2014</title>
<link>http://sencjw.com/posts/2014-05-19-bayhac-2014.html</link>
<description><![CDATA[<article>
<header>
<h1>BayHac2014</h1>
<p>
Posted on May 19, 2014
</p>
</header>
<p>I’m making my way back from <a href="http://www.haskell.org/haskellwiki/BayHac2014">BayHac 2014</a> as I write this but I wanted to put down a few thoughts while they’re still fresh.</p>
<h2 id="friday">Friday</h2>
<p>The hackathon started out with a talk on Pipes by Gabriel Gonzalez and then one on Free Monads by Dan Piponi. Both were excellent. And <em>excellent</em> here means that I think they were both the most lucid explanations of their respective topic that I’ve yet seen.</p>
<p>Gabriel’s talk really helped to solidify my understanding of where pipes sit relative to <a href="http://hackage.haskell.org/package/conduit-1.0.15">conduit</a>, the other streaming-data library that I’m familiar with. The emphasis in the pipes talk was on the intuition behind the <a href="http://hackage.haskell.org/package/pipes-4.1.2/docs/Pipes.html#t:ListT"><code>ListT</code></a> type and the <a href="http://hackage.haskell.org/package/pipes-4.1.2/docs/Pipes.html#t:yield"><code>yield</code></a> and <a href="http://hackage.haskell.org/package/pipes-4.1.2/docs/Pipes.html#t:await"><code>await</code></a> functions.</p>
<p>Dan Piponi spoke on free monads, <a href="https://docs.google.com/file/d/0B51SFgxqMDS-NDBOX0ZDdW52dEE/edit">Free, but not as in beer or speech</a> (<a href="https://plus.google.com/u/0/events/cu5t5s2g14t4fqmapft5bcatqeg">video</a>), by first starting with an algebraic structure called a <em>magma</em>, which is simply a single, closed binary operation on a set:</p>
<pre class="sourceCode haskell"><code class="sourceCode haskell"><span class="kw">class</span> <span class="dt">Magma</span> <span class="kw">where</span>
<span class="ot"> o ::</span> a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> a</code></pre>
<p>Next he suggested the idea of the “least special magma.” We want to capture the idea that we can do this binary operation, and that we have things that are part of the set (the <code>a</code> above). This leads us to a tree:</p>
<pre class="sourceCode haskell"><code class="sourceCode haskell"><span class="kw">data</span> <span class="dt">FreeMagma</span> a <span class="fu">=</span> <span class="dt">Var</span> a
<span class="fu">|</span> <span class="dt">Tree</span> (<span class="dt">FreeMagma</span> a) (<span class="dt">FreeMagma</span> a)
<span class="kw">instance</span> <span class="dt">Magma</span> (<span class="dt">FreeMagma</span> a) <span class="kw">where</span>
o <span class="fu">=</span> <span class="dt">Tree</span></code></pre>
<p>So the idea is that we’re combining two subexpressions (which could be just <code>Var a</code>, of course) and that’s it. The <em>structure</em> embodies the operation that we’re interested in. I don’t want to recapitulate the talk, but here’s one last slide. We can kinda crawl the structure that we’ve set up in order to evaluate the free magma:</p>
<pre class="sourceCode haskell"><code class="sourceCode haskell"><span class="ot">interpretMagma ::</span> <span class="dt">Magma</span> b <span class="ot">=&gt;</span> (a <span class="ot">-&gt;</span> b) <span class="ot">-&gt;</span> (<span class="dt">FreeMagma</span> a <span class="ot">-&gt;</span> b)
interpretMagma f (<span class="dt">Var</span> a) <span class="fu">=</span> f a
interpretMagma f (<span class="dt">Tree</span> a b) <span class="fu">=</span> interpretMagma f a <span class="ot">`o`</span> interpretMagma f b</code></pre>
<p>Evaluating this thing is really just replacing the structure with elements of our choosing according to some rule.</p>
<p>The talk goes on (and the plot thickens!) by moving into free monoids and then, free monads. It was a great introduction!</p>
<h2 id="saturday">Saturday</h2>
<p>Saturday I was able to attend part of the <a href="http://yesodweb.com/">Yesod</a> class (and I’m already a little familiar with Yesod), so the introduction was mostly things I’ve covered on my own. As an aside, I was <em>scheduled</em> for the Lens class and I say scheduled because BayHac was <em>very</em> popular and classes were randomly assigned based up on interest and space. Most classes were packed.</p>
<p>The lens introduction by Shachaf Ben-Kiki was great. I’ve been reading up on these a lot lately so for me the ground had been prepared in just the right way for me to get a lot out of this. Shachaf moved at a brisk pace, whether through practice or sheer type-signature-fu, he hammered out types and definitions for things like lenses and traversals about as fast as I type prose. This class really lit a bulb for me about why the types work the way that they do for lenses. My very hand-wavey summary of this was that a lens is like having a writer monad “logging” the parts of some structure you’re interested in walking over. But rather than being interested in the <em>value</em> that the writer produces it’s the <em>log</em> that you want.</p>
<p><em>Caution, the following is based on my own emerging understanding of Lenses. Please pardon any errors (and I welcome corrections).</em></p>
<p>What started to make sense for me was the connection between <a href="https://hackage.haskell.org/package/lens-4.1.2/docs/Control-Lens-Setter.html#v:over">over</a>, <a href="http://hackage.haskell.org/package/base-4.7.0.0/docs/Data-Traversable.html#v:traverse">traverse</a>, and <a href="http://hackage.haskell.org/package/lens-4.1.2.1/docs/Control-Lens-Lens.html#t:Lens">Lens</a>.</p>
<p>First, looking at traverse, which has the type:</p>
<pre class="sourceCode haskell"><code class="sourceCode haskell">traverse
<span class="ot"> ::</span> (<span class="dt">Traversable</span> t, <span class="dt">Applicative</span> f) <span class="ot">=&gt;</span> (a <span class="ot">-&gt;</span> f b) <span class="ot">-&gt;</span> t a <span class="ot">-&gt;</span> f (t b)</code></pre>
<p>you can think of it as a sort of generalized <a href="http://hackage.haskell.org/package/base-4.7.0.0/docs/Data-List.html#v:map">map</a> (I do). We know the <code>f</code> above is a Functor because:</p>
<pre class="sourceCode haskell"><code class="sourceCode haskell"><span class="kw">class</span> <span class="dt">Functor</span> f <span class="ot">=&gt;</span> <span class="dt">Applicative</span> f <span class="kw">where</span> <span class="fu">...</span></code></pre>
<p>So, picking an Applicative, say the <a href="http://hackage.haskell.org/package/transformers-0.4.1.0/docs/Data-Functor-Identity.html#t:Identity">Identity</a> Applicative, you can write something like map:</p>
<pre class="sourceCode haskell"><code class="sourceCode haskell"><span class="ot">map&#39; ::</span> <span class="dt">Traversable</span> t <span class="ot">=&gt;</span> (a <span class="ot">-&gt;</span> b) <span class="ot">-&gt;</span> t a <span class="ot">-&gt;</span> t b
map&#39; f <span class="fu">=</span> runIdentity <span class="fu">.</span> traverse (<span class="dt">Identity</span> <span class="fu">.</span> f)</code></pre>
<p>notice how we’re sort of “packaging” up the result of the function in a dummy Applicative (<code>runIdentity . Identity == id</code>), which we then immediately discard. This is exactly the sort of sleight of hand that we need for Lens:</p>
<pre class="sourceCode haskell"><code class="sourceCode haskell"><span class="kw">type</span> <span class="dt">Lens</span> s t a b <span class="fu">=</span> forall f<span class="fu">.</span> <span class="dt">Functor</span> f <span class="ot">=&gt;</span> (a <span class="ot">-&gt;</span> f b) <span class="ot">-&gt;</span> s <span class="ot">-&gt;</span> f t</code></pre>
<p>Notice how the <a href="https://hackage.haskell.org/package/lens-4.1.2/docs/Control-Lens-Getter.html#v:view">view</a> function does something really similar:</p>
<pre class="sourceCode haskell"><code class="sourceCode haskell"><span class="ot">view ::</span> <span class="dt">MonadReader</span> s m <span class="ot">=&gt;</span> <span class="dt">Getting</span> a s a <span class="ot">-&gt;</span> m a
<span class="co">-- re-written with definition of Getting</span>
<span class="ot">view ::</span> <span class="dt">MonadReader</span> s m <span class="ot">=&gt;</span> (a <span class="ot">-&gt;</span> <span class="dt">Const</span> a a) <span class="ot">-&gt;</span> s <span class="ot">-&gt;</span> <span class="dt">Const</span> a s <span class="ot">-&gt;</span> m a</code></pre>
<p><code>Const</code> is similar to <code>Identity</code> in that it has a “weird” definition:</p>
<p>`<code>haskell instance Functor (Const m) where fmap _ (Const v) = Const v -- the function doesn't matter!</code></p>
<p>putting that all together (and I’m still a bit fuzzy on how the types work out on these) gives you something that takes a Lens of some structure but then <em>ignores</em> that structure (the <code>s</code> in the <code>Const a s</code>). So you’re getting your structure with the value picked out, but then ignoring the structure (and leaving just the value you’re interested in).</p>
<p>That’s really handwavey, but here’s an example:</p>
<pre class="sourceCode haskell"><code class="sourceCode haskell"><span class="kw">data</span> <span class="dt">Person</span> <span class="fu">=</span> <span class="dt">Person</span> {<span class="ot"> fn ::</span> <span class="dt">String</span> ,<span class="ot"> ln ::</span> <span class="dt">String</span> }
<span class="co">-- e.g. fn (Person &quot;Chris&quot; &quot;Wilson&quot;) == &quot;Chris&quot;)</span></code></pre>
<p>Now I can make a <code>Lens</code> of <code>fn</code> by specifying my own getter and setter functions:</p>
<pre class="sourceCode haskell"><code class="sourceCode haskell">fnLens <span class="fu">=</span> lens fn (\(<span class="dt">Person</span> a b) v <span class="ot">-&gt;</span> <span class="dt">Person</span> v b)</code></pre>
<p>Now I can use that to access the <code>Person</code> structure:</p>
<pre class="sourceCode haskell"><code class="sourceCode haskell">view fnLens (<span class="dt">Person</span> <span class="st">&quot;Chris&quot;</span> <span class="st">&quot;Wilson&quot;</span>)
<span class="co">-- &quot;Chris&quot;</span></code></pre>
<p>And the type would be something like:</p>
<pre><code>view :: (a -&gt; Const a a) -- as above
-&gt; s
-&gt; Const a s
-&gt; m a
fnLens :: (String -&gt; Const String String) -- subbing in types
-&gt; Person
-&gt; Const String Person
view fnLens :: MonadReader Person m =&gt; m String</code></pre>
<p>The above type signature is a bit wonky, but I think it captures what’s happening as the types unify. So it all boils down to something that extracts a <code>String</code> from a <code>Person</code>. But the intuition that is starting to grow for me is that Lenses let you use a carefully-chosen (i.e. <code>Const</code>) <code>Functor</code> to “smuggle” a value out of a bigger structure.</p>
<h2 id="sunday">Sunday</h2>
<p>I spent a lot of time on Sunday working on Joe Nelson’s <a href="https://github.com/begriffs/haskell-vim-now">haskell-vim-now</a> one-line Haskell Vim installer. Lots of people were excited about the prospect of having an easy-to-install Vim mode. I think that this has made a lot of progress. If you like Vim and want to do Haskell development, go install it now. If you want to just install it here, just run this:</p>
<pre class="sourceCode bash"><code class="sourceCode bash"><span class="kw">curl</span> -o - https://raw.githubusercontent.com/begriffs/haskell-vim-now/master/install.sh <span class="kw">|</span> <span class="kw">bash</span></code></pre>
<p>But please see the <a href="https://github.com/begriffs/haskell-vim-now/blob/master/README.md">README</a> for keybindings and general tips on use. Also, if there is anything that you’d like to see included or revised, you are <a href="https://github.com/begriffs/haskell-vim-now/issues">invited to submit an issue</a>.</p>
<p>I also spent some time talking with the <a href="https://snowdrift.coop">Snowdrift.coop</a> developers. This is a funding platform that seeks to crowdfund ongoing Free/Libre/Open Source projects. They have a nice <a href="https://snowdrift.coop/p/snowdrift/w/intro">intro</a>. The Haskell angle here is that this is a Yesod app: source <a href="https://github.com/dlthomas/snowdrift">on Github</a> and <a href="https://gitorious.org/snowdrift/snowdrift/source/6b587c9c176aa24917c7403dbadd3778e17d08b4:">on Gitorious</a>.</p>
<h2 id="summary">Summary</h2>
<p>BayHac was a great experince! I got to meet with a bunch of people that I had only been following online so far. And I think it really fired me up to write more production Haskell. I’m even looking for ways to integrate it into Bendyworks’ development.</p>
</article>
]]></description>
<pubDate>Mon, 19 May 2014 00:00:00 UT</pubDate>
<guid>http://sencjw.com/posts/2014-05-19-bayhac-2014.html</guid>
</item>
<item>
<title>Lenses 101 (for me)</title>
<link>http://sencjw.com/posts/2014-04-30-lenses-101.html</link>
<description><![CDATA[<article>
<header>
<h1>Lenses 101 (for me)</h1>
<p>
Posted on April 30, 2014
</p>
</header>
<p><em>Note:</em> This is a short commentary on the new <a href="http://www.serpentine.com/wreq/">wreq library</a>. These comments were directed at my coworkers, but I thought they’d be interesting here. This post is literate Haskell, you should be able to cut-n-paste.</p>
<hr />
<pre class="sourceCode literate literatehaskell"><code class="sourceCode literatehaskell"><span class="ot">&gt;</span> <span class="ot">{-# LANGUAGE TemplateHaskell #-}</span>
<span class="ot">&gt;</span> <span class="kw">module</span> <span class="dt">Main</span> <span class="kw">where</span>
<span class="ot">&gt;</span> <span class="kw">import</span> Control.Lens</code></pre>
<p>I think a big reason why I’m so stoked about this is that it’s a solid library that’s offering a lens-based API (something that I think will show up more and more as time goes on). I’m still digging into them, but lenses are sort of like the “.” (dot) from Ruby, but implemented as a library and infinitely more flexible:</p>
<p>Getters:</p>
<p>your basic “getter” is ^. (carrot-dot, aka “view”) It lets you “view” things:</p>
<pre class="sourceCode literate literatehaskell"><code class="sourceCode literatehaskell"><span class="ot">&gt;</span> <span class="co">-- basic &quot;Person&quot; data</span>
<span class="ot">&gt;</span> <span class="kw">data</span> <span class="dt">Person</span> <span class="fu">=</span> <span class="dt">Person</span> {_<span class="ot">fn::</span><span class="dt">String</span>, _<span class="ot">ln::</span><span class="dt">String</span>, _<span class="ot">email::</span><span class="dt">String</span>} <span class="kw">deriving</span> <span class="dt">Show</span>
<span class="ot">&gt;</span>
<span class="ot">&gt; me ::</span> <span class="dt">Person</span>
<span class="ot">&gt;</span> me <span class="fu">=</span> <span class="dt">Person</span> {_fn<span class="fu">=</span><span class="st">&quot;Chris&quot;</span>, _ln<span class="fu">=</span><span class="st">&quot;Wilson&quot;</span>, _email<span class="fu">=</span><span class="st">&quot;chris@bendyworks.com&quot;</span>}
<span class="ot">&gt;</span>
<span class="ot">&gt;</span> <span class="fu">$</span>(makeLenses <span class="ch">&#39;&#39;</span><span class="dt">Person</span>) <span class="co">-- autogen the getters/setters</span></code></pre>
<p>And using it to view inside the Person datatype:</p>
<pre class="sourceCode literate literatehaskell"><code class="sourceCode literatehaskell"><span class="ot">&gt;</span> ex1 <span class="fu">=</span> me<span class="fu">^.</span>fn
<span class="ot">&gt;</span> <span class="co">-- &quot;Chris&quot;</span>
<span class="ot">&gt;</span> ex2 <span class="fu">=</span> me<span class="fu">^.</span>email
<span class="ot">&gt;</span> <span class="co">-- &quot;chris@bendyworks.com&quot;</span></code></pre>
<p>Next you’ve got your “setter” (it just updates, non-destructively returning a new thing), also called “set”:</p>
<pre class="sourceCode literate literatehaskell"><code class="sourceCode literatehaskell"><span class="ot">&gt;</span> ex3 <span class="fu">=</span> set fn <span class="st">&quot;Christopher&quot;</span> me
<span class="ot">&gt;</span> <span class="co">-- Person {_fn = &quot;Christopher&quot;, _ln = &quot;Wilson&quot;, _email = &quot;chris@bendyworks.com&quot;}</span></code></pre>
<p>or saying it with operators (the &amp; above is reverse function application, the function on the right is applied to the data on the left, kinda like a shell pipeline):</p>
<pre class="sourceCode literate literatehaskell"><code class="sourceCode literatehaskell"><span class="ot">&gt;</span> ex4 <span class="fu">=</span> me <span class="fu">&amp;</span> fn<span class="fu">.~</span><span class="st">&quot;Christopher&quot;</span>
<span class="ot">&gt;</span> <span class="co">-- Person {_fn = &quot;Christopher&quot;, _ln = &quot;Wilson&quot;, _email = &quot;chris@bendyworks.com&quot;}</span></code></pre>
<p>“But Chris!” you interject, “that’s just lame-o ‘.’ that’s in Ruby ALREADY! Show me some lazer-beam stuff!” Okay, lenses also do traversing! That is you can get/set a bunch of things at once:</p>
<pre class="sourceCode literate literatehaskell"><code class="sourceCode literatehaskell"><span class="ot">&gt;</span> <span class="co">-- bendyworks</span>
<span class="ot">&gt;</span> <span class="kw">data</span> <span class="dt">Bendyworks</span> <span class="fu">=</span> <span class="dt">Bendyworks</span> {_<span class="ot">employees::</span>[<span class="dt">Person</span>]} <span class="kw">deriving</span> <span class="dt">Show</span>
<span class="ot">&gt;</span> <span class="fu">$</span>(makeLenses <span class="ch">&#39;&#39;</span><span class="dt">Bendyworks</span>)
<span class="ot">&gt;</span> <span class="co">-- some setting up</span>
<span class="ot">&gt;</span> bendy <span class="fu">=</span> <span class="dt">Bendyworks</span> {_employees <span class="fu">=</span>
<span class="ot">&gt;</span> [ <span class="dt">Person</span> <span class="st">&quot;Amy&quot;</span> <span class="st">&quot;Unger&quot;</span> <span class="st">&quot;amy@bendyworks.com&quot;</span>
<span class="ot">&gt;</span> <span class="co">-- ...</span>
<span class="ot">&gt;</span> , <span class="dt">Person</span> <span class="st">&quot;Will&quot;</span> <span class="st">&quot;Strinz&quot;</span> <span class="st">&quot;will@bendyworks.com&quot;</span>
<span class="ot">&gt;</span> ]} <span class="co">-- all employees (imagine)</span></code></pre>
<p>Now we traverse over the employees field of the Bendyworks structure, and we can compose a getter with that!</p>
<pre class="sourceCode literate literatehaskell"><code class="sourceCode literatehaskell"><span class="ot">&gt;</span> ex5 <span class="fu">=</span> bendy <span class="fu">^..</span> employees<span class="fu">.</span>traversed<span class="fu">.</span>fn
<span class="ot">&gt;</span> <span class="co">-- [&quot;Amy&quot;, ..., &quot;Will&quot;]</span>
<span class="ot">&gt;</span>
<span class="ot">&gt;</span> ex6 <span class="fu">=</span> bendy <span class="fu">^..</span> employees<span class="fu">.</span>traversed<span class="fu">.</span>email
<span class="ot">&gt;</span> <span class="co">-- [&quot;amy@bendyworks.com&quot;, ..., &quot;will@bendyworks.com&quot;]</span></code></pre>
<p>The thing that’s kinda cool is that “employees.traversed.fn” forms a sort-of lens on the whole Bendyworks datatype, letting us walk over it and pull out values. The traversal is a first-class thing (those ’.’s in the name are just plain-old function composition!). We can store it and use it as a new accessor:</p>
<pre class="sourceCode literate literatehaskell"><code class="sourceCode literatehaskell"><span class="ot">&gt; emails ::</span> <span class="dt">Traversal&#39;</span> <span class="dt">Bendyworks</span> <span class="dt">String</span>
<span class="ot">&gt;</span> emails <span class="fu">=</span> employees<span class="fu">.</span>traversed<span class="fu">.</span>email
<span class="ot">&gt;</span>
<span class="ot">&gt;</span> ex7 <span class="fu">=</span> bendy <span class="fu">^..</span> emails
<span class="ot">&gt;</span> <span class="co">-- [...] -- just like above</span></code></pre>
<p>They’re really composable! You can set a traversal with your old friend .~ (set):</p>
<pre class="sourceCode literate literatehaskell"><code class="sourceCode literatehaskell"><span class="ot">&gt;</span> ex8 <span class="fu">=</span> bendy <span class="fu">&amp;</span> emails <span class="fu">.~</span> <span class="st">&quot;[HIDDEN]&quot;</span>
<span class="ot">&gt;</span> <span class="co">-- Bendyworks {_employees = [Person {_fn=&quot;Amy&quot;,...,_email=&quot;[HIDDEN]&quot;}, ...]}</span></code></pre>
<p>That’s simultaneously setting the emails of all Bendyworkers to the string “[HIDDEN]”. Notice how, if you squint, it’s like the .~ is a SUPER-DOT that can set a bunch of stuff at once. I think it is way cool. I’m just starting to look at the lens library and it’s big. There are tons of functions in there and a lot ground covered. But I think that as time goes on this will become pretty common. Functional getters and setters FTW!</p>
</article>
]]></description>
<pubDate>Wed, 30 Apr 2014 00:00:00 UT</pubDate>
<guid>http://sencjw.com/posts/2014-04-30-lenses-101.html</guid>
</item>
<item>
<title>Feynman Understands Programming</title>
<link>http://sencjw.com/posts/2014-04-22-feynman-understands-programming.html</link>
<description><![CDATA[<article>
<header>
<h1>Feynman Understands Programming</h1>
<p>
Posted on April 22, 2014
</p>
</header>
<p>Watch this video of Feynman explaining how he does physics work. Programming works the same way!</p>
<p>Here’s the translation key: replace “theory” with “a potential program that solves my problem.” And replace “consequences of the theory” with either the correct operation of the program or of bugs (as revealed by tests breaking). All the intervening layers of software make it hard to <em>really</em> know what’s going on. The best that we can hope for is, like Feynman explains, “qualitative understanding” of what the program should do. Before we can write programs, we have to have an idea of what we expect that program to do. Critically, we also have to have an idea of <em>if</em> that expectation were true (or false) <em>what other things would we expect to see?</em> Programming is hard because we have to envision these other phantom worlds and treat them as equally real until we know they aren’t.</p>
<p>Stay tuned for when he begins talking about how important unbroken stretches of time are for working on (programming). Feynman’s solution is to cultivate an aura of <em>irresponsibility</em> so that he’ll have time to do physics.</p>
<iframe
width="420"
height="315"
src="//www.youtube.com/embed/Bgaw9qe7DEE?start=2160"
frameborder="0" allowfullscreen>
</iframe>
</article>
]]></description>
<pubDate>Tue, 22 Apr 2014 00:00:00 UT</pubDate>
<guid>http://sencjw.com/posts/2014-04-22-feynman-understands-programming.html</guid>
</item>
<item>
<title>A Working Computer</title>
<link>http://sencjw.com/posts/2014-03-27-working-computer.html</link>
<description><![CDATA[<article>
<header>
<h1>A Working Computer</h1>
<p>
Posted on March 27, 2014
</p>
</header>
<p>Just thought that I’d make a tiny little post here and mention that I got my <a href="http://www.nand2tetris.org/">nand2tetris</a> computer up and running. That is, I finished off the CPU (which has some tricky parts) and connected it up to the 32K ROM and the Memory (also screen and keyboard memory maps).</p>
<p>I’m now at the point where I can begin implementing the software stack that the platform uses. I’ve started out by writing the assembler in Haskell. We’ll see how this goes.</p>
<p>If this is the first you’re hearing about nand2tetris, and if additionally, you enjoy hardware-y sorts of things, then I can’t recommend this course enough. It has been like a light going on in my head for understanding how these <a href="https://www.youtube.com/watch?v=EKWGGDXe5MA">silly little computers</a> all around us work!</p>
</article>
]]></description>
<pubDate>Thu, 27 Mar 2014 00:00:00 UT</pubDate>
<guid>http://sencjw.com/posts/2014-03-27-working-computer.html</guid>
</item>
<item>
<title>ChiHack</title>
<link>http://sencjw.com/posts/2013-11-08-chihack.html</link>
<description><![CDATA[<article>
<header>
<h1>ChiHack</h1>
<p>
Posted on November 8, 2013
</p>
</header>
<p>As I continue my leisurely foray into the world of Haskell, I have come upon a bivouac of Haskellers near Chicago this weekend. Myself and a co-worker from the office will be attending the first-ever <a href="https://plus.google.com/events/cc4njkf8kh5aho6soboisv6c7rc">ChiHack</a>. Maybe I can get someone to explain <a href="http://www.mpi-sws.org/~skilpat/backpack/">Backpack</a> to me.</p>
</article>
]]></description>
<pubDate>Fri, 08 Nov 2013 00:00:00 UT</pubDate>
<guid>http://sencjw.com/posts/2013-11-08-chihack.html</guid>
</item>
<item>
<title>reactive_record</title>
<link>http://sencjw.com/posts/2013-10-03-reactive-record.html</link>
<description><![CDATA[<article>
<header>
<h1>reactive_record</h1>
<p>
Posted on October 3, 2013
</p>
</header>
<p>Just wanted to make a quick note that I have published my first gem, <a href="https://rubygems.org/gems/reactive_record">reactive_record</a>, on rubygems. It is a utility that lets you “export” constraints from your existing postgres database, creating Rails models.</p>
<p>It is pretty early, but I have put in a lot of work and I hope that it is useful for your projects.</p>
</article>
]]></description>
<pubDate>Thu, 03 Oct 2013 00:00:00 UT</pubDate>
<guid>http://sencjw.com/posts/2013-10-03-reactive-record.html</guid>
</item>
</channel>
</rss>
Jump to Line
Something went wrong with that request. Please try again.