<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Insights at Workshop 14</title>
    <description>Work and insights from Crowdhailer at Workshop 14. I focus on developing lightweight solutions to modern standards. This blog will cover best practices, efficient work-flow and other items of interest
</description>
    <link>http://insights.workshop14.io/</link>
    <atom:link href="http://insights.workshop14.io/feed.xml" rel="self" type="application/rss+xml"/>
    <pubDate>Sun, 23 Oct 2016 08:36:14 +0000</pubDate>
    <lastBuildDate>Sun, 23 Oct 2016 08:36:14 +0000</lastBuildDate>
    <generator>Jekyll v3.2.1</generator>
    
      <item>
        <title>Purify your programs with capability objects</title>
        <description>&lt;p&gt;&lt;strong&gt;Introducing capability objects to eliminate side effects and side causes&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Pure funcations are predictable, and therefore easier to test and reason about than code with side effects.
Some functional languages go to great lengths to control side effects, such as Haskell with its use of the IO Monad.&lt;/p&gt;

&lt;p&gt;This post shows how we can get the same advantages in JavaScript.
(The advantages are the same for many dynamic languages and I also use this technique in Ruby.)
Capability objects provide a simple mechanism for controlling side effects and side causes.
Their use can improve the rationality, readability and reusability of program components.&lt;/p&gt;

&lt;h3 id=&quot;when-is-a-function-pure&quot;&gt;When is a function Pure?&lt;/h3&gt;
&lt;p&gt;A function is pure when isolated from side effects and side causes:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;The only effect of it’s execution is the return value (&lt;em&gt;side effect free&lt;/em&gt;).&lt;/li&gt;
  &lt;li&gt;The return value is always the same given the same arguments (&lt;em&gt;side cause free&lt;/em&gt;).&lt;/li&gt;
  &lt;li&gt;A function with both has referential transparency(&lt;em&gt;pure&lt;/em&gt;).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;It is easiest to clarify these three with some examples.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-js&quot; data-lang=&quot;js&quot;&gt;&lt;span class=&quot;c1&quot;&gt;// Side effect free&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;flip&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(){&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Math&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;=&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;0.5&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;heads&quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;tails&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Side cause free&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;addAndLog&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;){&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;adding&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Pure&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;){&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;There are many ways a function can become coupled to the outside world.
Ways include accessing global variables such as the window object, logging and throwing errors.
Finally any function that accepts a function as an argument (i.e. callback) will become polluted if that callback is impure.&lt;/p&gt;

&lt;p&gt;A program cannot be useful without causing some side effect, it must at least display it’s result.
The goal of a capability object is to separate the business logic and interaction with the outside world.
This separation pushes impure code to the edges of our program leaving the logic pure.
This purity makes validating code that performs important logic easier.&lt;/p&gt;

&lt;h3 id=&quot;capability-objects-and-effectively-isolated-functions&quot;&gt;Capability Objects and effectively isolated functions.&lt;/h3&gt;
&lt;p&gt;A capability object is an object on which some of its methods may be impure or have side effects.
An effectively isolated function is one that is pure when the capability object has only pure functionality.&lt;/p&gt;

&lt;p&gt;The calling code then chooses to provide explicit access for a function to the outside world by controlling the capabilities that are passed in.
If it helps this can be considered as dependency injection of all impure capabilities.&lt;/p&gt;

&lt;p&gt;We make our examples effectively isolated by rewriting them to take appropriate capability objects.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-js&quot; data-lang=&quot;js&quot;&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;flip&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;randomiser&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;){&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;randomiser&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;=&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;0.5&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;heads&quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;tails&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;addAndLog&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;logger&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;){&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;logger&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;adding&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Already pure&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;){&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h3 id=&quot;ok-but-why&quot;&gt;Ok, but why?&lt;/h3&gt;

&lt;p&gt;To show  off the advantages of pure and side effect free functionality we need a more sophisticated example.
Let’s start with a naieve implementation of a dispatcher. &lt;em&gt;Dispatchers are a key part of the &lt;a href=&quot;https://facebook.github.io/flux/docs/overview.html&quot;&gt;flux architecture&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-js&quot; data-lang=&quot;js&quot;&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Dispatcher&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;callbacks&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;){&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;dispatch&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;action&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;){&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;callbacks&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;forEach&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;callback&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;){&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;callback&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;instanceof&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;callback&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;action&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;TypeError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Callback is not a function&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;callbacks&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;length&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;warn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;action&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;action&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;This dispatcher dispatches an action to each callback in a collection.
Meaningful errors should be the result of any callback that is not a function.
A log is required for each action that is dispatched.
Finally if there are no callbacks our log should be a warning as we never want a dispatched action to have no effect.&lt;/p&gt;

&lt;p&gt;The naieve implementation is tightly coupled to the world outside its scope.
It creates side effects when throwing errors and writing log messages.&lt;/p&gt;

&lt;p&gt;To isolate the dispatcher we make the following changes.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-js&quot; data-lang=&quot;js&quot;&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Dispatcher&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;callbacks&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;logger&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;){&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;dispatch&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;action&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;){&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;callbacks&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;forEach&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;callback&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;){&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;callback&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;instanceof&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;callback&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;action&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;err&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;TypeError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Callback is not a function&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;logger&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;err&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;callbacks&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;length&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;nx&quot;&gt;logger&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;warn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;action&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;nx&quot;&gt;logger&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;action&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;In this version there is not a single side effect.
A logger is passed as a dependency, so it is within scope when we call methods on it.
Instead of throwing errors the dispatcher now reports errors via the logger.&lt;/p&gt;

&lt;p&gt;Let us examine the advantages of these changes.&lt;/p&gt;

&lt;h4 id=&quot;detailed-logs&quot;&gt;Detailed logs&lt;/h4&gt;
&lt;p&gt;In larger systems it is helpful to add labels to logs.
One such label might be the section of code that logged the message.
This can be achieved by starting the dispatcher with a logger that always adds a label to its log messages.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-js&quot; data-lang=&quot;js&quot;&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;logger&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;){&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;The Dispatcher:&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;// etc...&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h4 id=&quot;clean-logs&quot;&gt;Clean logs&lt;/h4&gt;
&lt;p&gt;In production we might only be interested in messages that are a warning or an error.
To set this up only our logger needs to know about a log level and we can just dispense with logs that are not important.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-js&quot; data-lang=&quot;js&quot;&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;logger&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;){&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;LOG_LEVEL&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;INFO_LOG_LEVEL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;// etc...&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h4 id=&quot;tested-logs&quot;&gt;Tested logs&lt;/h4&gt;
&lt;p&gt;We have described a dispatcher that logs at different priorities an action that has no callbacks to one that has at least a single callback.
This is the kind of behaviour it would be nice to test.
Stubbing would have been the only option open to us to test the original code.&lt;/p&gt;

&lt;p&gt;Stubbing methods on the global console object would require a cleanup step which can be problematic if the test fails.
The effectively isolated dispatcher can use a fake logger when we are testing the log messages.
This logger will record each call to a method we are interested in.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-js&quot; data-lang=&quot;js&quot;&gt;&lt;span class=&quot;c1&quot;&gt;// This returns a function that records each time it is called&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;createTranscriptFunction&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(){&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;transcript&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[];&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;){&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;transcript&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;push&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;func&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;transcript&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;transcript&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;func&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;logger&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;createTranscriptFunction&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;warn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;createTranscriptFunction&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h4 id=&quot;reporting-errors&quot;&gt;Reporting errors&lt;/h4&gt;

&lt;p&gt;&lt;em&gt;The stack trace of an error is formed when the error is created and not when it is thrown.
This means that if we pass the error to a logger which then throws it we still get the correct stacktrace.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;In production it is not useful to throw errors.
The customer is unlikely to be interested in a stacktrace.
Additionally one bad callback is no reason to not call the other callbacks.
The best case is that one bad callback is not important and its effect may not be visible to the user.
If errors are occurring in production we want to be notified about them and let the user carry on.&lt;/p&gt;

&lt;p&gt;Conversely in development errors should be thrown.
As developers we want notification of broken code as soon as possible.
The dispatcher does not need to be aware of a choice of error handling strategy.
Instead it can simply be passed to an appropriate logger.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-js&quot; data-lang=&quot;js&quot;&gt;&lt;span class=&quot;c1&quot;&gt;// Development&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;logger&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;err&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;){&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;err&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Production&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;logger&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;err&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;){&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;MyErrorServer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;notifyException&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;err&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h3 id=&quot;is-it-worth-it&quot;&gt;Is it worth it.&lt;/h3&gt;

&lt;p&gt;So far only advantages have been highlighted, but what are the costs.&lt;/p&gt;

&lt;p&gt;Passing around capability objects requires a bit more setup.
Failing to pass in a logger can result in code failing even if all the business functionality is present.
An option to handle when a logger is not present is to fallback to using the global console.
I do not do this as I think that a missing logger is something that I want to be a failure and in production missing logs is a problem to which I want to be alerted.&lt;/p&gt;

&lt;p&gt;Leaving debug comments in your codebase makes it a bit larger.
Not really a problem as the amount of code is so small.
If it turns out to be a problem the way to remove the debug calls is with a build step.&lt;/p&gt;

&lt;p&gt;If a function causes many different side effects then it will require several capability objects.
This is a pain but ultimately a good thing.
Any function that needs access to more than two external resources is probably doing too much.&lt;/p&gt;

&lt;h3 id=&quot;resources&quot;&gt;Resources&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://blog.jenkster.com/2015/12/what-is-functional-programming.html&quot;&gt;What is Functional Programming&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://joeduffyblog.com/2015/11/10/objects-as-secure-capabilities/&quot;&gt;Objects as Secure Capabilities&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Sun, 01 May 2016 16:39:05 +0000</pubDate>
        <link>http://insights.workshop14.io/2016/05/01/purify-your-programs-with-capability-objects.html</link>
        <guid isPermaLink="true">http://insights.workshop14.io/2016/05/01/purify-your-programs-with-capability-objects.html</guid>
        
        <category>Functional Programming</category>
        
        <category>JavaScript</category>
        
        <category>Design</category>
        
        
      </item>
    
      <item>
        <title>Why I won't leave Ruby for Elixir</title>
        <description>&lt;p&gt;This post is not about the Elixir community or job opportunities with Ruby.
It is not really about Ruby vs Elixir at all.
What I want to explain is why I am uncomfortable hitching my bandwaggon to the movement from Object Oriented Programming(OOP) to Functional Programming(FP).&lt;/p&gt;

&lt;h3 id=&quot;background&quot;&gt;Background&lt;/h3&gt;

&lt;p&gt;The first language I used professionally was Ruby.
I have been working with it for several years.
In that time I have looked at many ways to improve code quality.
One set of guidelines for improving code is &lt;a href=&quot;http://insights.workshop14.io/2015/07/14/domain-driven-design-introduction.html&quot;&gt;Domain Driven Design(DDD)&lt;/a&gt;.
This is a methodology for writing programs which reflect the domain of the problem they are trying to solve.
DDD is applicable to all programming paradigms but is most often discussed in an OOP context.&lt;/p&gt;

&lt;p&gt;More recently I have been employed to write Elixir.
Elixir is a &lt;a href=&quot;http://elixir-lang.org/&quot;&gt;proudly functional language&lt;/a&gt; that is built atop the Erlang virtual machine(beam).
It has some Ruby inspired syntax but few other similarities.
Working with this new language was a thorough introduction to functional programming.&lt;/p&gt;

&lt;p&gt;Elixir has some powerful concepts such as pattern matching, immutability and pipelines.
These concepts are common across many functional programming languages but much rarer in most object oriented languages.&lt;/p&gt;

&lt;p&gt;However as I became more familiar with these concepts I could find no good reason why they were limited to functional languages.
In particular creating immutable objects certainly is possible and seemed to be valuable.&lt;/p&gt;

&lt;h3 id=&quot;which-to-choose&quot;&gt;Which to choose&lt;/h3&gt;

&lt;p&gt;So I find myself in the situation do I want to program in a functional language or an object language.&lt;/p&gt;

&lt;p&gt;When starting with Elixir one comment from Dave Thomas stuck in my mind.
He said “I don’t think in objects, I think in processes”.
I wondered which one I thought in or even if there is a best way to think.&lt;/p&gt;

&lt;p&gt;Intriguingly I think DDD has a suggestion on whether it is better, as a programmer, to think in objects or processes.
Ask the following question.
&lt;em&gt;Does the client(or any non technical stakeholder) think in processes or objects?&lt;/em&gt;
The answer to that question will be the same answer to whether FP or OOP is a more suitable way to model their domain.&lt;/p&gt;

&lt;p&gt;I certainly value immutability in a programming language and would agree that it can help make code predictable.
My time developing with Elixir clear demonstrated this.
However Ruby can have immutable objects.
So in the end it comes down to the domain to see which paradigm is more suitable.&lt;/p&gt;

&lt;p&gt;Thinking in processes can be helpful, but many of these processes will involve well-defined domain objects.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Browse the &lt;em&gt;Catalogue&lt;/em&gt;&lt;/li&gt;
  &lt;li&gt;View that &lt;em&gt;Item&lt;/em&gt;&lt;/li&gt;
  &lt;li&gt;Update your &lt;em&gt;Basket&lt;/em&gt;&lt;/li&gt;
  &lt;li&gt;checkout == create an &lt;em&gt;Order&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In my opinion neither paradigm is superior.
And my advice is to stop trying to pick a side and enjoy learning both.&lt;/p&gt;

&lt;h3 id=&quot;whats-next-for-me&quot;&gt;What’s next for me&lt;/h3&gt;
&lt;p&gt;Erlang has some superpowers when it comes to writing parallel, fault tolerant code and Elixir inherits these powers.
If a system is meant to manage many demands concurrently then I would use Elixir.
A web socket server is an example of such a system.
For a program with less strenuous requirements I would prefer to use Ruby.&lt;/p&gt;

&lt;p&gt;So I have a preference for Ruby.
This is because; Ruby’s support for functional concepts is better than working with objects in Elixir.
In Ruby I can leverage most of the lessons I learned from my time in with functional programming.&lt;/p&gt;

&lt;h3 id=&quot;best-of-both&quot;&gt;Best of both&lt;/h3&gt;
&lt;p&gt;Some talks discussing immutability and objects.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=rMxurF4oqsc&quot;&gt;Blending Functional and OO Programming in Ruby&lt;/a&gt;
Great talk from &lt;a href=&quot;https://twitter.com/_solnic_&quot;&gt;Piotr Solnica&lt;/a&gt; about his exploration of this area.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=yTkzNHF6rMs&quot;&gt;Boundaries&lt;/a&gt; Immutable OO as FauxO, brilliance from &lt;a href=&quot;https://twitter.com/garybernhardt&quot;&gt;Gary Bernhardt&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Mon, 18 Apr 2016 19:24:05 +0000</pubDate>
        <link>http://insights.workshop14.io/2016/04/18/why-i-cant-leave-ruby-for-elixir.html</link>
        <guid isPermaLink="true">http://insights.workshop14.io/2016/04/18/why-i-cant-leave-ruby-for-elixir.html</guid>
        
        <category>Functional Programming</category>
        
        <category>Object Oriented Programming</category>
        
        <category>Immutability</category>
        
        
      </item>
    
      <item>
        <title>Three JavaScript frameworks for 2016</title>
        <description>&lt;p&gt;&lt;strong&gt;Three modern JavaScript frameworks that are interesting and have something to teach you.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Keeping track of the latest JavaScript frameworks is exhausting.
It is difficult to separate the genuinely interesting from the crowd.
Recently I have had some time to explore the current offerings.
This selection are my favourite and worth a second look.&lt;/p&gt;

&lt;h3 id=&quot;reduxhttpreduxjsorg&quot;&gt;&lt;a href=&quot;http://redux.js.org/&quot;&gt;Redux&lt;/a&gt;&lt;/h3&gt;

&lt;h5 id=&quot;flux---reflux---redux&quot;&gt;Flux -&amp;gt; Reflux -&amp;gt; Redux&lt;/h5&gt;

&lt;p&gt;&lt;img src=&quot;http://img.stackshare.io/service/1275/flux.png&quot; alt=&quot;Flux logo&quot; /&gt;
Flux was coined by Facebook to describe the recommended architecture to use with React.&lt;/p&gt;

&lt;p&gt;The key concept is that of a unidirectional dataflow.
Actions cause updates in a store(aka model).
The model generates a view and this finally updates the DOM.
User interactions are mapped to actions to close the loop.&lt;/p&gt;

&lt;p&gt;Redux is a recent addition to the flux family tree.
It develops on flux by confining all application state to a single store.
This sounds a drastic limitation but creates some interesting payoffs.
One of these benefits is that Redux offers a time-travelling debugger.
This works by keeping a record of each version of the state and allowing a debugger to replay through this history.
It is invaluable when debugging a process with many steps.&lt;/p&gt;

&lt;p&gt;To get a thorough introduction to Redux there is a series of explanatory videos.
These run through all the basic concepts very quickly.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://cycle.js.org/img/cyclejs_logo.svg&quot; alt=&quot;Cycle logo&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;cyclehttpcyclejsorg&quot;&gt;&lt;a href=&quot;http://cycle.js.org/&quot;&gt;Cycle&lt;/a&gt;&lt;/h3&gt;

&lt;h5 id=&quot;haskell---reactivex---cycle&quot;&gt;Haskell -&amp;gt; ReactiveX -&amp;gt; Cycle&lt;/h5&gt;
&lt;p&gt;Cycle takes inspiration from functional technologies such as Haskell and ReactiveX.
Don’t be deterred by these advanced forebears.
Only a limited number of concepts are used and they are explained when needed.&lt;/p&gt;

&lt;p&gt;Cycles design starts with a proposition - what if the user was a function?
The result is a unidirectional data flow, in common with FLux.
However all key components are reactive instead of proactive.
Much of Cycle is built on observables, which are leveraged from RX.js.&lt;/p&gt;

&lt;p&gt;Modelling the system as an observable to a user is certainly unusual.
To me the observable pattern is useful when the object being observed does not care about the behaviour (or even existence) of any observers.
This is not the case for any real system.
The user cares quite a lot about whether the program responds or not to its actions.&lt;/p&gt;

&lt;p&gt;That said there are a few examples where this approach results in very elegant programs.
The concept is well explained on the Cycle website, have a read through and decide if your system makes sense as an observable.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://vuejs.org/images/logo.png&quot; alt=&quot;Vue logo&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;vuehttpvuejsorg&quot;&gt;&lt;a href=&quot;http://vuejs.org/&quot;&gt;Vue&lt;/a&gt;&lt;/h3&gt;

&lt;h5 id=&quot;backbone---mv---mvvm&quot;&gt;Backbone -&amp;gt; MV* -&amp;gt; MVVM&lt;/h5&gt;

&lt;p&gt;Vue uses the Model-View-ViewModel(MVVM) pattern.
It is a focused toolset for dealing with the View and ViewModel layer.
A few further core components of an app are included, such as a router.
Apart from these the core business logic is completely in the hands of the developer.&lt;/p&gt;

&lt;p&gt;Vue evolves the MVVM pattern forward in several respects.
Complete widgets can be encapsulated in single &lt;code class=&quot;highlighter-rouge&quot;&gt;.vue&lt;/code&gt; files
These files contain HTML, CSS and JS.
The databinding syntax that glues the View to ViewModel is concise and explicit.
These changes create a powerful framework that will be familiar to developers who have used other MV* frameworks.&lt;/p&gt;

&lt;p&gt;Vue rides the line between library and framework quite expertly.
I particularly like the way it does not interfere with implementing the core application logic.
It is quite possible to implement a flux architecture within a Vue project.
Important for your project to remain buzzword compliant.&lt;/p&gt;

&lt;p&gt;The documentation does a great job of describing the MVVM pattern.
Particularly valuable when many explanations muddle all the various MV* patterns together.&lt;/p&gt;

&lt;h3 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h3&gt;

&lt;p&gt;All of these projects have ideas I have been able to use going forward.
Perhaps the most significant for me was having one store for the state of an app.
In my current project the single store has just been a wrapper around the history API.
Encoding the entire app state in the URL has given the app the some nice properties.
First is refreshing the page will not lose any information.
Second the back button neatly steps through the history of the application.&lt;/p&gt;

&lt;p&gt;So which of these three should you use?
All of them, in the correct situation.
They all have great documentation and learning them is valuable even if you do not use them.&lt;/p&gt;

&lt;p&gt;If my next project had lots of collections, I would use Vue to create coherent components.
But my design would be inspired by Redux and reduce the number of stateful components.
For a more interactive product, I would employ Cycle.
The observable model would be very nice for handling rich input from the user.&lt;/p&gt;

&lt;p&gt;Well those are my three favourites at the moment;I am sure you have others that you can suggest.&lt;/p&gt;

&lt;!-- Put as an example in the links --&gt;
&lt;p&gt;Herinrik Jorteg created an example where the router was just a view into the state.
link to old webcomponents frp post.&lt;/p&gt;
</description>
        <pubDate>Wed, 23 Mar 2016 14:00:00 +0000</pubDate>
        <link>http://insights.workshop14.io/2016/03/23/three-javascript-frameworks-for-2016.html</link>
        <guid isPermaLink="true">http://insights.workshop14.io/2016/03/23/three-javascript-frameworks-for-2016.html</guid>
        
        <category>JavaScript</category>
        
        <category>Design</category>
        
        
      </item>
    
      <item>
        <title>Dreamcoding my ideal language.</title>
        <description>&lt;p&gt;&lt;strong&gt;Dreamcoding is the process of writing down the code you wish to write, without considering implementaion.
This post is what happened when I tried to apply that concept to a whole language.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I was first introduced to the concept of dreamcoding on the &lt;a href=&quot;http://nobackend.org/&quot;&gt;nobackend.org&lt;/a&gt; site.
Conceptually it is very similar to &lt;a href=&quot;https://www.youtube.com/watch?v=gULkBpl3e7c&quot;&gt;‘coding by wishful thinking’&lt;/a&gt; that I have seen from Corey Haines.&lt;/p&gt;

&lt;h3 id=&quot;what-i-want&quot;&gt;What I want&lt;/h3&gt;

&lt;p&gt;In my career I have worked with JavaScript, Ruby and Python, most recently I have been working with &lt;a href=&quot;http://elixir-lang.org/&quot;&gt;Elixr&lt;/a&gt;.
In my free-time I have experimented with yet more.
These are all great languages yet there are certain features that might be useful that I have not found in any language.
These ‘missing’ features are what I present here.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;DISCLAIMER: These features might be harmful.&lt;/strong&gt;
I think all these features might be interesting but as I have not implemented them, so they could contain any problems.&lt;/p&gt;

&lt;p&gt;All examples are highlighted as Ruby that’s just because they look more interesting than un-highlighted and Ruby has a very free syntax.&lt;/p&gt;

&lt;h4 id=&quot;named-curried-functions&quot;&gt;1. Named Curried Functions&lt;/h4&gt;
&lt;p&gt;My first feature is a function that is both curried and has named parameters.
Currying is the partial application of functions.
It allows for the very concise description of certain problems, for example mapping collections.
Named arguments in functions are expressive at communicating the intent of a function.
My hope is that named-curried functions could be both expressive and concise.&lt;/p&gt;

&lt;p&gt;Such a combination might look like.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-rb&quot; data-lang=&quot;rb&quot;&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;divide&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;numerator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;denominator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;numerator&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;denominator&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;divide&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;numerator: &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;denominator: &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# =&amp;gt; 2&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;half&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;divide&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;denominator: &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;half&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;numerator: &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# =&amp;gt; 3&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;invert&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;divide&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;numerator: &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;invert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;denominator: &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# =&amp;gt; 0.25&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Perhaps if the function has arity 1 then the name of the final argument can be omitted&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;invert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# =&amp;gt; 0.25&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h4 id=&quot;immutable-objects&quot;&gt;Immutable objects&lt;/h4&gt;
&lt;p&gt;Objects are a useful abstraction in many cases to model a domain.
In my experience, the most useful objects in domain modeling are small &lt;a href=&quot;http://insights.workshop14.io/2015/07/15/value-objects-in-ruby.html&quot;&gt;value objects&lt;/a&gt;.
Immutable structures are cited to help improve the predictability of code, which I think is the case.&lt;/p&gt;

&lt;p&gt;Most languages that are immutable are functional languages.
The pass data around and do not have a way to attach domain information to custom objects.
In the Ruby community there has been some discussion around immutability.
However because it is not immutable by default it is slow as certain optimisations cannot be made.&lt;/p&gt;

&lt;p&gt;Simple immutable objects can just be modeled as partially applied modules.
Thought like this it would also be possible to have modules applied to different degrees, for example.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-rb&quot; data-lang=&quot;rb&quot;&gt;&lt;span class=&quot;k&quot;&gt;module&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;User&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;first_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;first_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;first_name&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;first_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;last_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;first_name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;++&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot; &quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;++&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;last_name&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Here we just ignore the unexpected argument passed in.&lt;/span&gt;
&lt;span class=&quot;no&quot;&gt;User&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;first_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;first_name: &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Stuart&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;last_name: &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Little&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# =&amp;gt; &quot;Stuart&quot;&lt;/span&gt;

&lt;span class=&quot;no&quot;&gt;User&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;first_name: &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Stuart&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;last_name: &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Little&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# =&amp;gt; &quot;Stuart Little&quot;&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;stuart&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;User&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;first_name: &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Stuart&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;last_name: &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Little&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;stuart&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;name&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# =&amp;gt; &quot;Stuart Little&quot;&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;littles&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;User&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;last_name: &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Little&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# =&amp;gt; {User, {last_name: &quot;Little&quot;}}&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;littles&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;first_name: &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Stuart&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# =&amp;gt; &quot;Stuart Little&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;If logic is needed to instantiate objects this can be added as a function on the module.
For example if we wanted to create a user from a CSV row.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-rb&quot; data-lang=&quot;rb&quot;&gt;&lt;span class=&quot;k&quot;&gt;module&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;User&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;from_csv_archive&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;archive_string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;first_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;last_name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;archive_string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;split&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;' '&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;no&quot;&gt;User&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;first_name: &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;first_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;last_name: &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;last_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h4 id=&quot;side-effects-always-dependencies&quot;&gt;Side Effects always Dependencies&lt;/h4&gt;
&lt;p&gt;A well structured way of handling side effects is important when writing modular code.
I would like to see controlled access IO through an &lt;code class=&quot;highlighter-rouge&quot;&gt;IO&lt;/code&gt; module that is not in the global namespace.
This IO module would be passed as in a function argument list, this would mean that two things.
First a fake implementation can always be passed in for the purpose of testing.
Second the language would be able to track its use and make optimisations of the code that did not call upon external IO.
Making IO always an explicit dependency might have advantages that the computer can assume functions without this declaration are pure.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-rb&quot; data-lang=&quot;rb&quot;&gt;&lt;span class=&quot;no&quot;&gt;IO&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;puts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Hello world!&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# !! Error as no module IO found here&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;module&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;ConsoleLogger&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;output&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;io&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;IO&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;io&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;puts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;output&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;no&quot;&gt;ConsoleLogger&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Hello world!&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# Hello world!&lt;/span&gt;

&lt;span class=&quot;sr&quot;&gt;//&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;NullIO&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dummy&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;object&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;that&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;has&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;the&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;same&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;interface&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;the&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;IO&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;
&lt;span class=&quot;no&quot;&gt;ConsoleLogger&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;output: &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Hello world!&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;io: &lt;/span&gt;&lt;span class=&quot;no&quot;&gt;NullIO&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h4 id=&quot;limited-public-interfaces&quot;&gt;Limited public interfaces&lt;/h4&gt;
&lt;p&gt;Controlling the public interface of a module is a good way to preserve modularity.
In some languages it is very easy to write code that relies on implementation details.
One way to control this would be to make all modules declare implementation of specific interfaces.&lt;/p&gt;

&lt;p&gt;To go even further a function name can only be used once across all interfaces
For example, if a value has a &lt;code class=&quot;highlighter-rouge&quot;&gt;to_string&lt;/code&gt; method then it is certain that the value implements the printable interface.
For this reason I want to experiment with structural typing where each function name is only able to refer to a single function signature within a certain context.
By default every function is private and they are only exposed through interfaces.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-rb&quot; data-lang=&quot;rb&quot;&gt;&lt;span class=&quot;c1&quot;&gt;# Define a to_string interface that takes no arguments and returns a string&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;interface&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Printable&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;to_string&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Any&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;String&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Trying to create another interface with the string function is an error&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;interface&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Other&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;to_string&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Any&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;String&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# !! raise SignatureAlreadyDefined&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;module&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;User&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;# Simply defining this function marks this module as printable&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;to_string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;s2&quot;&gt;&quot;user&quot;&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;c1&quot;&gt;# By default this will be private as it is not in any defined interface.&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;private_method&lt;/span&gt;
    &lt;span class=&quot;ss&quot;&gt;:some_constant&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;no&quot;&gt;User&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;implements&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Printable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# =&amp;gt; true&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h3 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;As a developer I am excited to build new things.
I’m sure I would enjoy the challenge of implementing my own language.
The reality is that this would be &lt;a href=&quot;http://www.hanselman.com/blog/YakShavingDefinedIllGetThatDoneAsSoonAsIShaveThisYak.aspx&quot;&gt;yak shaving&lt;/a&gt; of epic proportions.
So, for the moment, I have decided on dreamcoding only.&lt;/p&gt;

&lt;p&gt;These four features interest me, and I will continue my search for them.
The next languages I want to investigate are Haskell, Scala and Typescript.&lt;/p&gt;

&lt;p&gt;Do you see an obvious flaw in these features? Please do convince me.
Is one of these features already in existence? That is excellent I would love to know where and see some examples&lt;/p&gt;
</description>
        <pubDate>Thu, 26 Nov 2015 16:39:05 +0000</pubDate>
        <link>http://insights.workshop14.io/2015/11/26/dreamcoding-my-ideal-language.html</link>
        <guid isPermaLink="true">http://insights.workshop14.io/2015/11/26/dreamcoding-my-ideal-language.html</guid>
        
        <category>Functional Programming</category>
        
        <category>Immutability</category>
        
        <category>Design</category>
        
        
      </item>
    
      <item>
        <title>Organising client JavaScript with Rollup.js</title>
        <description>&lt;p&gt;&lt;strong&gt;&lt;a href=&quot;http://rollupjs.org&quot;&gt;Rollup.js&lt;/a&gt; is a great way to add structure to a large client-side code base.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/rollup-js-logo.svg&quot; alt=&quot;Rollup.js logo&quot; /&gt;&lt;/p&gt;

&lt;p&gt;You might not be wanting to tackle all of EcmaScript(ES6), yet still want to separate your JavaScript code into modules.
Previously the best way to do this was Browserify with common.js modules.
Rollup.js is the logical next step as it replaces the common.js modules with ES6 modules.
It is also a component of Babel (a full ES6 transpiler) so there is an easy next step to get working with the rest of ES6.&lt;/p&gt;

&lt;p&gt;I have recently introduced Rollup.js into my development workflow.
The simple command line interface means it can be used without the overhead of taskrunners like(gulp).
It is easy to integrate with existing tools for testing.
I use the Karma test runner to execute my test framework of choice, which is currently Jasmine.&lt;/p&gt;

&lt;p&gt;This post walks through my setup of Jasmine, Karma and rollup.
Want to jump straight to the code?
&lt;a href=&quot;https://github.com/CrowdHailer/rollup-karma-jasmine-example&quot;&gt;Visit this repository to see the code&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;I will assume that you already have node and npm installed, need help see &lt;a href=&quot;https://docs.npmjs.com/getting-started/installing-node&quot;&gt;Installing Node.js and npm&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;h3 id=&quot;setting-up-a-node-project&quot;&gt;Setting up a node project&lt;/h3&gt;

&lt;p&gt;We first need to create a &lt;code class=&quot;highlighter-rouge&quot;&gt;package.json&lt;/code&gt; file to identify our project as a node project.
This can be done by hand or by executing &lt;code class=&quot;highlighter-rouge&quot;&gt;npm init&lt;/code&gt;, which walks through setup.
The only setup we need is to give the project a name, let’s call it calculator.&lt;/p&gt;

&lt;p&gt;Next is to fetch the development dependencies we will use.
Fetch all the dependencies by executing the following.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-sh&quot; data-lang=&quot;sh&quot;&gt;&lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;npm install --save-dev &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    rollup &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    jasmine &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    karma &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    karma-jasmine &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    karma-firefox-launcher&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;At this point make sure that you have added &lt;code class=&quot;highlighter-rouge&quot;&gt;node_modules&lt;/code&gt; to your &lt;code class=&quot;highlighter-rouge&quot;&gt;.gitignore&lt;/code&gt; file.
It is not a good idea to commit all these node files to version control-something that I have done on too many occasions.&lt;/p&gt;

&lt;h3 id=&quot;setting-up-karmajs&quot;&gt;Setting up Karma.js&lt;/h3&gt;

&lt;p&gt;The Karma test runner also comes with a handy project initializer which will create a &lt;code class=&quot;highlighter-rouge&quot;&gt;karma.conf.js&lt;/code&gt; file.
Run the karma initializer with the following options.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-sh&quot; data-lang=&quot;sh&quot;&gt;&lt;span class=&quot;gp&quot;&gt;$  &lt;/span&gt;./node_modules/.bin/karma init

Which testing framework &lt;span class=&quot;k&quot;&gt;do &lt;/span&gt;you want to use ?
Press tab to list possible options. Enter to move to the next question.
&lt;span class=&quot;gp&quot;&gt;&amp;gt; &lt;/span&gt;jasmine

Do you want to use Require.js ?
This will add Require.js plugin.
Press tab to list possible options. Enter to move to the next question.
&lt;span class=&quot;gp&quot;&gt;&amp;gt; &lt;/span&gt;no

Do you want to capture any browsers automatically ?
Press tab to list possible options. Enter empty string to move to the next question.
&lt;span class=&quot;gp&quot;&gt;&amp;gt; &lt;/span&gt;Firefox
&amp;gt;

What is the location of your &lt;span class=&quot;nb&quot;&gt;source &lt;/span&gt;and &lt;span class=&quot;nb&quot;&gt;test &lt;/span&gt;files ?
You can use glob patterns, eg. &lt;span class=&quot;s2&quot;&gt;&quot;js/*.js&quot;&lt;/span&gt; or &lt;span class=&quot;s2&quot;&gt;&quot;test/**/*Spec.js&quot;&lt;/span&gt;.
Enter empty string to move to the next question.
&lt;span class=&quot;gp&quot;&gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;test&lt;/span&gt;/bundle.js
11 11 2015 17:04:52.298:WARN &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;init]: There is no file matching this pattern.

&amp;gt;

Should any of the files included by the previous patterns be excluded ?
You can use glob patterns, eg. &lt;span class=&quot;s2&quot;&gt;&quot;**/*.swp&quot;&lt;/span&gt;.
Enter empty string to move to the next question.
&amp;gt;

Do you want Karma to watch all the files and run the tests on change ?
Press tab to list possible options.
&lt;span class=&quot;gp&quot;&gt;&amp;gt; &lt;/span&gt;no


Config file generated at &lt;span class=&quot;s2&quot;&gt;&quot;/home/peter/Projects/Calculator/karma.conf.js&quot;&lt;/span&gt;.&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h4 id=&quot;note&quot;&gt;Note&lt;/h4&gt;

&lt;ul&gt;
  &lt;li&gt;We do not need Require.js as we will be replacing this with Rollup.js&lt;/li&gt;
  &lt;li&gt;You can select any browser from the list, just make sure that you have installed the correct browser runner.&lt;/li&gt;
  &lt;li&gt;Don’t worry about the missing test file, we will add it shortly.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;creating-our-first-test&quot;&gt;Creating our first test&lt;/h3&gt;

&lt;p&gt;Let’s create a single test to check out Karma setup.
We will create a main test file and add an example test.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-js&quot; data-lang=&quot;js&quot;&gt;&lt;span class=&quot;c1&quot;&gt;// test/main.js&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;describe&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;A suite&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;contains spec with an expectation&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;expect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;toBe&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;To bundle this file use Rollup with its default settings and store the output.
&lt;em&gt;At this point the output will be unchanged, this is because we are yet to import any modules&lt;/em&gt;&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-sh&quot; data-lang=&quot;sh&quot;&gt;&lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;./node_modules/.bin/rollup &lt;span class=&quot;nb&quot;&gt;test&lt;/span&gt;/main.js &amp;gt; &lt;span class=&quot;nb&quot;&gt;test&lt;/span&gt;/bundle.js&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Now our bundle is available we can run the test.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-sh&quot; data-lang=&quot;sh&quot;&gt;&lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;./node_modules/.bin/karma start --singleRun&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;This will show one passing test.
As &lt;code class=&quot;highlighter-rouge&quot;&gt;test/bundle.js&lt;/code&gt; is just a derived file it does not belong in version control.
Add a line for it in the &lt;code class=&quot;highlighter-rouge&quot;&gt;.gitignore&lt;/code&gt;.&lt;/p&gt;

&lt;h3 id=&quot;simple-test-execution&quot;&gt;Simple test execution&lt;/h3&gt;

&lt;p&gt;Typing all those commands to execute the tests would be painful.
We can make life much easier by declaring them as npm scripts.
First one change is needed in &lt;code class=&quot;highlighter-rouge&quot;&gt;karma.conf.js&lt;/code&gt;, we will set singleRun configuration to be true.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-js&quot; data-lang=&quot;js&quot;&gt;&lt;span class=&quot;c1&quot;&gt;// karma.conf.js&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;module&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;exports&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// Continuous Integration mode&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// if true, Karma captures browsers, runs the tests and exits&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;singleRun&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;A lot of functionality can end up in npm scripts and it is easy to write magical single line scripts that no-one understands.
My advice is to write small contained scripts for bundling and running the tests. Then have a third script that coordinates the small component scripts.
Add these scripts into &lt;code class=&quot;highlighter-rouge&quot;&gt;package.json&lt;/code&gt;.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-json&quot; data-lang=&quot;json&quot;&gt;&lt;span class=&quot;err&quot;&gt;//&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;package.json&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;scripts&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;test&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;npm run -s test:build &amp;amp;&amp;amp; npm run -s test:run&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;test:build&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;rollup ./test/main.js &amp;gt; test/bundle.js&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;test:run&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;karma start&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;To run the project tests we can just execute the npm test script.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-sh&quot; data-lang=&quot;sh&quot;&gt;&lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;npm -s &lt;span class=&quot;nb&quot;&gt;test&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;This single simple test command follows npm conventions and is easy to remember.
Having a trivial test command is important if test driving the development of a project.&lt;/p&gt;

&lt;h3 id=&quot;testing-some-real-code&quot;&gt;Testing some real code&lt;/h3&gt;

&lt;p&gt;At the moment we have Rollup.js setup but it is redundant as we have no modules.
It is time to test some real code for a calculator.
The first feature a calculator should have is the ability to add two numbers.
Let’s adjust the test file so that it imports the calculator and add a meaningful test.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-js&quot; data-lang=&quot;js&quot;&gt;&lt;span class=&quot;c1&quot;&gt;// test/main.js&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Import all exported functions from the calculator source file&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// They will be available as part of the calculator namespace&lt;/span&gt;
&lt;span class=&quot;kr&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;calculator&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;../src/calculator&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;describe&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;A Calculator&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;should be able to add two numbers&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;expect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;calculator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;toEqual&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;The tests should now be failing, there is no code after all.
There are several features a good calculator might need.
To keep features separate the calculator module will import modules to gain its utility.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-js&quot; data-lang=&quot;js&quot;&gt;&lt;span class=&quot;c1&quot;&gt;// src/calculator.js&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Import add from the `calculator/add.js` file&lt;/span&gt;
&lt;span class=&quot;kr&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;add&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;./calculator/add&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Export add as one of the exports for the calculator module&lt;/span&gt;
&lt;span class=&quot;kr&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;add&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-js&quot; data-lang=&quot;js&quot;&gt;&lt;span class=&quot;c1&quot;&gt;// src/calculator/add.js&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// export the function add as the default for this module&lt;/span&gt;
&lt;span class=&quot;kr&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;With the tests passing again our impressive calculator is taking shape.&lt;/p&gt;

&lt;h3 id=&quot;building-a-distribution&quot;&gt;Building a distribution&lt;/h3&gt;

&lt;p&gt;The final thing, now we have working calculator components, is to bundle the source into a single file.
This is so it can be consumed in all the browsers that are not yet supporting ES6 modules.&lt;/p&gt;

&lt;p&gt;Using Rollup.js again we bundle the distribution and save it in &lt;code class=&quot;highlighter-rouge&quot;&gt;index.js&lt;/code&gt;.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-sh&quot; data-lang=&quot;sh&quot;&gt;&lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;./node_modules/.bin/rollup &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    --format iife &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    --name calculator &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    src/calculator.js &amp;gt;  index.js&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;We pass the format and name options so that our final bundle is available in the global namespace and can be used by other js code.&lt;/p&gt;

&lt;p&gt;Again to keep our version control neat we add index.js to &lt;code class=&quot;highlighter-rouge&quot;&gt;.gitignore&lt;/code&gt;.&lt;/p&gt;

&lt;h3 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h3&gt;

&lt;p&gt;This has so far been a convenient way for me to add some structure to my projects.
It has been much simpler to setup than Browserify with Gulp or Grunt.
Check out the &lt;a href=&quot;https://github.com/CrowdHailer/rollup-karma-jasmine-example&quot;&gt;code for the calculator project&lt;/a&gt; the result of this walk through.
Tell me what you think about this approach, if you would use it or if anything is missing.&lt;/p&gt;
</description>
        <pubDate>Thu, 12 Nov 2015 08:33:05 +0000</pubDate>
        <link>http://insights.workshop14.io/2015/11/12/organising-client-javascript-with-rollup-js.html</link>
        <guid isPermaLink="true">http://insights.workshop14.io/2015/11/12/organising-client-javascript-with-rollup-js.html</guid>
        
        <category>JavaScript</category>
        
        <category>Rollup.js</category>
        
        <category>ES6</category>
        
        
      </item>
    
      <item>
        <title>Handling Errors in Elixir, No one say Monad.</title>
        <description>&lt;h3 id=&quot;being-contrary&quot;&gt;Being Contrary&lt;/h3&gt;

&lt;p&gt;This post is to extend a throwaway comment I made on &lt;a href=&quot;https://twitter.com/CrowdHailer/status/654202422416556032&quot;&gt;Twitter&lt;/a&gt; about returning tagged tuples as the result of any expression in Elixir.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tempted to say all elixir funcs should return a result tuple. &lt;code class=&quot;highlighter-rouge&quot;&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;:ok,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Obviously several people disagreed and a tweet was never going to be enough to explain my reasoning.
So here goes…&lt;/p&gt;

&lt;h3 id=&quot;update&quot;&gt;Update&lt;/h3&gt;
&lt;p&gt;I recently implemented the ideas that are discussed here.
Check out &lt;a href=&quot;https://github.com/CrowdHailer/OK&quot;&gt;OK&lt;/a&gt; to jump straight to the results.&lt;/p&gt;

&lt;h3 id=&quot;some-background&quot;&gt;Some background&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;em&gt;Tuple:&lt;/em&gt; A data structure consisting of multiple parts.&lt;/li&gt;
  &lt;li&gt;&lt;em&gt;Tagged Tuple:&lt;/em&gt; A tuple where the first part is an atom that acts as a label describing the remaining contents in the tuple.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Elixir has inherited the tagged tuple error handling convention from Erlang.
Let’s take a function that has a chance of failing to compute.
If all goes well, the function will return a tuple tagged with the &lt;code class=&quot;highlighter-rouge&quot;&gt;:ok&lt;/code&gt; atom and a value.
If the function could not return a value then it returns a tuple tagged &lt;code class=&quot;highlighter-rouge&quot;&gt;:error&lt;/code&gt; and the reason.
Subsequent code can then pattern match on the tag to call the correct behaviour.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-elixir&quot; data-lang=&quot;elixir&quot;&gt;&lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;MyModule&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;flaky_method&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:ok&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;IO&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;sd&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;All good value was: &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;.&quot;&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;reason&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;IO&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;sd&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;Uh oh! Failed due to &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;reason&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;.&quot;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Returning a tagged tuple is only a convention.
In the real world many functions do not adhere to this contract:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Some functions simply return &lt;code class=&quot;highlighter-rouge&quot;&gt;nil&lt;/code&gt; or &lt;code class=&quot;highlighter-rouge&quot;&gt;:error&lt;/code&gt; instead of a tuple and a reason.&lt;/li&gt;
  &lt;li&gt;Some functions can’t fail so just return a value. As in my original tweet, adding 2 numbers always works and so &lt;code class=&quot;highlighter-rouge&quot;&gt;2 + 2&lt;/code&gt; will only return &lt;code class=&quot;highlighter-rouge&quot;&gt;4&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;Some functions borrow a Ruby convention and have functions that can throw errors and end with an exclamation mark.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;a-problem-to-solve&quot;&gt;A problem to solve&lt;/h3&gt;

&lt;p&gt;So before presenting you with a solution it’s good to have a problem:&lt;/p&gt;

&lt;p&gt;Imagine I have a JSON file of information about people in my company.
I want to fetch all the data relating to me in this file.&lt;/p&gt;

&lt;p&gt;To do this I first read the file, then parse the JSON, and finally search for the details relating to me.
Ideally our code will resemble an intuitive description of the problem; we described this problem as a sequence of steps and so our code should read as a sequence of steps.
Given that it is possible for each of our steps to fail, we need to prepare to handle those errors. The error handling can pollute our nice list of instructions and result in code littered with conditionals.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-elixir&quot; data-lang=&quot;elixir&quot;&gt;&lt;span class=&quot;n&quot;&gt;result&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;File&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;read&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sd&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;my_company/employees.json&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:ok&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;contents&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Poison&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;decode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;contents&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:ok&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Dict&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fetch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;sd&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;Peter&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
          &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:ok&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:ok&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
          &lt;span class=&quot;ss&quot;&gt;:error&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:key_not_found&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
          &lt;span class=&quot;c1&quot;&gt;# Notice the Dict API doesn't return error with reason.&lt;/span&gt;
          &lt;span class=&quot;c1&quot;&gt;# So we add a reason to make it conform.&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;reason&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;reason&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;reason&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;reason&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Well that’s ugly. Can we do this better?&lt;/p&gt;

&lt;p&gt;Thinking about it a bit harder we can see a common pattern in the code:
If the result of a step is successful, we want to take the value of the result and use it in the next step.
But if the result was an error then we want to stop processing.&lt;/p&gt;

&lt;h3 id=&quot;how-about-a-result-module&quot;&gt;How about a Result module?&lt;/h3&gt;

&lt;p&gt;Let’s create a module that has the responsibilty of handling this conventional error pattern.
The &lt;code class=&quot;highlighter-rouge&quot;&gt;Result&lt;/code&gt; module handles passing values from &lt;code class=&quot;highlighter-rouge&quot;&gt;:ok&lt;/code&gt; tagged tuples to the next function.
But if the result is an &lt;code class=&quot;highlighter-rouge&quot;&gt;:error&lt;/code&gt; tagged tuple then following functions will simply be ignored.&lt;/p&gt;

&lt;p&gt;The function of interest is &lt;code class=&quot;highlighter-rouge&quot;&gt;bind&lt;/code&gt;.
It has the following behaviour:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;If the result given is a success, call the next function with the returned value.&lt;/li&gt;
  &lt;li&gt;If the result is a failure, don’t invoke the next function.&lt;/li&gt;
&lt;/ul&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-elixir&quot; data-lang=&quot;elixir&quot;&gt;&lt;span class=&quot;k&quot;&gt;defmodule&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Result&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bind&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:ok&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;func&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;when&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;is_function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;func&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;func&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bind&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;failure&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_func&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;failure&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;With the &lt;code class=&quot;highlighter-rouge&quot;&gt;bind&lt;/code&gt; method we can then return to a linear set of steps.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-elixir&quot; data-lang=&quot;elixir&quot;&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Result&lt;/span&gt;

&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:ok&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;sd&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;my_company/employees.json&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;|&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bind&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;File&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;read&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;|&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bind&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Poison&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;decode&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;|&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bind&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;fn&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;(%{&lt;/span&gt;&lt;span class=&quot;sd&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;Peter&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;})&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:ok&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:key_not_found&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;# This noise here is only necessary as the Dict returns :error without a reason&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Not bad! We have a single list of steps, but having the &lt;code class=&quot;highlighter-rouge&quot;&gt;bind&lt;/code&gt; function and function capturing everywhere still makes this a bit messy.&lt;/p&gt;

&lt;p&gt;Can we go better again?&lt;/p&gt;

&lt;h3 id=&quot;there-is-a-monad-in-the-house&quot;&gt;There is a monad in the house.&lt;/h3&gt;

&lt;p&gt;This combination of tagged tuples can be viewed as a result monad. The result monad is a monad because it has features in common with other monads.&lt;/p&gt;

&lt;p&gt;Monads are a very abstract concept and as we are not trying to generalise any further we do not need to investigate them any further.
Using the result tuple as a monad allows us to use the experience of people who have thought more about monads.&lt;/p&gt;

&lt;p&gt;For this reason I am working on an extension to the result module that will handle tagged tuples as monads.
I want it to be able to handle &lt;code class=&quot;highlighter-rouge&quot;&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;:ok,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;:error,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;reason&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt; only so that it provides guidance on the API for other functions.
The extension will be the ok-pipeline macro - &lt;code class=&quot;highlighter-rouge&quot;&gt;|ok&amp;gt;&lt;/code&gt;.
This macro will be a combination of an elixir pipeline and the bind function.&lt;/p&gt;

&lt;p&gt;With this ok-pipeline our example problem could be refactored even further.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;I have assumed the API for dict is updated&lt;/em&gt;&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-elixir&quot; data-lang=&quot;elixir&quot;&gt;&lt;span class=&quot;kn&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Result&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;get_employee_data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:ok&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ok&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;File&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;read&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ok&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Poison&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;decode&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ok&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Dict&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fetch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;handle_user_data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:ok&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}),&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;IO&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;puts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sd&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;Contact at &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;sd&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;email&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;handle_user_data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:enoent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}),&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;IO&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;puts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sd&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;File not found&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;handle_user_data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:invalid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}}),&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;IO&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;puts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sd&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;Invalid JSON&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;handle_user_data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:key_not_found&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}),&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;IO&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;puts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sd&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;Could not find employee&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;get_employee_data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sd&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;my_company/employees.json&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;|&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;handle_user_data&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h3 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h3&gt;

&lt;p&gt;At the end of the last example we used a regular pipe to pass the tuple to the function instead of to the extracted value.
In practice this often happens as the last step because we can’t put off handling errors forever.
And nor should we, code is confident when we can handle errors all in one place.
This last function that knows about errors expects a tuple and not just the value  - to label this difference I normally name them &lt;code class=&quot;highlighter-rouge&quot;&gt;handle_something&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;So does considering monads in a pipeline help or hinder your thinking?
I think it helps and have managed to use a result pipeline in a couple of places so far.
If you are able to try it out do let me know how it goes.&lt;/p&gt;

&lt;h3 id=&quot;resources&quot;&gt;Resources&lt;/h3&gt;
&lt;p&gt;Finally a few excellent resources on monads if you want to read further but I stress that a full understanding is not necessary to enjoy the benefits.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/CrowdHailer/OK&quot;&gt;OK&lt;/a&gt;
Elegant error handling in elixir pipelines.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=J1jYlPtkrqQ&quot;&gt;Refactoring Ruby with Monads&lt;/a&gt;&lt;br /&gt;
Whistle-stop tour of monads with &lt;a href=&quot;https://twitter.com/tomstuart&quot;&gt;Tom Stuart&lt;/a&gt;. His &lt;code class=&quot;highlighter-rouge&quot;&gt;Optional&lt;/code&gt; is the analogue of the Result monad.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://adit.io/posts/2013-04-17-functors,_applicatives,_and_monads_in_pictures.html&quot;&gt;Monads in Pictures&lt;/a&gt;&lt;br /&gt;
Best resource for explaining monads, done with pictures. Thanks to &lt;a href=&quot;https://twitter.com/_egonschiele&quot;&gt;Aditya Bhargava&lt;/a&gt; for this one.&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Sun, 18 Oct 2015 17:00:05 +0000</pubDate>
        <link>http://insights.workshop14.io/2015/10/18/handling-errors-in-elixir-no-one-say-monad.html</link>
        <guid isPermaLink="true">http://insights.workshop14.io/2015/10/18/handling-errors-in-elixir-no-one-say-monad.html</guid>
        
        <category>Elixir</category>
        
        <category>Functional Programming</category>
        
        <category>Monad</category>
        
        
      </item>
    
      <item>
        <title>Domain Driven Design, Where the real value lies.</title>
        <description>&lt;p&gt;Conclusion of &lt;a href=&quot;/2015/07/14/domain-driven-design-introduction.html&quot;&gt;Domain Drive Design series&lt;/a&gt; following on from &lt;a href=&quot;/2015/08/16/introducing-interactors-to-represent-getting-stuff-done.html&quot;&gt;Interactors&lt;/a&gt;.&lt;/p&gt;

&lt;h3 id=&quot;confession&quot;&gt;Confession&lt;/h3&gt;

&lt;p&gt;This is the final post in this series, and I have a confession.
What has been discussed so far has not been the whole story of Domain Driven Design.&lt;/p&gt;

&lt;p&gt;So far several useful patterns have been covered.
These make up the tactics of Domain Driven Design.
However tactics should not be employed without a strategy. Without an understanding of the strategy you will end up with a cargo cult.
I did not realise the importance of the strategy when I started writing these articles.
And in my defence, even Eric Evans has said he wishes that he put more emphasis on the strategy in his &lt;a href=&quot;http://www.amazon.co.uk/Domain-driven-Design-Tackling-Complexity-Software/dp/0321125215&quot;&gt;book&lt;/a&gt; that started Domain Driven Design.&lt;/p&gt;

&lt;h3 id=&quot;explaining-the-strategy&quot;&gt;Explaining the strategy.&lt;/h3&gt;
&lt;p&gt;Domain Driven Design has much to say on the best environment for development.
Key is that all interested parties in a project are able to understand each other.
These parties could be developers, managers, client, designers, customers and more.
To ensure understanding, time should be spent to develop a domain specific language.
In addition barriers between those developing the software and the users of the software should be eliminated as much as possible.&lt;/p&gt;

&lt;p&gt;Once this has been achieved the developers should not need to make assumptions and instead consult stakeholders when making decisions.
Implementing software is difficult enough and without distilled domain knowledge it has very little chance of solving the problem at hand.&lt;/p&gt;

&lt;p&gt;Much of the strategy can be described as common sense but that doesn’t mean it does not bear repeating or explicitly naming.
I think it is unhelpful that both the tactics and strategy of Domain Driven Design are interlaced.
To encapsulate the core concepts of the strategy in Domain Driven Design I would like to try the following definition.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;strong&gt;Knowledge Limited Programming:&lt;/strong&gt; The decision to not develop a piece of code until the situation requiring its development is known.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3 id=&quot;revisiting-the-tactics&quot;&gt;Revisiting the tactics&lt;/h3&gt;

&lt;p&gt;With an understanding of the strategy we can reexamine the patterns in a more informed context.
There are two distinct groups for the design objects.
First, those that represent concepts from the domain.
They are:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;/2015/08/02/tackling-god-objects-in-ruby.html&quot;&gt;Entities&lt;/a&gt; - A domain object with an identity that can change over time, such as customer.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;/2015/07/15/value-objects-in-ruby.html&quot;&gt;Values&lt;/a&gt; - A domain object without an identity separate to its attributes e.g. price, discount code or address.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;/2015/08/16/introducing-interactors-to-represent-getting-stuff-done.html&quot;&gt;Interactors&lt;/a&gt; - A domain object that represents an action or activity e.g. login, checkout, signup etc.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The rest with the purpose of protecting the core domain from technical concerns.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;/2015/07/23/application-border-control-with-ruby-form-objects.html&quot;&gt;Form objects&lt;/a&gt; - Prevents the HTML form considerations effecting our domain&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;/2015/08/09/untangle-your-domain-model-from-the-database.html&quot;&gt;Repository&lt;/a&gt; - Prevents the database structure from penetrating the domain model&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Without the strategy it is tempting to ask developers what entities should look like.
With the strategy the answer is whatever makes most sense in the domain.
Of course there are many similarities between projects that allow common behaviour to be reused but the domain model should not be tied to a library’s language or layout.
My mantra for employing the tactics of Domain Driven Design would be:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Use domain concepts not language constructs.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I have written gems to help with value objects and form objects, both are small so they encroach as little as possible on the domain.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/CrowdHailer/typetanic&quot;&gt;Typetanic&lt;/a&gt; A library of value objects to help start a project, at the moment just email. As your domain grows richer you should throw out the Typetanic version and replace with custom implementations.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/CrowdHailer/vulcanize&quot;&gt;Vulcanize&lt;/a&gt; A library for building form objects. Domain representation is handled by value objects that the consumer needs to provide.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;rails-friend-or-foe&quot;&gt;Rails: friend or foe?&lt;/h3&gt;
&lt;p&gt;When I started investigating Domain Driven Design, I tried to push as far away from Rails conventions as possible.
This was not due to dislike of Rails but to get the perspective that comes with distance.&lt;/p&gt;

&lt;p&gt;Within Rails there is a strategy and tactics, the “Rails way” and the “Rails stack” consisting of all the “Active* Gems”.
The strategy is to define what is common across applications. Then to provide that core as a default without any thought needed on the developers part.
This is exactly the opposite of defining a domain language specifically for your problem.
I am of the opinion that the “Rails Way” is incompatible with the strategy of Domain Driven Design.&lt;/p&gt;

&lt;p&gt;Rails strategy is implemented with a well defined MVC architecture.
MVC provides a clear way to break up an application into the three layers.
However, there is no help in deciding how to break down an application further.
The patterns from Domain Driven Design do however help with breaking down the domain model.
It is certainly possible to use Domain Driven Design to break down a model with an MVC application.
I am of the opinion that the “Rails Stack” is compatible within a domain driven application.&lt;/p&gt;

&lt;h3 id=&quot;other-views&quot;&gt;Other views&lt;/h3&gt;

&lt;p&gt;What about Domain Driven Design compared to hexagonal rails and clean architecture?
The patterns of DDD are represented in both of these architectures.
For example, clean architecture makes use of interactors to separate a delivery mechanism from a core of entities.
Hexagonal Rails talks of ports in the domain for infrastructure adapters. The UI adapter is the delivery mechanism and a database adapter could be encapsulated by a repository.&lt;/p&gt;

&lt;p&gt;The strategic side of Domain Driven Design is emphasised less in the other two.
Patterns are suggested for technical benefits.
Code is more extensible, more maintainable; easier to test.
These improvements will of course lead to faster development cycles and happier clients/customers but the emphasis seems to be on the technical wins.
I think this emphasis is important because DDD has a helpful dialogue on when not to implement any of the advanced patterns.
Take for example the following hypothetical conversation.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;After thrashing out the details we discovered that what the client wanted was a Rails app, so we build a Rails app.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This discussion focuses on the core of the Domain Driven Design strategy.&lt;/p&gt;

&lt;h3 id=&quot;whats-next&quot;&gt;What’s next&lt;/h3&gt;

&lt;p&gt;I have been developing an &lt;a href=&quot;https://github.com/CrowdHailer/just-job&quot;&gt;example ddd project&lt;/a&gt; - it is a to-do list.
It may be small but the strategy of DDD should be applicable to a project of any size. It is a work in progress and would be a great place to discuss DDD. Just open an issue if you think I can do it better.&lt;/p&gt;

&lt;p&gt;A few parting thoughts on lessons I have learned:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;If there is such a thing as strings in your domain their length method should return a number in centimeters&lt;/li&gt;
  &lt;li&gt;Prefer vertical grouping, section not layers&lt;/li&gt;
  &lt;li&gt;Do not redesign code for tests but if it’s hard to test, that is a warning&lt;/li&gt;
  &lt;li&gt;Design patterns are most useful for communication between humans&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;resources&quot;&gt;Resources&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://gorodinski.com/blog/2013/03/11/the-two-sides-of-domain-driven-design/#.VdO9AIJSIUA.twitter&quot;&gt;The Two Sides of Domain-Driven Design (DDD)&lt;/a&gt;&lt;br /&gt;
This post from &lt;a href=&quot;https://twitter.com/eulerfx&quot;&gt;Lev Gorodinski&lt;/a&gt; explores Domain-Driven Design from the tactical and strategic perspectives&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://subvisual.co/blog/posts/20-clean-architecture&quot;&gt;Clean Architecture&lt;/a&gt;&lt;br /&gt;
A really comprehensive article on employing clean architecture with the Rails stack by &lt;a href=&quot;https://twitter.com/zamith&quot;&gt;Luis Zamith&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.se-radio.net/2015/05/se-radio-episode-226-eric-evans-on-domain-driven-design-at-10-years/&quot;&gt;Eric Evans on Domain-Driven Design at 10 Years&lt;/a&gt;&lt;br /&gt;
Really interesting chat with &lt;a href=&quot;https://twitter.com/ericevans0&quot;&gt;Eric Evans&lt;/a&gt; on the 10 years of Domain Driven Design since his book was released.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/CrowdHailer/just-job&quot;&gt;Just Job&lt;/a&gt;&lt;br /&gt;
A to-do list built from the ground up using the principles of Domain Driven Design(DDD)&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;/2015/07/14/domain-driven-design-introduction.html&quot;&gt;Dicovering the joy of over design&lt;/a&gt;&lt;br /&gt;
The beginning of these articles, getting started with Domain Driven Design.&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Thu, 20 Aug 2015 16:56:05 +0000</pubDate>
        <link>http://insights.workshop14.io/2015/08/20/domain-driven-design-where-the-real-value-lies.html</link>
        <guid isPermaLink="true">http://insights.workshop14.io/2015/08/20/domain-driven-design-where-the-real-value-lies.html</guid>
        
        <category>Ruby</category>
        
        <category>Domain Driven Design</category>
        
        
      </item>
    
      <item>
        <title>Introducing Interactors to represent getting stuff done.</title>
        <description>&lt;p&gt;Part 5 in &lt;a href=&quot;/2015/07/14/domain-driven-design-introduction.html&quot;&gt;Domain Drive Design series&lt;/a&gt; following on from &lt;a href=&quot;/2015/08/09/untangle-your-domain-model-from-the-database.html&quot;&gt;Repositories&lt;/a&gt;.&lt;/p&gt;

&lt;h3 id=&quot;whats-in-a-name&quot;&gt;What’s in a name?&lt;/h3&gt;
&lt;p&gt;Interactors suffer from a bit of an identity crisis. I have seen them called ‘interactors’, ‘use cases’ and ‘service objects’. Here is my take on each of those terms:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;strong&gt;Service object&lt;/strong&gt; is used to describe the encapsulation of an external service that your system uses. E.g. you might have an ‘email’ service object.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;strong&gt;Use case&lt;/strong&gt; makes the most sense on a non-technical level, so the ‘Login usecase’ is something that a customer does.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;strong&gt;Interactor&lt;/strong&gt; is the technical term for the Ruby object that is used to perform a given use case.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I believe ‘interactor’ is the most useful term when talking about an implementation and will therefore stick to that.&lt;/p&gt;

&lt;h3 id=&quot;what-are-interactors&quot;&gt;What are interactors?&lt;/h3&gt;
&lt;p&gt;An interactor orchestrates components in a system to complete a specific business use case. It is important that an interactor knows how to delegate — the desired result should be achieved without the interactor carrying out any of the work itself. It should also know nothing about how the result of its action will be presented to the user.&lt;/p&gt;

&lt;p&gt;As something that is defined by what they do not do, it is tricky to see the value out of context. However the separation they enforce between the code that deals with rendering, HTTP, and sessions from the code with the important business logic rapidly increases in value as the system grows. It also removes dependence on any particular framework; when all the framework code is outside the interactors then it can be replaced whilst leaving the business logic untouched.&lt;/p&gt;

&lt;h3 id=&quot;basic-structure&quot;&gt;Basic Structure&lt;/h3&gt;
&lt;p&gt;An interaction can occur only once. A user many try the same interaction multiple times but as a different outcome is possible on each occasion it is classified as a separation interaction. What happens as the result of an interaction cannot be changed after it has occurred.&lt;/p&gt;

&lt;p&gt;An instance of an interactor is used to represent a single interaction. To reflect the desired behaviour it is initialized with all of the required parameters and context; these cannot be modified after initialization. On the object the only methods that are available are query methods to report on what occurred. People often add &lt;code class=&quot;highlighter-rouge&quot;&gt;success?/failure?&lt;/code&gt; methods but I try to use terms that are specific to the interaction such as &lt;code class=&quot;highlighter-rouge&quot;&gt;created?/deleted?/approved?&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;That interactors cannot be modified means they are immutable. Ruby makes immutability hard so I do not write any code to enforce this and simply follow the convention of only querying they response object.&lt;/p&gt;

&lt;p&gt;An example interactor representing the user use case of creating a post for a blog might look something like the following.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;c1&quot;&gt;# Inside a controller action&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;create&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;# Coerce insecure user input into the domain context&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;form&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;CreatePostForm&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:post&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;

  &lt;span class=&quot;c1&quot;&gt;# Run the use case passing in everything that is needed as arguments&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;create_post&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;CreatePost&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;form&lt;/span&gt;

  &lt;span class=&quot;c1&quot;&gt;# Query the interactor instance on the outcome of the interaction&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;create_post&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;created?&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;redirect_to&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;post_url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;create_post&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;post&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;
    &lt;span class=&quot;vi&quot;&gt;@form&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;create_post&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;form&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;render&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:new&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# in a create_post.rb file&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;CreatePost&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;# initialize with the params in the form and the user in the context&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;initialize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;context&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;form&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;vi&quot;&gt;@form&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;form&lt;/span&gt;
    &lt;span class=&quot;vi&quot;&gt;@user&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;context&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;current_user&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;kp&quot;&gt;attr_reader&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:form&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:user&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:post&lt;/span&gt;

  &lt;span class=&quot;kp&quot;&gt;private&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;run&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;form&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;valid?&lt;/span&gt;
      &lt;span class=&quot;vi&quot;&gt;@post&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Post&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;create&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;form&lt;/span&gt;
      &lt;span class=&quot;vi&quot;&gt;@created&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kp&quot;&gt;true&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;The controller action knows how to call an interactor as well as the methods it can query to find the outcome.
The controller may not interact with the domain in any other way, all entities, values and services and invisible to it.
The interactor does not know anything about the framework, the results it exposes have no knowledge of how they will be presented, i.e. there are no &lt;code class=&quot;highlighter-rouge&quot;&gt;to_html&lt;/code&gt; methods. The controller or a dedicated presenter will convert the plain data objects into a rendered view.&lt;/p&gt;

&lt;p&gt;The interactors demote a strong boundary between your domain code which should be pure ruby and your framework code which can be full of framework specific terms, from rails/sinatra/etc. This boundary allows you to test the two pieces in isolation.&lt;/p&gt;

&lt;h4 id=&quot;testing-the-domain&quot;&gt;Testing the domain&lt;/h4&gt;
&lt;p&gt;Testing the domain with interactors is easy because they explicitly passed all parameters during there initialization. The steps to test the domain are setup the arguments to be passed to the Interactor, initialize the interactor and finally query on the result. It is immutable so test can be run in any order. The benefits of this include.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;There is no need to have a step where you log in the user. Just pass any user into the context&lt;/li&gt;
  &lt;li&gt;Any other awkward things like mailers or bug reporting can have null implementations, also part of the context.&lt;/li&gt;
  &lt;li&gt;All return values are Ruby objects and these are much easier to test on.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With interactors it also becomes much easier to write an integration test than to write a test that needs to make a HTTP request and understand HTML responses. This is an example of testing an interactor.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;CreatePostTest&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Minitest&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Test&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;valid_form&lt;/span&gt;
    &lt;span class=&quot;no&quot;&gt;CreatePostForm&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:title&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'A nice title'&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;invalid_form&lt;/span&gt;
    &lt;span class=&quot;no&quot;&gt;CreatePostForm&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:title&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'&amp;lt;script&amp;gt;bad code&amp;lt;/script&amp;gt;'&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;context&lt;/span&gt;
    &lt;span class=&quot;no&quot;&gt;OpenStruct&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:current_user&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;nullUser&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test_will_not_create_post_with_invalid_title&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;create_post&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;CreatePost&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;context&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;invalid_form&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;refute&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;create_post&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;created?&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test_will_create_post_with_valid_title&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;create_post&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;CreatePost&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;context&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;valid_form&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;assert&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;create_post&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;created?&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Compare this with the last test you wrote where you had to check an action from a logged in user which required RackTest or Capybara.&lt;/p&gt;

&lt;h3 id=&quot;testing-the-controllers-and-views&quot;&gt;Testing the controllers and views&lt;/h3&gt;
&lt;p&gt;Working with interactors does not improve dealing with HTML parsing or setting up session data. In those test you will still want to make use of RackTest or Capybara. What it does do is make those tests a whole lot simpler. You can write a single test for each possible outcome for a given interactor where the outcome is stubbed. With one logical test for each usecase outcome you can escape from trying to test the domain through the unwieldy web based interface.&lt;/p&gt;

&lt;h3 id=&quot;my-interactor-implementation-allsystems&quot;&gt;My interactor implementation AllSystems&lt;/h3&gt;
&lt;p&gt;It would certainly be possible to implement interactors without a gem. I am also a fan of less dependencies where possible. However using a very small gem allows me not have to keep checking the plumbing of my interactor objects. I have written a gem called AllSystems that allows blocks to be passed for each possible outcome. This follows the principle of tell don’t ask which is best laid out in the talk eastward oriented code.&lt;/p&gt;

&lt;p&gt;So what do you think? Will you be tempted to try interactors or do you have a way to keep the framework you use encapsulated? Leave me a comment I will be very interested.&lt;/p&gt;

&lt;h3 id=&quot;resources&quot;&gt;Resources&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://technology.stitchfix.com/blog/2015/06/02/anatomy-of-service-objects-in-rails/&quot;&gt;Anatomy of a Rails Service Object&lt;/a&gt;&lt;br /&gt;
Overview on designing a service object in rails from &lt;a href=&quot;https://twitter.com/davetron5000&quot;&gt;David Copeland&lt;/a&gt;. These are interactors as describe here and they should work outside of rails.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://medium.com/@KamilLelonek/what-service-objects-are-not-7abef8aa2f99&quot;&gt;What service objects are not&lt;/a&gt;&lt;br /&gt;
Again called service objects this is a good post from &lt;a href=&quot;https://twitter.com/KamilLelonek&quot;&gt;Kamil Lelonek&lt;/a&gt;. Good advice on what does not belong in an interactor, hint it’s nearly everything.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://confreaks.tv/videos/rubyconf2014-eastward-ho-a-clear-path-through-ruby-with-oo&quot;&gt;Eastward Ho! A Clear Path Through Ruby With OO&lt;/a&gt;&lt;br /&gt;
One of the best talks online. Jim Gay gives advice for writing code that follows tell don’t ask.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/CrowdHailer/AllSystems&quot;&gt;AllSystems gem&lt;/a&gt;&lt;br /&gt;
Simple interactor objects in Ruby written by myself.&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Sun, 16 Aug 2015 16:56:05 +0000</pubDate>
        <link>http://insights.workshop14.io/2015/08/16/introducing-interactors-to-represent-getting-stuff-done.html</link>
        <guid isPermaLink="true">http://insights.workshop14.io/2015/08/16/introducing-interactors-to-represent-getting-stuff-done.html</guid>
        
        <category>Ruby</category>
        
        <category>Domain Driven Design</category>
        
        
      </item>
    
      <item>
        <title>Untangle your Domain Model from the Database</title>
        <description>&lt;p&gt;Part 5 in &lt;a href=&quot;/2015/07/14/domain-driven-design-introduction.html&quot;&gt;Domain Drive Design series&lt;/a&gt; following on from &lt;a href=&quot;http://insights.workshop14.io/2015/08/02/tackling-god-objects-in-ruby.html&quot;&gt;Entities and Records&lt;/a&gt;.&lt;/p&gt;

&lt;h3 id=&quot;the-domain-model-is-not-just-model-objects&quot;&gt;The Domain Model is not just model objects&lt;/h3&gt;

&lt;p&gt;I have asserted that for any non-trivial program the modeling of the problem space should not be handled by individual model objects. Instead it should be handled through the coordinated action of many domain objects. In the last post we introduced entities and records to handle some of the concerns of modeling a system. In this post we discuss the repository pattern as a solution to our need to store and recover those entities and records.&lt;/p&gt;

&lt;p&gt;I would recommend reading the post on &lt;a href=&quot;http://insights.workshop14.io/2015/08/02/tackling-god-objects-in-ruby.html&quot;&gt;Entities and Records&lt;/a&gt; first. Don’t want to? Well, in summary, records are dumb data stores where the state of the system resides. Entities are stateless wrappers for records that hold behaviour that requires some of the records contents. We do not need to know of the existence of the records and should interact with them only through the entities that wrap them.&lt;/p&gt;

&lt;h3 id=&quot;the-problem-of-persistence&quot;&gt;The Problem of Persistence&lt;/h3&gt;
&lt;p&gt;The database is a small concern in a system. It is easy to forget this when developing in frameworks where you have to choose the database up front and where the methods on a model are exact reflections of your database schema. The littering of database concerns across the codebase is a distraction from writing the code most suited to your domain. For this reason we treat the database as a detail and want it isolated from the core entities.&lt;/p&gt;

&lt;p&gt;We want to get to a stage where we have record objects that we do not interact with directly and entities that have no knowledge of the database. This is excellent — we have achieved separating knowledge of the database and the main behaviour of the application.&lt;/p&gt;

&lt;p&gt;Now we need a way to persist the records. This task falls to a repository. The repository will be the only thing that knows the storage mechanism supporting the application.&lt;/p&gt;

&lt;h3 id=&quot;using-a-repository&quot;&gt;Using a Repository&lt;/h3&gt;

&lt;p&gt;Here is a quick one sentence summary of the repository pattern by Martin Fowler:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;A Repository mediates between the domain and data mapping layers, acting like an in-memory domain object collection.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Before proceeding we need to introduce the concept of an aggregate. In the last post we introduced two entities: a &lt;code class=&quot;highlighter-rouge&quot;&gt;User&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;Credentials&lt;/code&gt; both of which wrapped a record object the &lt;code class=&quot;highlighter-rouge&quot;&gt;User::Record&lt;/code&gt;. This collection of objects acted together to model a single user. Collections like this are described in Domain Driven Design as an aggregate. Martin Fowler provides an excellent &lt;a href=&quot;http://martinfowler.com/bliki/DDD_Aggregate.html&quot;&gt;summary on aggregates&lt;/a&gt;. This description comes with advice on handling these aggregates. Key is that one of the components should be recognisable as the aggregate root and any reference from outside the aggregate should go to the root only.&lt;/p&gt;

&lt;p&gt;In our system the &lt;code class=&quot;highlighter-rouge&quot;&gt;User&lt;/code&gt; is the root of the aggregate. This implies we should only be able to get load or save our user entity and the credentials it comes with and not directly load/save the credentials object. For this reason we need a repository of users and not one of credentials, this also explains why the record was named the &lt;code class=&quot;highlighter-rouge&quot;&gt;User::Record&lt;/code&gt; as it is an implementation detail that will be used as a foundation to our &lt;code class=&quot;highlighter-rouge&quot;&gt;User::Repository&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The key feature of our repository is that it should act as a collection of user entities. It does not need to look like a database and semantics of SQL or any other query language should not be evident in the API it exposes. The only difference between a repository and typical in-memory collection is that it will probably have a more sophisticated set of query methods than a normal collection.&lt;/p&gt;

&lt;p&gt;Let’s design how we would like a repository to be used. We will want simple queries such as &lt;code class=&quot;highlighter-rouge&quot;&gt;first&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;last&lt;/code&gt;. Retrieving by an id value is like a key lookup and so a &lt;code class=&quot;highlighter-rouge&quot;&gt;[]&lt;/code&gt; method is useful; or even better, a &lt;code class=&quot;highlighter-rouge&quot;&gt;fetch&lt;/code&gt; method. Then there will be queries that are specific to the collection; for example, finding all users by a family name.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;I recommend designing your API with pagination in mind unless you are sure it is unnecessary. This is because adding it later can be trouble.&lt;/em&gt;&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;c1&quot;&gt;# Simple query&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;adam&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;User&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Repository&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;first&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# =&amp;gt; #&amp;lt;User fullname=&quot;Adam Smith&quot;&amp;gt;&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Complex query, perhaps involving paginated results&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;johnes&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;User&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Repository&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;family&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;johnes&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;page: &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# =&amp;gt; [#&amp;lt;User fullname=&quot;Emma Johnes&quot;&amp;gt;, #&amp;lt;User fullname=&quot;Kate Johnes&quot;&amp;gt;]&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Handling missing entries with useful null objects&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;user&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;User&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Repository&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;fetch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'ID_001'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;GuestUser&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# =&amp;gt; #&amp;lt;GuestUser&amp;gt;&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Building empty entities with correct record structures&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;new_user&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;User&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Repository&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;build&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# =&amp;gt; #&amp;lt;User fullname=&quot;&quot;&amp;gt;&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Editing user&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;new_user&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;full_name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Peter Saxton&quot;&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# =&amp;gt; #&amp;lt;User fullname=&quot;Peter Saxton&quot;&amp;gt;&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Adding user to collection of users.&lt;/span&gt;
&lt;span class=&quot;no&quot;&gt;User&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Repository&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;save&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;new_user&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# =&amp;gt; #&amp;lt;User::Repository&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h3 id=&quot;building-the-repository&quot;&gt;Building the Repository&lt;/h3&gt;
&lt;p&gt;Once we know how we would like to use our repository, we can set about implementing it. There are several ways to go about this but I always try to go for the simplest.&lt;/p&gt;

&lt;p&gt;There are some very capable Object Relational Mappers available, the best being &lt;a href=&quot;http://sequel.jeremyevans.net/&quot;&gt;Sequel&lt;/a&gt;. I don’t want to reinvent handling SQL so I build on top of the Sequel library. The following implementation will realise the behaviour above:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;User&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Repository&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;self&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;build&lt;/span&gt;
      &lt;span class=&quot;no&quot;&gt;User&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;User&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Record&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;new&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;save&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;entity&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;entity&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;record&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;save&lt;/span&gt;
      &lt;span class=&quot;nb&quot;&gt;self&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;remove&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;entity&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;entity&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;record&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;destroy&lt;/span&gt;
      &lt;span class=&quot;nb&quot;&gt;self&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;rescue&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Sequel&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;NoExistingObject&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;raise&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;RecordAbsent&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;first&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;record&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;User&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Record&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;first&lt;/span&gt;
      &lt;span class=&quot;no&quot;&gt;User&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;record&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;last_login&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;record&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;User&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Record&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;sort&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:last_login_at&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;first&lt;/span&gt;
      &lt;span class=&quot;no&quot;&gt;User&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;record&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;family&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;last_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;page: &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;page_size: &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;15&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;records&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;User&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Record&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;where&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:last_name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;last_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;sort&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:first_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;paginate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;page&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;page_size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;records&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;map&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;User&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;new&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h3 id=&quot;design-overkill&quot;&gt;Design Overkill&lt;/h3&gt;
&lt;p&gt;This example repository does everything that is required of it. Despite that it fails on being elegant code. For example, the line &lt;code class=&quot;highlighter-rouge&quot;&gt;entity.record.save&lt;/code&gt; goes against the good advice of &lt;a href=&quot;https://en.wikipedia.org/wiki/Law_of_Demeter&quot;&gt;The Law of Demeter&lt;/a&gt;.It is also implicitly dependent on the &lt;code class=&quot;highlighter-rouge&quot;&gt;User::Record&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;User&lt;/code&gt; classes.&lt;/p&gt;

&lt;p&gt;There are ways to fix some of these design complaints. If you would like to see some of these solutions have a look at &lt;a href=&quot;https://github.com/lotus/model&quot;&gt;Lotus Model&lt;/a&gt; or &lt;a href=&quot;https://github.com/rom-rb&quot;&gt;Ruby Object Mapper (ROM)&lt;/a&gt;. However, in all the projects where I have employed a repository I have not gone much further than the code shown in the example above. As this series is all about well designed code and the benefits that can be got from doing the right thing, the question is: why do I stop here?&lt;/p&gt;

&lt;p&gt;To make a generic repository that can be backed by a sequel backend or an in-memory backend is complex. It requires adapters and an in-memory implementation of storage. If queries are sophisticated then the in memory-adapter needs to support a similar set of queries.&lt;/p&gt;

&lt;p&gt;Creating a generic query interface when I might never use it is overkill and so I choose to stick with the bad code. The saving grace with this dirty code is that it is contained within the repository.&lt;/p&gt;

&lt;p&gt;Another reason to create a generic adapter to the database is to allow testing without the database in place. As shown in the previous post I can test entities without a database by replacing the record objects with simple &lt;code class=&quot;highlighter-rouge&quot;&gt;OpenStructs&lt;/code&gt;. The remaining tests that can’t make this replacement are slower yet the number of tests are small because the repository is focused on handling only queries on the collection.&lt;/p&gt;

&lt;p&gt;In reality I have found this level of sophistication in the repository a good compromise between isolated code and building adapters that might never be used. As ROM or the Lotus model mature I might find myself using these and getting the isolation I have currently traded away.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Have you tried using the repository pattern or perhaps employ the datamapper pattern? Let me know in the comments below.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The next post will be the last in the series and will introduce &lt;a href=&quot;/2015/08/16/introducing-interactors-to-represent-getting-stuff-done.html&quot;&gt;interactors&lt;/a&gt;. Then we can finally mate our domain model with the framework of choice and make our program available to the world.&lt;/p&gt;

&lt;p&gt;Further reading:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://medium.com/@KamilLelonek/why-is-your-rails-application-still-coupled-to-activerecord-efe34d657c91&quot;&gt;Why is your Rails application still coupled to ActiveRecord?&lt;/a&gt;
Isolating your project from any ORM framework using the repository pattern by &lt;a href=&quot;https://twitter.com/KamilLelonek&quot;&gt;Kamil Lelonek&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://smashingboxes.com/ideas/domain-logic-in-rails&quot;&gt;Domain Logic in Rails&lt;/a&gt;
Using Domain Driven Design instead of the Rails way, I don’t think the two are as exculsive as &lt;a href=&quot;https://twitter.com/cogdog&quot;&gt;Alan Levine&lt;/a&gt; does but a good introduced none the less.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://hawkins.io/2014/01/pesistence_with_repository_and_query_patterns/&quot;&gt;Persistence with Repository and Query Patterns&lt;/a&gt;
Part of a very detailed series of posts on building DDD systems. Here &lt;a href=&quot;https://twitter.com/adman65&quot;&gt;Adam Hawkins&lt;/a&gt; tackles Repository and Query Patterns. Make time to read the rest they are all good references.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://thepaulrayner.com/blog/aggregates-and-entities-in-domain-driven-design/&quot;&gt;Aggregates &amp;amp; Entities in Domain-Driven Design&lt;/a&gt;
Insightful thoughts on the distinctions between aggregates and entities in domain driven design from &lt;a href=&quot;https://twitter.com/thepaulrayner&quot;&gt;Paul Rayner&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Sun, 09 Aug 2015 20:20:06 +0000</pubDate>
        <link>http://insights.workshop14.io/2015/08/09/untangle-your-domain-model-from-the-database.html</link>
        <guid isPermaLink="true">http://insights.workshop14.io/2015/08/09/untangle-your-domain-model-from-the-database.html</guid>
        
        <category>Ruby</category>
        
        <category>Domain Driven Design</category>
        
        
      </item>
    
      <item>
        <title>Tackling God objects in Ruby applications</title>
        <description>&lt;p&gt;Part 4 in &lt;a href=&quot;/2015/07/14/domain-driven-design-introduction.html&quot;&gt;Domain Drive Design series&lt;/a&gt; following on from &lt;a href=&quot;/2015/07/23/application-border-control-with-ruby-form-objects.html&quot;&gt;form objects&lt;/a&gt;.&lt;/p&gt;

&lt;h3 id=&quot;the-worst-advice-i-have-followed&quot;&gt;The worst advice I have followed&lt;/h3&gt;

&lt;blockquote&gt;
  &lt;p&gt;Fat Model, Skinny controller&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This advice is only good advice in that a fat model is slightly preferable to a fat controller. When creating projects with Rails I would have a single model for a single database table. So as a database table grows then data in the model representation grows. Object Oriented Programming (OOP) is about packaging behavior with data, as the data in the model increases the behavior on the model tends to follow this increase. Quite soon you end up with a fat model and shorty afterwards a God object. God objects are objects that seem to know and act upon all parts of the system. They are an antipattern that are in violation of the single responsibility principle.&lt;/p&gt;

&lt;p&gt;Recently I have seen people blaming Rails and particularly ActiveRecord (the library) for encouraging God objects. ActiveRecord is a beast but also a fantastic piece of software. Most importantly it is a tool and doesn’t encourage or discourage God objects. ActiveRecord does, however, facilitate making over sized objects if you are not disciplined. What does encourage creating God objects is simplistic advice such as ‘fat model skinny controller’.&lt;/p&gt;

&lt;p&gt;So what is good practise? Well I think that it is small, well defined, single responsibility objects everywhere.&lt;/p&gt;

&lt;h3 id=&quot;the-persistence-problem&quot;&gt;The persistence problem&lt;/h3&gt;

&lt;p&gt;Handling the data in a single database table, sounds like a single responsibility so why not a single object. That is a valid starting point but for anything beyond a trivial application it is too simplistic. To break apart our model let’s look at some of the key functionality we need when handling a database table.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;Data serialization. The database will not understand our domain objects, so we need to transform them to and from a format that the database does understand. We should do this as near the database as possible so that the database has the smallest possible influence on the rest of our code.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Querying. We will want to be able to fetch the correct items from our database. This may be simple or it may involve filtering on many fields, such as find all the declined orders for this month for customers who signed up more than a year ago.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Business Logic. What you want to accomplish with your data, this is specific to your problem and as such there is no limit to how complex this part might be.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;building-a-solution&quot;&gt;Building a solution&lt;/h3&gt;
&lt;p&gt;First we want to separate querying, this functionality acts on the whole database table while the other two parts need to act of individual entries. To handle querying we will introduce repositories in the next post.&lt;/p&gt;

&lt;p&gt;To split serialization and behavior I employ the decorator pattern. I have a core Record object that formats the data saved to it. Record objects are just dumb data buckets. Business logic is built into entities - each entity wraps a single record and has no state other that the record object it is decorating.&lt;/p&gt;

&lt;h4 id=&quot;records&quot;&gt;Records&lt;/h4&gt;
&lt;p&gt;These are the only objects anywhere in my system that know how data is stored in the database. We often don’t think about databases as out of our control but we did not build them and so the API is not of our design. Therefore it most likely will not be the best representation of data in our domain. For this reason Record objects act as gatekeepers to information from the database in a way analagous to form objects normalising input from user input.&lt;/p&gt;

&lt;p&gt;The only logic a Record object should have should be packing domain objects into the database and initializing domain objects from entries in the database.&lt;/p&gt;

&lt;p&gt;Talking to a database is a solved problem and I use an ORM, either ActiveRecord or Sequel. The benefits of using an ORM library is that I can write Record very quickly. However both ORMs have many features that allow them to act as far more than a data bucket. It is only by being disciplined that the functionality of a record remains serialization only.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;UserRecord&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Sequel&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:users&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h4 id=&quot;entities&quot;&gt;Entities&lt;/h4&gt;

&lt;p&gt;These objects encapsulate business logic and so have very little in common with each other, or across projects. The only consistent feature is that the are initialized with a record and that they cannot have any state on themselves. They must always update the record if something changes.&lt;/p&gt;

&lt;p&gt;Multiple entity classes can be created for a single record class. These entities are separated by business concerns and there is no limit to how many can be made for a single record. Now the behavior can be built up of small manageable parts no matter how large our database table grows.&lt;/p&gt;

&lt;p&gt;Other parts of the program should never need to interact with a record directly but only with an entity that is decorating it. Good DDD code should communicate in a language understood by the client. They will understand user but not ‘user entity’ or ‘user record’ for this reason the user is represented by the user entity and the user record is just an implementation detail&lt;/p&gt;

&lt;h3 id=&quot;examples&quot;&gt;Examples&lt;/h3&gt;
&lt;p&gt;A very typical example would be similar to the following. A user represents the information kept in the users database table. There is a good amount of meta information associated with the account such as authentication credentials.&lt;/p&gt;

&lt;p&gt;Following good design principles we have dedicated value objects for email, password and name. This means we have moved validation away from our entities. Our record layer will happily dump and load these value objects to the database. However features continue to be added and our user needs a combined full name and also the ability to authenticate. These methods are not part of the same set of responsibility and so we look for a way to separate them.&lt;/p&gt;

&lt;p&gt;Authentication is often a good candidate to be separated to a single purpose entity. In this example we have done just that and named the extracted class ‘Credentials’.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;UserRecord&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Sequel&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:users&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;# Turns database friendly representations of values in to rich objects specific to our domain&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;plugin&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:serialization&lt;/span&gt;

  &lt;span class=&quot;n&quot;&gt;serialize_attributes&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Email&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;method&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:dump&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Email&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;method&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:load&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)],&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:email&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;serialize_attributes&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Password&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;method&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:dump&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Password&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;method&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:load&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)],&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:password&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;serialize_attributes&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;method&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:dump&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;method&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:load&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)],&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:first_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:last_name&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;User&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;# Enities make no sense if they don't also have a record to preserve state&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;initialize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;record&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;vi&quot;&gt;@record&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;record&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;kp&quot;&gt;attr_reader&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:record&lt;/span&gt;
  &lt;span class=&quot;kp&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:record&lt;/span&gt;

  &lt;span class=&quot;c1&quot;&gt;# Behaviour that the user can handle itself.&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;full_name&lt;/span&gt;
    &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;record&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;first_name&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;record&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;last_name&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;full_name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;full_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;first_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;last_name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;full_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;split&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;' '&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;record&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;first_name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;first_name&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;record&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;last_name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;last_name&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;c1&quot;&gt;# Behaviour that the user delegates to a dedicated credentials object&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;authenticate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;submitted_password&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;credentials&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;authenticate&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;submitted_password&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;c1&quot;&gt;# The credentials object also uses the same record&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;credentials&lt;/span&gt;
    &lt;span class=&quot;vi&quot;&gt;@credentials&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Credentials&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;record&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Credentials&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;initialize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;record&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;vi&quot;&gt;@record&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;record&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;kp&quot;&gt;attr_reader&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:record&lt;/span&gt;
  &lt;span class=&quot;kp&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:record&lt;/span&gt;

  &lt;span class=&quot;c1&quot;&gt;# Logic for authentication can grow and is cleanly separated from the main user object&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;authenticate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;submitted_password&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kp&quot;&gt;nil&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;unless&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;correct_password?&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;submitted_password&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;record_login&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;self&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;kp&quot;&gt;private&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;correct_password?&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;submitted_password&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;record&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;password&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;submitted_password&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;record_login&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;date_time&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;DateTime&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;now&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;last_login_at&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;date_time&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h3 id=&quot;testing&quot;&gt;Testing&lt;/h3&gt;
&lt;p&gt;Testing records is done in much the same way as you would have tested methods on any ActiveRecord model. The main difference is that there should be much fewer tests and these tests should be simply setting a value and testing the same value is retrieved.&lt;/p&gt;

&lt;p&gt;Tests that hit the database are slower because of their interaction with the database. I don’t stub the database out at this level as a record is only about talking to the database. These tests are few enough that slower tests are not a problem.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;UserRecordTests&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;MiniTest&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Test&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;# My helper to refresh the database after each test&lt;/span&gt;
  &lt;span class=&quot;kp&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;DatabaseTesting&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test_can_save_first_name&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# create domain object&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;first_name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'Peter'&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;# set record entry&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;record&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;UserRecord&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;first_name: &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;first_name&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;# assert against domain object&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;assert_equal&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;first_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;record&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;first_name&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Testing for entities can easily be separated from the database by providing them with a stand in record. My tests all initialize the entity with an openstruct to stand in for the record. There are then two kinds of tests. First setting values on the openstruct and testing the entities behave correctly. Otherwise, manipulating the entity and asserting the correct values are in the openstruct&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;UserTest&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Minitest&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Test&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;record&lt;/span&gt;
    &lt;span class=&quot;vi&quot;&gt;@record&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;OpenStruct&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;new&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;user&lt;/span&gt;
    &lt;span class=&quot;vi&quot;&gt;@user&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;User&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;record&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;teardown&lt;/span&gt;
    &lt;span class=&quot;vi&quot;&gt;@user&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kp&quot;&gt;nil&lt;/span&gt;
    &lt;span class=&quot;vi&quot;&gt;@record&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kp&quot;&gt;nil&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test_user_has_correct_full_name&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# Setup record&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;record&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;first_name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'Peter'&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;record&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;last_name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'Saxton'&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;# Check behavior&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;assert_equal&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'Peter Saxton'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;full_name&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test_user_sets_first_name_on_record&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# Manipulate user&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;full_name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'Peter Saxton'&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;# Check record&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;assert_equal&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'Peter'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;record&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;first_name&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test_user_sets_last_name_on_record&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;full_name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'Peter Saxton'&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;assert_equal&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'Saxton'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;record&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;last_name&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h3 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h3&gt;

&lt;p&gt;This is my take on entities and records. I encourage you to give them a try as multiple entities can be an effective cure for god objects. This is not quite the whole persistence problem solved as we still need to pull the correct records out of our database. That is my next post and it’s on &lt;a href=&quot;http://insights.workshop14.io/2015/08/09/untangle-your-domain-model-from-the-database.html&quot;&gt;repositories&lt;/a&gt;.&lt;/p&gt;

&lt;h3 id=&quot;resources&quot;&gt;Resources&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://blog.joncairns.com/2013/04/fat-model-skinny-controller-is-a-load-of-rubbish/&quot;&gt;Fat model skinney controller is a load of rubbish&lt;/a&gt;
Don’t make my mistakes wish I had found this post earlier, thanks &lt;a href=&quot;https://twitter.com/joonty&quot;&gt;Jon Cairns&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://robots.thoughtbot.com/skinny-controllers-skinny-models&quot;&gt;Skinny Controllers, Skinny Models&lt;/a&gt;
Worth saying one more time, this time from thoughtbot and &lt;a href=&quot;https://twitter.com/joeferris&quot;&gt;Joe Ferris&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://viget.com/extend/how-i-used-activerecord-serialize-with-a-custom-data-type&quot;&gt;How I use ActiveRecord serialize with custom data types&lt;/a&gt;&lt;br /&gt;
Explaining the serialize method in active record by &lt;a href=&quot;https://twitter.com/zporter9&quot;&gt;Zachary Porter&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://victorsavkin.com/post/41016739721/building-rich-domain-models-in-rails-separating&quot;&gt;Building rich domain objects&lt;/a&gt;
Separating models on similar lines using models, data objects and repositories from &lt;a href=&quot;https://twitter.com/victorsavkin&quot;&gt;Victor Savkin&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Sun, 02 Aug 2015 21:20:00 +0000</pubDate>
        <link>http://insights.workshop14.io/2015/08/02/tackling-god-objects-in-ruby.html</link>
        <guid isPermaLink="true">http://insights.workshop14.io/2015/08/02/tackling-god-objects-in-ruby.html</guid>
        
        <category>Ruby</category>
        
        <category>Domain Driven Design</category>
        
        
      </item>
    
  </channel>
</rss>
