<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Caffeinated Ideas</title><link>https://caffeinatedideas.com/</link><description>Recent content on Caffeinated Ideas</description><generator>Hugo</generator><language>en-us</language><lastBuildDate>Fri, 25 Jun 2021 00:00:00 +0000</lastBuildDate><atom:link href="https://caffeinatedideas.com/index.xml" rel="self" type="application/rss+xml"/><item><title>This Week in Cats: EitherT</title><link>https://caffeinatedideas.com/2021/06/25/this-week-in-cats-eithert.html</link><pubDate>Fri, 25 Jun 2021 00:00:00 +0000</pubDate><guid>https://caffeinatedideas.com/2021/06/25/this-week-in-cats-eithert.html</guid><description>&lt;p&gt;Exceptions are the antithesis of functional programming since they
break referential transparency, the code after resolving the exception
cannot be substituted for the code prior to the exception. To avoid
exceptions but still communicate errors to callers, we end up using
the &lt;code&gt;Either&lt;/code&gt; type throughly through the code. We also want our code
to be async and so we also use the &lt;code&gt;Future&lt;/code&gt; type in the result which
leads to many methods like:&lt;/p&gt;</description></item><item><title>This Week in Cats: Eval</title><link>https://caffeinatedideas.com/2021/05/05/this-week-in-cats-eval.html</link><pubDate>Wed, 05 May 2021 00:00:00 +0000</pubDate><guid>https://caffeinatedideas.com/2021/05/05/this-week-in-cats-eval.html</guid><description>&lt;p&gt;One of the big patterns in software is the idea of evaluating some piece of logic once. Normally
this is done to obtain a value from a function or method call that takes some time to compute and
Scala proposes using lazy val for this purpose.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-scala" data-lang="scala"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;@&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; squareSlowly&lt;span style="color:#f92672"&gt;(&lt;/span&gt;i&lt;span style="color:#66d9ef"&gt;:&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;Int&lt;/span&gt;&lt;span style="color:#f92672"&gt;)&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;:&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;Int&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#f92672"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;Thread&lt;/span&gt;&lt;span style="color:#f92672"&gt;.&lt;/span&gt;sleep&lt;span style="color:#f92672"&gt;(&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;10000&lt;/span&gt;&lt;span style="color:#f92672"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; i &lt;span style="color:#f92672"&gt;*&lt;/span&gt; i
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;defined function squareSlowly
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;@&lt;/span&gt; squareSlowly&lt;span style="color:#f92672"&gt;(&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;10&lt;/span&gt;&lt;span style="color:#f92672"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// ... for 10 seconds ...
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;res1&lt;span style="color:#66d9ef"&gt;:&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;Int&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;100&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;@&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;lazy&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;val&lt;/span&gt; tenSq &lt;span style="color:#66d9ef"&gt;=&lt;/span&gt; squareSlowly&lt;span style="color:#f92672"&gt;(&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;10&lt;/span&gt;&lt;span style="color:#f92672"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;tenSq&lt;span style="color:#66d9ef"&gt;:&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;Int&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;lazy&lt;/span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#75715e"&gt;// notice the immediate return
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;@&lt;/span&gt; tenSq
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// ... for some time up to 10 seconds ...
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;res3&lt;span style="color:#66d9ef"&gt;:&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;Int&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;100&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;@&lt;/span&gt; tenSq
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;res4&lt;span style="color:#66d9ef"&gt;:&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;Int&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;100&lt;/span&gt; &lt;span style="color:#75715e"&gt;// notice the immediate return
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The problem here is that &lt;code&gt;tenSq&lt;/code&gt; is a variable and not a function call. If you wanted to pass
&lt;code&gt;tenSq&lt;/code&gt; into methods or functions, you would need to use the &lt;a href="https://docs.scala-lang.org/tour/by-name-parameters.html"&gt;call by name&lt;/a&gt; argument:&lt;/p&gt;</description></item><item><title>This Week in Cats: Kleisli</title><link>https://caffeinatedideas.com/2021/04/09/this-week-in-cats-kleisli.html</link><pubDate>Fri, 09 Apr 2021 00:00:00 +0000</pubDate><guid>https://caffeinatedideas.com/2021/04/09/this-week-in-cats-kleisli.html</guid><description>&lt;p&gt;&lt;a href="https://typelevel.org/cats/datatypes/kleisli.html"&gt;Kleisli&lt;/a&gt;. It’s got a funny name but it’s actually a simple concept. Suppose you have
two functions that you want to execute together:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-scala" data-lang="scala"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;val&lt;/span&gt; computeSquare&lt;span style="color:#f92672"&gt;(&lt;/span&gt;i&lt;span style="color:#66d9ef"&gt;:&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;Int&lt;/span&gt;&lt;span style="color:#f92672"&gt;)&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;:&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;Int&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; i &lt;span style="color:#f92672"&gt;*&lt;/span&gt; i
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;val&lt;/span&gt; formatResponse&lt;span style="color:#f92672"&gt;(&lt;/span&gt;i&lt;span style="color:#66d9ef"&gt;:&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;Int&lt;/span&gt;&lt;span style="color:#f92672"&gt;)&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;:&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;String&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;s&amp;#34;Your answer is &lt;/span&gt;&lt;span style="color:#e6db74"&gt;$i&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// One way of doing it is
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;val&lt;/span&gt; sqrAns &lt;span style="color:#66d9ef"&gt;=&lt;/span&gt; computeSquare&lt;span style="color:#f92672"&gt;(&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;3&lt;/span&gt;&lt;span style="color:#f92672"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;val&lt;/span&gt; strAns &lt;span style="color:#66d9ef"&gt;=&lt;/span&gt; formatResponse&lt;span style="color:#f92672"&gt;(&lt;/span&gt;sqrAns&lt;span style="color:#f92672"&gt;)&lt;/span&gt; &lt;span style="color:#75715e"&gt;// strAns = &amp;#34;Your answer is 9&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// or avoiding naming variable
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;val&lt;/span&gt; strAns &lt;span style="color:#66d9ef"&gt;=&lt;/span&gt; formatResponse&lt;span style="color:#f92672"&gt;(&lt;/span&gt;computeSquare&lt;span style="color:#f92672"&gt;(&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;3&lt;/span&gt;&lt;span style="color:#f92672"&gt;)).&lt;/span&gt; &lt;span style="color:#75715e"&gt;// strAns = &amp;#34;Your answer is 9&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Instead of needing to call these two functions over and over, either as individual lines or nested,
you can easily create a new function from the two that always does both using function composition:&lt;/p&gt;</description></item><item><title>This Week in Cats: Alternative</title><link>https://caffeinatedideas.com/2021/03/26/this-week-in-cats-alternative.html</link><pubDate>Fri, 26 Mar 2021 00:00:00 +0000</pubDate><guid>https://caffeinatedideas.com/2021/03/26/this-week-in-cats-alternative.html</guid><description>&lt;p&gt;Let’s say I have two methods that return &lt;code&gt;Either&lt;/code&gt; and I just want to take the
first successful result, only defaulting to the error return if both fail. For example, each method
is going to look at different fields of a request body and if the required fields are present, build
an object.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-scala" data-lang="scala"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;trait&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Credential&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;case&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;CredType1&lt;/span&gt;&lt;span style="color:#f92672"&gt;(&lt;/span&gt;username&lt;span style="color:#66d9ef"&gt;:&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;String&lt;/span&gt;&lt;span style="color:#f92672"&gt;,&lt;/span&gt; password&lt;span style="color:#66d9ef"&gt;:&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;String&lt;/span&gt;&lt;span style="color:#f92672"&gt;)&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;extends&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Credential&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;case&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;CredType2&lt;/span&gt;&lt;span style="color:#f92672"&gt;(&lt;/span&gt;token&lt;span style="color:#66d9ef"&gt;:&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;String&lt;/span&gt;&lt;span style="color:#f92672"&gt;)&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;extends&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Credential&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;case&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;ReqBody&lt;/span&gt;&lt;span style="color:#f92672"&gt;(&lt;/span&gt;username&lt;span style="color:#66d9ef"&gt;:&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;Option&lt;/span&gt;&lt;span style="color:#f92672"&gt;[&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;String&lt;/span&gt;&lt;span style="color:#f92672"&gt;],&lt;/span&gt; password&lt;span style="color:#66d9ef"&gt;:&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;Option&lt;/span&gt;&lt;span style="color:#f92672"&gt;[&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;String&lt;/span&gt;&lt;span style="color:#f92672"&gt;],&lt;/span&gt; token&lt;span style="color:#66d9ef"&gt;:&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;Option&lt;/span&gt;&lt;span style="color:#f92672"&gt;[&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;String&lt;/span&gt;&lt;span style="color:#f92672"&gt;])&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; maybeCredType1&lt;span style="color:#f92672"&gt;(&lt;/span&gt;req&lt;span style="color:#66d9ef"&gt;:&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;ReqBody&lt;/span&gt;&lt;span style="color:#f92672"&gt;)&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;:&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;Either&lt;/span&gt;&lt;span style="color:#f92672"&gt;[&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;Throwable&lt;/span&gt;, &lt;span style="color:#66d9ef"&gt;Credential&lt;/span&gt;&lt;span style="color:#f92672"&gt;]&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;=&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;Applicative&lt;/span&gt;&lt;span style="color:#f92672"&gt;[&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;Option&lt;/span&gt;&lt;span style="color:#f92672"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;.&lt;/span&gt;map2&lt;span style="color:#f92672"&gt;(&lt;/span&gt;req&lt;span style="color:#f92672"&gt;.&lt;/span&gt;username&lt;span style="color:#f92672"&gt;,&lt;/span&gt; req&lt;span style="color:#f92672"&gt;.&lt;/span&gt;password&lt;span style="color:#f92672"&gt;)(&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;CredType1&lt;/span&gt;&lt;span style="color:#f92672"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;.&lt;/span&gt;map&lt;span style="color:#f92672"&gt;(&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;Right&lt;/span&gt;&lt;span style="color:#f92672"&gt;(&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;_&lt;/span&gt;&lt;span style="color:#f92672"&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;.&lt;/span&gt;getOrElse&lt;span style="color:#f92672"&gt;(&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;Left&lt;/span&gt;&lt;span style="color:#f92672"&gt;(&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Exception&lt;/span&gt;&lt;span style="color:#f92672"&gt;(&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;Cred1 requires both a username and password&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;)))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; maybeCredType2&lt;span style="color:#f92672"&gt;(&lt;/span&gt;req&lt;span style="color:#66d9ef"&gt;:&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;ReqBody&lt;/span&gt;&lt;span style="color:#f92672"&gt;)&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;:&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;Either&lt;/span&gt;&lt;span style="color:#f92672"&gt;[&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;Throwable&lt;/span&gt;, &lt;span style="color:#66d9ef"&gt;Credential&lt;/span&gt;&lt;span style="color:#f92672"&gt;]&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;=&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; req&lt;span style="color:#f92672"&gt;.&lt;/span&gt;token
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;.&lt;/span&gt;map&lt;span style="color:#f92672"&gt;(&lt;/span&gt;value &lt;span style="color:#66d9ef"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Right&lt;/span&gt;&lt;span style="color:#f92672"&gt;(&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;CredType2&lt;/span&gt;&lt;span style="color:#f92672"&gt;(&lt;/span&gt;value&lt;span style="color:#f92672"&gt;)))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;.&lt;/span&gt;getOrElse&lt;span style="color:#f92672"&gt;(&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;Left&lt;/span&gt;&lt;span style="color:#f92672"&gt;(&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Exception&lt;/span&gt;&lt;span style="color:#f92672"&gt;(&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;Cred2 requires a token&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;)))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I could write some additional logic that calls the correct method based on the values in &lt;code&gt;ReqBody&lt;/code&gt; but then
I&amp;rsquo;d be duplicating the logic about which fields are required for which implementation of &lt;code&gt;Credential&lt;/code&gt;. This is
where we want to call both and take the first success. There are a number of ways I could implement that, pattern
matching, for comprehension, nested maps, but as I suspected this is a solved problem. Cats defines the &lt;code&gt;&amp;lt;+&amp;gt;&lt;/code&gt;
operator to implement this kind of alternative matching behavior.&lt;/p&gt;</description></item><item><title>This Week in Cats</title><link>https://caffeinatedideas.com/2021/03/25/this-week-in-cats.html</link><pubDate>Thu, 25 Mar 2021 00:00:00 +0000</pubDate><guid>https://caffeinatedideas.com/2021/03/25/this-week-in-cats.html</guid><description>&lt;p&gt;As I mentioned &lt;a href="https://caffeinatedideas.com/2020/04/08/2020-q1-tech-radar-update.html"&gt;last April&lt;/a&gt;, I ended up switching jobs and found myself in a Scala
shop that embraced the &lt;a href="https://typelevel.org/"&gt;Typelevel&lt;/a&gt; functional programming style. As I worked on tickets
and shippped features, I started to deep dive into the cats library. Many of the concepts
made my life easier and so I sarted to share them internally in a learning slack channel.&lt;/p&gt;
&lt;p&gt;It then dawned on me that they might also be useful for others. As time permits, I&amp;rsquo;m going
to clean up the slack posts and start a new series - This Week In Cats. It&amp;rsquo;s probably a mistake
to committing to a weekly post but that&amp;rsquo;s the name of the series in slack.&lt;/p&gt;</description></item><item><title>2020 Q2 Tech Radar Update</title><link>https://caffeinatedideas.com/2020/06/29/2020-q2-tech-radar-update.html</link><pubDate>Mon, 29 Jun 2020 00:00:00 +0000</pubDate><guid>https://caffeinatedideas.com/2020/06/29/2020-q2-tech-radar-update.html</guid><description>&lt;p&gt;With 2020 closing in on the half way point, it&amp;rsquo;s time to reflect back on the goals
I had set this year and see how they&amp;rsquo;re holding up.&lt;/p&gt;
&lt;h2 id="reviewing-the-q2-updated-plan"&gt;Reviewing the Q2 Updated Plan&lt;/h2&gt;
&lt;p&gt;Going into Q2, I made a lot of adjustments to my tech radar goals when I moved
to &lt;a href="https://www.rallyhealth.com/"&gt;Rally&lt;/a&gt;. The move to Rally was a very positive change but required ramping
up on &lt;a href="https://www.scala-lang.org/"&gt;Scala&lt;/a&gt; - something I did not anticipate at the beginning of the year.
So, how did I do on my new list?&lt;/p&gt;</description></item><item><title>Updating main git branch name</title><link>https://caffeinatedideas.com/2020/06/16/updating-main-git-branch-name.html</link><pubDate>Tue, 16 Jun 2020 00:00:00 +0000</pubDate><guid>https://caffeinatedideas.com/2020/06/16/updating-main-git-branch-name.html</guid><description>&lt;p&gt;There&amp;rsquo;s a lot of terminology we use without thinking about the meaning of those words.
When I started tinkering around with the insides of the IBM PC and configuring hard drives,
it was common to see references to the master and the slave drive in the BIOS and on the
jumper settings. Those same terms were used in textbooks and lectures about database systems
and highly available system designs in the 90s.&lt;/p&gt;</description></item><item><title>Scala's foldLeft Operator Demystified</title><link>https://caffeinatedideas.com/2020/05/07/scalas-foldleft-operator-demystified.html</link><pubDate>Thu, 07 May 2020 00:00:00 +0000</pubDate><guid>https://caffeinatedideas.com/2020/05/07/scalas-foldleft-operator-demystified.html</guid><description>&lt;p&gt;Back in 2012 I wrote a blog entry, &lt;a href="https://caffeinatedideas.com/2012/07/12/scala-syntactical-heartburn.html"&gt;Scala Syntactical Heartburn&lt;/a&gt;, in which I
said&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The first approach, using the /: operator, doesn&amp;rsquo;t make sense. I&amp;rsquo;m not sure how I get foldLeft,
inject, or whatever else you want to use to describe the operation out of this symbol.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Well, that changed this week while reading &lt;a href="https://www.manning.com/books/functional-programming-in-scala"&gt;Functional Programming in Scala&lt;/a&gt;. In chapter
3, there is a discussion on how to create an immutable, functional List type and doing interesting
operations on the list, like summing the list. Enter foldLeft and foldRight.&lt;/p&gt;</description></item><item><title>Type Hint ProcessBuilder Calls</title><link>https://caffeinatedideas.com/2020/04/24/type-hint-processbuilder-calls.html</link><pubDate>Fri, 24 Apr 2020 00:00:00 +0000</pubDate><guid>https://caffeinatedideas.com/2020/04/24/type-hint-processbuilder-calls.html</guid><description>&lt;p&gt;One of the many things that OpsCenter had to do was spawn new processes
with custom environment variables using the &lt;code&gt;environment()&lt;/code&gt;
method on the &lt;a href="https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/ProcessBuilder.html"&gt;ProcessBuilder&lt;/a&gt; class. The method, which embraces mutable
state, returns a &lt;code&gt;Map&amp;lt;String, String&amp;gt;&lt;/code&gt; that you need to update with whatever
new values you want to pass through to the new process.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-clojure" data-lang="clojure"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;(&lt;span style="color:#66d9ef"&gt;defn &lt;/span&gt;start-application []
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; (&lt;span style="color:#66d9ef"&gt;let &lt;/span&gt;[cmd (into-array String [&lt;span style="color:#e6db74"&gt;&amp;#34;java&amp;#34;&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;-jar&amp;#34;&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;App.jar&amp;#34;&lt;/span&gt;])
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; proc-builder (&lt;span style="color:#a6e22e"&gt;ProcessBuilder.&lt;/span&gt; cmd)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; env (&lt;span style="color:#a6e22e"&gt;.environment&lt;/span&gt; proc-builder)]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; (&lt;span style="color:#a6e22e"&gt;.put&lt;/span&gt; env &lt;span style="color:#e6db74"&gt;&amp;#34;ENV_NAME&amp;#34;&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;dev&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; (&lt;span style="color:#a6e22e"&gt;.start&lt;/span&gt; proc-builder)))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The &lt;code&gt;start-application&lt;/code&gt; function spawns a new Java application while setting the
&lt;code&gt;ENV_NAME&lt;/code&gt; parameter for the local machine and returns the new &lt;a href="https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/Process.html"&gt;&lt;code&gt;Process&lt;/code&gt;&lt;/a&gt; object.&lt;/p&gt;</description></item><item><title>2020 Q1 Tech Radar Update</title><link>https://caffeinatedideas.com/2020/04/08/2020-q1-tech-radar-update.html</link><pubDate>Wed, 08 Apr 2020 00:00:00 +0000</pubDate><guid>https://caffeinatedideas.com/2020/04/08/2020-q1-tech-radar-update.html</guid><description>&lt;p&gt;Hard to believe but we&amp;rsquo;re already three months into 2020 and it&amp;rsquo;s time for a quick
retrospective on my &lt;a href="https://caffeinatedideas.com/2020/01/15/my-2020-tech-radar.html"&gt;2020 Tech Radar goals&lt;/a&gt;.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Exploring: &lt;a href="https://lamport.azurewebsites.net/tla/tla.html"&gt;TLA+&lt;/a&gt; &lt;br/&gt;
No significant progress to update on this. I&amp;rsquo;ve read through the first chapter of
&lt;a href="https://www.apress.com/gp/book/9781484238288"&gt;Practical TLA+&lt;/a&gt; but didn&amp;rsquo;t go beyond that.
&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Deep Dive: &lt;a href="https://www.rust-lang.org/"&gt;Rust&lt;/a&gt; &lt;br/&gt;
Started reading &lt;a href="https://nostarch.com/Rust2018"&gt;The Rust Programming Language&lt;/a&gt; book. I&amp;rsquo;m two chapters
in and so far it&amp;rsquo;s still pretty standard language stuff.
&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Deep Dive: &lt;a href="https://reasonml.github.io/"&gt;Reason&lt;/a&gt; &lt;br/&gt;
No progress.
&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;</description></item><item><title>Exceptions Ruin Code Flow</title><link>https://caffeinatedideas.com/2020/02/19/exceptions-ruin-code-flow.html</link><pubDate>Wed, 19 Feb 2020 00:00:00 +0000</pubDate><guid>https://caffeinatedideas.com/2020/02/19/exceptions-ruin-code-flow.html</guid><description>&lt;p&gt;We often insist that anyone writing code understand and handle errors using exceptions. By their definition, exceptions
force you to break your thought process on the present line of code and require that you immediately start to think about
how to handle the error condition. In some cases, like named exceptions in Java, there is no agency. You must either deal with
the exception or just declare it as a possible error to your code, pushing the concern to some other place in the code.&lt;/p&gt;</description></item><item><title>My 2020 Tech Radar</title><link>https://caffeinatedideas.com/2020/01/15/my-2020-tech-radar.html</link><pubDate>Wed, 15 Jan 2020 00:00:00 +0000</pubDate><guid>https://caffeinatedideas.com/2020/01/15/my-2020-tech-radar.html</guid><description>&lt;p&gt;Every year, I like to set goals for myself to help me focus on new things that I want to learn or adopt throughout
the year. I typically model my goals on a layout similar to the &lt;a href="https://www.thoughtworks.com/radar"&gt;ThoughWorks Radar&lt;/a&gt; that
is published every quarter. The three main categories that I&amp;rsquo;ve used in my tech radar are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Exploring &lt;br/&gt;
Topics listed in the &lt;em&gt;&amp;ldquo;exploring&amp;rdquo;&lt;/em&gt; section are items that I&amp;rsquo;ve run into either in conference talks or papers
and want to know more about them. This is usually limited to either reading a book, paper or watching conference
talks on the topic. Cursory knowledge is the goal with these topics.
&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;</description></item><item><title>Migrating to Clojure Deps</title><link>https://caffeinatedideas.com/2019/12/26/migrating-to-clojure-deps.html</link><pubDate>Thu, 26 Dec 2019 00:00:00 +0000</pubDate><guid>https://caffeinatedideas.com/2019/12/26/migrating-to-clojure-deps.html</guid><description>&lt;p&gt;Over the last couple of months, I&amp;rsquo;ve worked on migrating my static site generator code from &lt;a href="https://boot-clj.com/"&gt;boot&lt;/a&gt; to
Clojure&amp;rsquo;s new &lt;a href="https://clojure.org/reference/deps_and_cli"&gt;deps&lt;/a&gt; tooling. &lt;a href="https://clojure.org/reference/deps_and_cli"&gt;Deps&lt;/a&gt; is fairly minimal in what it provides and that turns out to be
exactly what I need.&lt;/p&gt;
&lt;h2 id="background"&gt;Background&lt;/h2&gt;
&lt;p&gt;Back in 2017, I outlined my motivation for &lt;a href="https://caffeinatedideas.com/2017/08/25/building-my-own-static-site-generator.html"&gt;building my own static site generator&lt;/a&gt;. At
the time, I selected &lt;a href="https://boot-clj.com/"&gt;boot&lt;/a&gt; as the platform to build off of. &lt;a href="https://boot-clj.com/"&gt;Boot&lt;/a&gt; abstracted a lot of
concepts common to build systems and had a large plugin ecosystem that I would leverage for various aspects - like
syncing files to AWS S3. This allowed me to focus my efforts on getting the representation of the site content
correct and building out the core functionality.&lt;/p&gt;</description></item><item><title>Code Needs Maintenance</title><link>https://caffeinatedideas.com/2019/08/05/code-needs-maintenance.html</link><pubDate>Mon, 05 Aug 2019 00:00:00 +0000</pubDate><guid>https://caffeinatedideas.com/2019/08/05/code-needs-maintenance.html</guid><description>&lt;p&gt;This weekend I had to replace the top deck boards on the steps leading to
our front porch. The work seemed easy enough - buy some wood, rough cut to
length, unscrew the old boards and screw in the new boards. It&amp;rsquo;s only eight
steps so it shouldn&amp;rsquo;t take more than a day if I&amp;rsquo;m slow. After spending a
whole day on the project, I only managed to replace three out of the eight
steps.&lt;/p&gt;</description></item><item><title>Building a Clojure to Jython Interop</title><link>https://caffeinatedideas.com/2019/07/16/building-clojure-jython-interop.html</link><pubDate>Tue, 16 Jul 2019 00:00:00 +0000</pubDate><guid>https://caffeinatedideas.com/2019/07/16/building-clojure-jython-interop.html</guid><description>&lt;p&gt;For the last four years, I&amp;rsquo;ve been working at Datastax on the &lt;a href="https://www.datastax.com/products/datastax-opscenter"&gt;OpsCenter&lt;/a&gt; product team. &lt;a href="https://www.datastax.com/products/datastax-opscenter"&gt;OpsCenter&lt;/a&gt;
itself was originally built with &lt;a href="https://twistedmatrix.com"&gt;Twisted&lt;/a&gt; on python and leveraged small agents, written in Clojure, to interact
with every Cassandra node instance. Shortly after I started, the core team decided to port the python component to
&lt;a href="https://www.jython.org/"&gt;Jython&lt;/a&gt;, a JVM based Python implementation. This isn&amp;rsquo;t a secret or propitiatory information since our
architect, &lt;a href="https://twitter.com/nickmbailey"&gt;Nick Bailey&lt;/a&gt;,
gave a talk at Clojure/conj 2016 about our efforts.&lt;/p&gt;</description></item><item><title>Problems with flatten on Java types</title><link>https://caffeinatedideas.com/2019/01/23/clojure-data-structure-interop.html</link><pubDate>Wed, 23 Jan 2019 00:00:00 +0000</pubDate><guid>https://caffeinatedideas.com/2019/01/23/clojure-data-structure-interop.html</guid><description>&lt;h2 id="the-bug"&gt;The bug&lt;/h2&gt;
&lt;p&gt;Our automated functional tests caught an exception in a block of functionality that needs to read a sequence of strings
from a deeply nested &lt;a href="https://yaml.org/"&gt;YAML&lt;/a&gt; file structure.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-clojure" data-lang="clojure"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;(&lt;span style="color:#66d9ef"&gt;defn &lt;/span&gt;load-yaml-contents
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; []
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;;; This is a mocked set of data from parsing the YAML file.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; (map identity [[&lt;span style="color:#e6db74"&gt;&amp;#34;one&amp;#34;&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;two&amp;#34;&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;three&amp;#34;&lt;/span&gt;] [&lt;span style="color:#e6db74"&gt;&amp;#34;four&amp;#34;&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;five&amp;#34;&lt;/span&gt;]]))
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;(-&amp;gt; (&lt;span style="color:#a6e22e"&gt;load-yaml-contents&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; flatten
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; (reduce concat []))
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;=&amp;gt; (&lt;span style="color:#e6db74"&gt;\o&lt;/span&gt; &lt;span style="color:#e6db74"&gt;\n&lt;/span&gt; &lt;span style="color:#e6db74"&gt;\e&lt;/span&gt; &lt;span style="color:#e6db74"&gt;\t&lt;/span&gt; &lt;span style="color:#e6db74"&gt;\w&lt;/span&gt; &lt;span style="color:#e6db74"&gt;\o&lt;/span&gt; &lt;span style="color:#e6db74"&gt;\t&lt;/span&gt; &lt;span style="color:#e6db74"&gt;\h&lt;/span&gt; &lt;span style="color:#e6db74"&gt;\r&lt;/span&gt; &lt;span style="color:#e6db74"&gt;\e&lt;/span&gt; &lt;span style="color:#e6db74"&gt;\e&lt;/span&gt; &lt;span style="color:#e6db74"&gt;\f&lt;/span&gt; &lt;span style="color:#e6db74"&gt;\o&lt;/span&gt; &lt;span style="color:#e6db74"&gt;\u&lt;/span&gt; &lt;span style="color:#e6db74"&gt;\r&lt;/span&gt; &lt;span style="color:#e6db74"&gt;\f&lt;/span&gt; &lt;span style="color:#e6db74"&gt;\i&lt;/span&gt; &lt;span style="color:#e6db74"&gt;\v&lt;/span&gt; &lt;span style="color:#e6db74"&gt;\e&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;After &lt;a href="https://clojuredocs.org/clojure.core/flatten"&gt;&lt;code&gt;flatten&lt;/code&gt;&lt;/a&gt; we would have a list of strings but then when that sequence is reduced using &lt;a href="https://clojuredocs.org/clojure.core/concat"&gt;&lt;code&gt;concat&lt;/code&gt;&lt;/a&gt;,
each string value is treated as a sequence of characters and each character is appended to the vector. This is not the result
that we want. I then had to question if this code ever worked. There was a unit test around this behavior that asserted the
result of this code produced a sequence of strings. This unit test was last touched when the code shipped and has been running
successfully in nightly builds. I was perplexed as to why the test passed but the code failed in an end to end test.&lt;/p&gt;</description></item><item><title>Why Learn a Lisp</title><link>https://caffeinatedideas.com/2017/12/22/why-learn-a-lisp.html</link><pubDate>Fri, 22 Dec 2017 00:00:00 +0000</pubDate><guid>https://caffeinatedideas.com/2017/12/22/why-learn-a-lisp.html</guid><description>&lt;p&gt;I&amp;rsquo;ve been fortunate enough since April 2015 to work in a position where I was
expected to write and support Clojure code as one of my primary responsibilities.
Over that time, Clojure has changed me as a programmer. It wasn&amp;rsquo;t until I listened
to &lt;a href="https://www.functionalgeekery.com/episode-68-matthew-butterick/#t=30:12"&gt;episode 68&lt;/a&gt; of the &lt;a href="https://.functionalgeekery.com"&gt;Functional Geekery podcast&lt;/a&gt; that I really
reflected on how learning a lisp language has changed me.&lt;/p&gt;
&lt;p&gt;Many people who work with a lisp language tend to speak of this transcending experience
and enlightenment that comes with learning a lisp. After hearing these kinds of vague
experience reports and all sorts of success stories with Clojure, I was determined to
become a Clojure developer. I pushed Clojure at QThru, tried to introduce it at Medio
and even selected Clojure as a key technology at jetway.io. Through all of this, I
couldn&amp;rsquo;t tell you an exact reason other than elegance and beauty - neither of which solved
a business problem for me.&lt;/p&gt;</description></item><item><title>What herd behavior can teach us about how we estimate work</title><link>https://caffeinatedideas.com/2017/12/15/herd-behavior-and-estimating.html</link><pubDate>Fri, 15 Dec 2017 00:00:00 +0000</pubDate><guid>https://caffeinatedideas.com/2017/12/15/herd-behavior-and-estimating.html</guid><description>&lt;p&gt;This year I managed to finally read Nate Silver&amp;rsquo;s book &lt;a href="https://www.amazon.com/Signal-Noise-Many-Predictions-Fail-but/dp/0143125087/ref=sr_1_1?ie=UTF8&amp;amp;qid=1513356807&amp;amp;sr=8-1&amp;amp;keywords=the+signal+and+the+noise+nate+silver"&gt;&amp;ldquo;The Signal and the Noise: Why So Many Predictions Fail &amp;ndash; but Some Don&amp;rsquo;t&amp;rdquo;&lt;/a&gt;.
The concepts in the book will feel similar to any developer who&amp;rsquo;s read up on or attended
any agile session on estimating. In Chapter 11, Silver turns to looking at stock
markets and why the modern market behavior has changed when compared to the market
behavior of the past.&lt;/p&gt;</description></item><item><title>Rebooting QThru</title><link>https://caffeinatedideas.com/2017/11/28/rebooting-qthru.html</link><pubDate>Tue, 28 Nov 2017 00:00:00 +0000</pubDate><guid>https://caffeinatedideas.com/2017/11/28/rebooting-qthru.html</guid><description>&lt;blockquote&gt;
&lt;p&gt;“Our greatest weakness lies in giving up. The most certain way to succeed is always to try just one more time.”&lt;/p&gt;
&lt;p&gt;&amp;ndash; Thomas Edison&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Shortly after Aaron informed everyone on July 8th, 2013 that QThru was out of money,
I met with one of my coworkers. We talked a lot about projects that were just left
unfinished and the potential we saw in the product. The most interesting question was
whether I would return to QThru if Aaron was removed and a new CEO was put in place.
In fact, a new CEO with experience selling into retail markets was just what QThru
needed as Aaron was unable to book any deals since we got funding. With that single
answer, I started helping produce a plan to adjust course with QThru assuming that the
company could be taken over.&lt;/p&gt;</description></item><item><title>Benchmarking Clojure Performance with a byte counting InputStream</title><link>https://caffeinatedideas.com/2017/10/25/benchmarking-clojure-perf.html</link><pubDate>Wed, 25 Oct 2017 00:00:00 +0000</pubDate><guid>https://caffeinatedideas.com/2017/10/25/benchmarking-clojure-perf.html</guid><description>&lt;p&gt;OpsCenter&amp;rsquo;s goal is to deliver operational simplicity around deploying
and managing a DSE (e.g. Cassandra) cluster. One core feature
of this offering is backup and restore functionality that snapshots the
individual nodes and then copies that data to either AWS S3 or a local
file system mount. The component that performs this task, the DataStax agent,
simply views all the data as Java streams instead of individual files on
the disk.&lt;/p&gt;</description></item><item><title>Modeling Sales Tax Rates</title><link>https://caffeinatedideas.com/2017/09/23/modeling-sales-tax-rates.html</link><pubDate>Sat, 23 Sep 2017 00:00:00 +0000</pubDate><guid>https://caffeinatedideas.com/2017/09/23/modeling-sales-tax-rates.html</guid><description>&lt;blockquote&gt;
&lt;p&gt;&amp;ldquo;The hardest thing in the world to understand is the income tax.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;&amp;ndash; Albert Einstein&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Consumers don&amp;rsquo;t often think about the legal requirement that a &lt;a href="https://en.wikipedia.org/wiki/Sales_tax"&gt;sales tax&lt;/a&gt;
must be paid by them for items they purchased based on where the transaction took place.
Retailers with physical locations very often collect and submit that tax on behalf of the
consumer to make the transaction easier. This means that any point of sale needs to have
support built in to compute and add the sales tax on to the cart.&lt;/p&gt;</description></item><item><title>QThru: Data Model</title><link>https://caffeinatedideas.com/2017/09/22/qthru-data-model.html</link><pubDate>Fri, 22 Sep 2017 00:00:00 +0000</pubDate><guid>https://caffeinatedideas.com/2017/09/22/qthru-data-model.html</guid><description>&lt;blockquote&gt;
&lt;p&gt;&amp;ldquo;Data is a precious thing and will last longer than the systems themselves.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;– Tim Berners-Lee&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The mobile platform we developed at QThru started as a simple mobile application
with a ReST API to perform CRUD operations. The types of data that we stored was
one of the more valuable assets that our platform was generating. Over the 2 years
of operation, the data model was transformed and enriched as we better understood
the domain. In this post, I&amp;rsquo;m going to point out some of the decisions we made
about our data model and whether they were helpful or not.&lt;/p&gt;</description></item><item><title>Building My Own Static Site Generator</title><link>https://caffeinatedideas.com/2017/08/25/building-my-own-static-site-generator.html</link><pubDate>Fri, 25 Aug 2017 00:00:00 +0000</pubDate><guid>https://caffeinatedideas.com/2017/08/25/building-my-own-static-site-generator.html</guid><description>&lt;p&gt;I&amp;rsquo;ve been pretty quiet on this blog for the last year as I worked on my own static site generator.
This wasn&amp;rsquo;t my original intention I wouldn&amp;rsquo;t recommend building from scratch for people who just
want to publish content. This story starts back in 2015 when my site was built using
&lt;a href="https://jekyllrb.com/"&gt;jekyll&lt;/a&gt; and hosted on S3.&lt;/p&gt;
&lt;h2 id="toward-a-clojure-solution"&gt;Toward a Clojure solution&lt;/h2&gt;
&lt;p&gt;Sometime around 2012 or 2013, I started learning more about static site hosting using AWS S3. The cost
would be pennies compared to the $10/mo I was paying for hosting a WordPress blog. That was a significant
savings for a site that I assume gets very little traffic. I started the process of exporting the old posts
from WordPress and building out a site with &lt;a href="https://jekyllrb.com/"&gt;jekyll&lt;/a&gt;, the most popular static site generator
at the time. I was a happy &lt;a href="https://jekyllrb.com/"&gt;jekyll&lt;/a&gt; user until I read &lt;a href="https://pragprog.com/book/tpp/the-pragmatic-programmer"&gt;The Pragmatic Programmer&lt;/a&gt;.&lt;/p&gt;</description></item><item><title>The Five W's of Engineering Leadership</title><link>https://caffeinatedideas.com/2017/08/09/five-ws-engineering-leadership.html</link><pubDate>Wed, 09 Aug 2017 00:00:00 +0000</pubDate><guid>https://caffeinatedideas.com/2017/08/09/five-ws-engineering-leadership.html</guid><description>&lt;p&gt;In the last couple of months, I&amp;rsquo;ve had some interesting conversations with my employer
about my career. Frankly, I&amp;rsquo;m not sure what I want to do next. One thing that has come
out of these conversations is a simple abstraction I&amp;rsquo;ve used to think about different
positions and what they do. I&amp;rsquo;ve based it on the &lt;a href="https://en.wikipedia.org/wiki/Five_Ws"&gt;Five W&amp;rsquo;s&lt;/a&gt;.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Who (individual assignments) - Team Lead&lt;/li&gt;
&lt;li&gt;What - Product Management&lt;/li&gt;
&lt;li&gt;When - Project Management&lt;/li&gt;
&lt;li&gt;Where (which team) - Engineering Manager&lt;/li&gt;
&lt;li&gt;Why - CTO&lt;/li&gt;
&lt;li&gt;How - Architect, Tech Lead&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;There are plenty of corner cases but at least having some high level abstraction has
given me some guidance.&lt;/p&gt;</description></item><item><title>QThru: Warp Pipe POS Integration</title><link>https://caffeinatedideas.com/2016/08/19/qthru-warp-pipe-pos-integration.html</link><pubDate>Fri, 19 Aug 2016 00:00:00 +0000</pubDate><guid>https://caffeinatedideas.com/2016/08/19/qthru-warp-pipe-pos-integration.html</guid><description>&lt;blockquote&gt;
&lt;p&gt;A lot of the Google inventions came from engineers just screwing around with
ideas. And then management would see them, and we&amp;rsquo;d say, &amp;lsquo;Boy, that&amp;rsquo;s
interesting. Let&amp;rsquo;s add some more engineers.&amp;rsquo;&lt;/p&gt;
&lt;p&gt;-Eric Schmidt&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;One of the largest challenges the engineering team faced at QThru was the initial
setup with a retail location. Our proof of concept code required a CSV file
with product and pricing data that we would then import into our database.
We thought that the CSV format would be consistent between point of sale (POS)
systems and that we could just use a copy of that data file. This was not true.
We also assumed that the pricing managers and staff at the grocery stores would
comfortable setting up the import program. This was also not true.&lt;/p&gt;</description></item><item><title>QThru: The Platform Architecture</title><link>https://caffeinatedideas.com/2016/06/28/qthru-platform-architecture.html</link><pubDate>Tue, 28 Jun 2016 00:00:00 +0000</pubDate><guid>https://caffeinatedideas.com/2016/06/28/qthru-platform-architecture.html</guid><description>&lt;blockquote&gt;
&lt;p&gt;Good judgment comes from experience, and experience comes from bad judgment.&lt;/p&gt;
&lt;p&gt;&amp;ndash; Frederick P. Brooks&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Now that the NDAs have expired and QThru has officially folded, I think it&amp;rsquo;s
important to publish what we learned from building a mobile commerce company
by a set of engineers that only had experience in the email and message space.
What we designed had some good parts but also some failures.&lt;/p&gt;
&lt;div class="highlight-box"&gt;
&lt;p&gt;This is the third in a series of retrospective thoughts on QThru, a mobile
self checkout startup that went bust. See my
&amp;ldquo;&lt;a href="https://caffeinatedideas.com/2016/06/03/the-qthru-series.html"&gt;QThru Series&lt;/a&gt;&amp;rdquo; post for a list of all the
topics.&lt;/p&gt;</description></item><item><title>QThru: The Business Model</title><link>https://caffeinatedideas.com/2016/06/16/qthru-business-model.html</link><pubDate>Thu, 16 Jun 2016 00:00:00 +0000</pubDate><guid>https://caffeinatedideas.com/2016/06/16/qthru-business-model.html</guid><description>&lt;blockquote&gt;
&lt;p&gt;I&amp;rsquo;m talking about liquid. Rich enough to have your own jet. Rich enough not to
waste time. Fifty, a hundred million dollars, buddy. A player. Or nothing.&lt;/p&gt;
&lt;p&gt;&amp;ndash; Gordon Gekko&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class="highlight-box"&gt;
&lt;p&gt;This is the second in a series of retrospective thoughts on QThru, a mobile
self checkout startup that went bust. See my
&amp;ldquo;&lt;a href="https://caffeinatedideas.com/2016/06/03/the-qthru-series.html"&gt;QThru Series&lt;/a&gt;&amp;rdquo; post for a list of all the
topics.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;In 2009, the smartphone app market was on fire. Apple&amp;rsquo;s decision to release a
native app SDK that developers actually wanted to use unleashed the creativity
of the world and new businesses started to emerge. In particular, startups
were looking at how an Internet connected computer could be used to process
payments. In February that year, Square launched their mobile payment platform
for iOS.&lt;/p&gt;</description></item><item><title>The QThru Series</title><link>https://caffeinatedideas.com/2016/06/03/the-qthru-series.html</link><pubDate>Fri, 03 Jun 2016 00:00:00 +0000</pubDate><guid>https://caffeinatedideas.com/2016/06/03/the-qthru-series.html</guid><description>&lt;blockquote&gt;
&lt;p&gt;One who fears failure limits his activities. Failure is only the opportunity
to more intelligently begin again.&lt;/p&gt;
&lt;p&gt;– Henry Ford&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In April 2012, I ended up meeting with Aaron Roberts for lunch. I had just left
BlackBerry for another position that didn&amp;rsquo;t quite live up to my expectations.
A few days prior, Aaron and I talked about a startup he was building called
QThru. Before we got too far into lunch, I flat out asked him if he had room
for another developer and we talked about how to proceed. After a quick meeting
with the existing dev team, I walked away from a paying job with benefits to
become the first, and currently unpaid, full time employee for QThru.&lt;/p&gt;</description></item><item><title>Another argument for s-expressions</title><link>https://caffeinatedideas.com/2015/10/22/the-argument-for-s-expressions.html</link><pubDate>Thu, 22 Oct 2015 00:00:00 +0000</pubDate><guid>https://caffeinatedideas.com/2015/10/22/the-argument-for-s-expressions.html</guid><description>&lt;p&gt;I found myself back in our Python code base today working with a set of nested
dictionary objects. As I set out to look for the equivalent of Clojure&amp;rsquo;s &lt;code&gt;get-in&lt;/code&gt;
function, I ended up at a &lt;a href="http://stackoverflow.com/a/14484711/67927"&gt;nifty solution using reduce&lt;/a&gt;. Inspired,
I ended up with the following function in our Util module:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;get_in&lt;/span&gt;(d, keys, notfound&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;None&lt;/span&gt;):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&amp;#34;Python implementation of Clojure&amp;#39;s get-in function.&amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;try&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; reduce(dict&lt;span style="color:#f92672"&gt;.&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;__getitem__&lt;/span&gt;, keys, d)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;except&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;TypeError&lt;/span&gt;, exceptions&lt;span style="color:#f92672"&gt;.&lt;/span&gt;KeyError:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; notfound
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Of course this failed the unit test that I wrote:&lt;/p&gt;</description></item><item><title>stat command</title><link>https://caffeinatedideas.com/2015/09/01/stat-command.html</link><pubDate>Tue, 01 Sep 2015 00:00:00 +0000</pubDate><guid>https://caffeinatedideas.com/2015/09/01/stat-command.html</guid><description>&lt;p&gt;I was working on a shell script today that required determining the user that
owned a particular directory. A quick search online led me to
&lt;a href="http://stackoverflow.com/questions/7331651/find-the-owner-of-a-file-in-unix"&gt;this&lt;/a&gt;
Stack Overflow post. This led me to the following quick command that I could use in
a script&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;CASSANDRA_USER&lt;span style="color:#f92672"&gt;=&lt;/span&gt;ls -l /var/lib | grep cassandra | awk &lt;span style="color:#e6db74"&gt;&amp;#39;{print $3}&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;USER&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;${&lt;/span&gt;CASSANDRA_USER|-&lt;span style="color:#e6db74"&gt;&amp;#34;cassandra&amp;#34;&lt;/span&gt;&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The second line sets the var USER to either the value in CASSANDRA_USER or to the
default string &amp;ldquo;cassandra&amp;rdquo; if the previous command did not result in a value. The
grep was the weak point and it actually started to fail when another component
added a directory to /var/lib that was owned by a user named cassandra.&lt;/p&gt;</description></item><item><title>Podcasts About Development</title><link>https://caffeinatedideas.com/2015/08/17/podcasts-about-development.html</link><pubDate>Mon, 17 Aug 2015 00:00:00 +0000</pubDate><guid>https://caffeinatedideas.com/2015/08/17/podcasts-about-development.html</guid><description>&lt;p&gt;When I used to commute to the office in Seattle, I would listen to a number of
development related podcasts. They were a great way to get exposed to new
trends as well as wake up my brain before getting to the office. This is a list
of a few of my favorite podcasts that have withstood the test of time. Let&amp;rsquo;s jump
right into the list.&lt;/p&gt;
&lt;h5 id="the-cognicast"&gt;&lt;a href="http://blog.cognitect.com/cognicast/"&gt;The Cognicast&lt;/a&gt;&lt;/h5&gt;
&lt;p&gt;Primarily focused on Clojure and ClojureScript development, this podcast always
seems to come up with interesting topics to talk about. Previous shows have
included deep dives into Om, property based testing, writing code without a
type system, data structures, dyslexia and more. It&amp;rsquo;s roughly an hour long, has
a consistent release schedule and a wide range of guests.&lt;/p&gt;</description></item><item><title>Why You Need Macros</title><link>https://caffeinatedideas.com/2015/08/06/why-you-need-macros.html</link><pubDate>Thu, 06 Aug 2015 00:00:00 +0000</pubDate><guid>https://caffeinatedideas.com/2015/08/06/why-you-need-macros.html</guid><description>&lt;p&gt;In 2013, I started looking into a
&lt;a href="http://elixir-lang.org/"&gt;Elixir&lt;/a&gt;, a new language that
looks like Ruby and runs on
&lt;a href="https://en.wikipedia.org/wiki/BEAM_(Erlang_virtual_machine)"&gt;BEAM&lt;/a&gt;. One of the more interesting
parts of the language is the early development of the
[macro](&lt;a href="https://en.wikipedia.org/wiki/Macro_(computer_science)"&gt;https://en.wikipedia.org/wiki/Macro_(computer_science)&lt;/a&gt; system,
an idea borrowed from Lisp. With macros, the Elixir developers were able to
iterate and provide a wide array of control structures without the need to bloat
the core language.&lt;/p&gt;
&lt;p&gt;While many developers look at macros as things to avoid, they are essential in
building languages today. Without macros, a language needs to produce a big
design first in order to ensure that the new feature fits within the large
language ecosystem. C# and Java are prime examples of slowly evolving features
that need to be blessed before they can be used. This leads to long release
cycles where the cost of failure is high. Yet, the Clojure community was able to
introduce &lt;a href="https://github.com/clojure/core.async"&gt;core.async&lt;/a&gt; without requiring any
impact to the core language library. At the heart of
&lt;a href="https://github.com/clojure/core.async"&gt;core.async&lt;/a&gt; is a
&lt;a href="http://hueypetersen.com/posts/2013/08/02/the-state-machines-of-core-async/"&gt;complex state machine&lt;/a&gt;
abstracted through a series of macros.&lt;/p&gt;</description></item><item><title>Great developers build tools</title><link>https://caffeinatedideas.com/2015/04/03/great-developers-build-tools.html</link><pubDate>Fri, 03 Apr 2015 00:00:00 +0000</pubDate><guid>https://caffeinatedideas.com/2015/04/03/great-developers-build-tools.html</guid><description>&lt;blockquote&gt;
&lt;p&gt;It was important, his father said, to craft the backs of cabinets and
fences properly, even though they were hidden. &amp;ldquo;He loved doing things right.
He even cared about the look of the parts you couldn&amp;rsquo;t see.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;&amp;ndash; Walter Isaacson. &amp;ldquo;Steve Jobs.&amp;rdquo; iBooks. &lt;a href="https://itun.es/us/QyFUz.l"&gt;https://itun.es/us/QyFUz.l&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Today I had to investigate a ticket that failed the end to end verification step.
The comment in the ticket contained a good amount of details about the environment
that the test was run in, what was performed and a little bit about the failure.
It was more details than a customer would provide but didn&amp;rsquo;t include log files,
memory dumps or live debugging.&lt;/p&gt;</description></item><item><title>Superfish Highlights the SSL Problem</title><link>https://caffeinatedideas.com/2015/03/06/superfish-highlights-the-ssl-problem.html</link><pubDate>Fri, 06 Mar 2015 00:00:00 +0000</pubDate><guid>https://caffeinatedideas.com/2015/03/06/superfish-highlights-the-ssl-problem.html</guid><description>&lt;p&gt;It&amp;rsquo;s only been two weeks since
&lt;a href="http://arstechnica.com/security/2015/02/lenovo-pcs-ship-with-man-in-the-middle-adware-that-breaks-https-connections/"&gt;news of Lenovo bundling Superfish on their laptops&lt;/a&gt;
was brought to the public&amp;rsquo;s attention. While the focus has been on who at Lenovo knew about the bundle,
few people are really talking about what it means to the security of the Internet. Developers used to just
enable SSL on their services to check off their security requirements. Developers now need to think
more about security and should pay attention to the new research underway.&lt;/p&gt;</description></item><item><title>Is node.js turning into the new Java?</title><link>https://caffeinatedideas.com/2015/02/18/is-nodejs-turning-into-the-new-java.html</link><pubDate>Wed, 18 Feb 2015 00:00:00 +0000</pubDate><guid>https://caffeinatedideas.com/2015/02/18/is-nodejs-turning-into-the-new-java.html</guid><description>&lt;p&gt;It&amp;rsquo;s been quite a ride for for node.js. A group of core developers secured a
&lt;a href="http://venturebeat.com/2014/02/11/former-node-leader-takes-big-money-launches-node-startup/"&gt;nice series A round to start npm, Inc.&lt;/a&gt;,
bringing a corporate steward to the growing repository site. Success stories on node.js in
&lt;a href="https://engineering.groupon.com/2013/node-js/geekon-i-tier/"&gt;various&lt;/a&gt;
companies &lt;a href="http://techblog.netflix.com/2014/08/scaling-ab-testing-on-netflixcom-with_18.html"&gt;seem&lt;/a&gt;
common place with new stories weekly. Recently,
&lt;a href="http://techcrunch.com/2015/02/09/nodesource-raises-3-million-to-build-new-programming-tools/"&gt;NodeSource closed their series A round&lt;/a&gt;
to bring node.js to enterprise customers. All this excitement for node.js and JavaScript was succinctly summed up in 140 characters:&lt;/p&gt;
&lt;blockquote class="twitter-tweet" data-cards="hidden" lang="en"&gt;&lt;p&gt;Brendan Eich: JavaScript&amp;#39;s destiny is to fulfill Java&amp;#39;s promise &lt;a href="http://t.co/KFM59kIz20"&gt;http://t.co/KFM59kIz20&lt;/a&gt;&lt;/p&gt;</description></item><item><title>Java 'synchronized' in Python</title><link>https://caffeinatedideas.com/2014/12/12/java-synchronized-in-python.html</link><pubDate>Fri, 12 Dec 2014 00:00:00 +0000</pubDate><guid>https://caffeinatedideas.com/2014/12/12/java-synchronized-in-python.html</guid><description>&lt;p&gt;A recent student posed the question, &amp;ldquo;Is there a way to lock execution of an entire
method in Python using Lock instead of writing out a with-block?&amp;rdquo; My answer
started with all the good reasons why we wouldn&amp;rsquo;t want to hide the locking behavior
in magic, why adding it to all methods on all objects in python would be bad for
performance and testing and then to argue that the current syntax based on the with
keyword isn&amp;rsquo;t that painful. Then I tried to see if I could replicate the problem
using some python magic.&lt;/p&gt;</description></item><item><title>How Certain Are You?</title><link>https://caffeinatedideas.com/2014/10/03/how-certain-are-you.html</link><pubDate>Fri, 03 Oct 2014 00:00:00 +0000</pubDate><guid>https://caffeinatedideas.com/2014/10/03/how-certain-are-you.html</guid><description>&lt;p&gt;At some point in our lives, we&amp;rsquo;re given this misconception that with effort and training we can have
some level of certainty about the future. On a small enough scale with very fixed boundaries, I suppose
that&amp;rsquo;s true - it&amp;rsquo;s probably pretty certain that I&amp;rsquo;ll take another breathe of air. Even then there is
still a small level of uncertainty that I won&amp;rsquo;t and the outcome of that action will make for a pretty
wild day. The harsh reality is that nothing in life is certain.&lt;/p&gt;</description></item><item><title>Breaking Statically Typed Languages</title><link>https://caffeinatedideas.com/2014/08/14/breaking-statically-typed-languages.html</link><pubDate>Thu, 14 Aug 2014 00:00:00 +0000</pubDate><guid>https://caffeinatedideas.com/2014/08/14/breaking-statically-typed-languages.html</guid><description>&lt;p&gt;Every time I tell my fellow Java developers that I enjoy writing code in python or node.js or clojure,
I&amp;rsquo;m very often dismissed with a set of reasons but the one I always enjoy is:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Java is statically typed so the compiler checks to make sure I don&amp;rsquo;t make mistakes.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Yet many Java developers don&amp;rsquo;t use the type system.&lt;/p&gt;
&lt;p&gt;Well, they really do use the type system but just as a way of declaring that everything in the system is
some built in type - typically integers, strings or booleans.&lt;/p&gt;</description></item><item><title>JavaScript Dependency Injection Pattern</title><link>https://caffeinatedideas.com/2014/02/17/javascript-dependency-injection-pattern.html</link><pubDate>Mon, 17 Feb 2014 00:00:00 +0000</pubDate><guid>https://caffeinatedideas.com/2014/02/17/javascript-dependency-injection-pattern.html</guid><description>&lt;p&gt;Over the course of the last month, I&amp;rsquo;ve been working on rebuilding a JavaScript SDK
for my employer. Once of the requirements was that all of the code needs to ship with
an automated test suite that capable of testing a majority of the basic functionality.
Throughout the process, I&amp;rsquo;ve relied a lot on dependency injection in order to provide
hooks to mock or stub out functionality in a fairly straight forward manner.&lt;/p&gt;</description></item><item><title>TIL Culture Matters</title><link>https://caffeinatedideas.com/2014/01/13/til-culture-matters.html</link><pubDate>Mon, 13 Jan 2014 00:00:00 +0000</pubDate><guid>https://caffeinatedideas.com/2014/01/13/til-culture-matters.html</guid><description>&lt;p&gt;For me, 2013 was a year of many lessons learned out of the unfortunate bankruptcy
of QThru. It just seemed right to document all of the things I&amp;rsquo;ve learned through
the process. This is the first post in my TIL (things I learned) series, focusing
on things that engineers don&amp;rsquo;t think about while working at a startup company. The
first lesson is that culture really does matter.&lt;/p&gt;
&lt;p&gt;If you&amp;rsquo;re an engineer at heart and you spend your time building things, you are
probably inclined to zone out when people start talking about mission statements,
values, review process and org charts - the culture. In fact, one of the appealing
upshots of working at a startup is that the management team is thin and isn&amp;rsquo;t
shoving these concepts down your throat at monthly or quarterly meetings. At first,
it can seem like a breathe of fresh air that lets you get down to the business of
building the product.&lt;/p&gt;</description></item><item><title>Taming node.js with Clojurescript</title><link>https://caffeinatedideas.com/2013/08/29/taming-nodejs-with-clojurescript.html</link><pubDate>Thu, 29 Aug 2013 00:00:00 +0000</pubDate><guid>https://caffeinatedideas.com/2013/08/29/taming-nodejs-with-clojurescript.html</guid><description>&lt;p&gt;In my previous post, I outlined a new, lighter weight approach
to building web applications using Clojurescript and node.js as the
runtime environment for the backend. The nice part of Clojurescript is that
it doesn&amp;rsquo;t try to abstract away the host environment so all those useful
node.js packages can be reused without the need to wait for someone to rewrite
them in Clojurescript.&lt;/p&gt;
&lt;p&gt;To start, we need to pick a framework for our web development. My personal
preference is &lt;a href="http://mcavage.me/node-restify/"&gt;restify&lt;/a&gt; since it comes out of
the box with support
for API versioning, a static file server and handles a fair number of ReST conventions
without any configuration. The only thing that it lacks is built in support for
a page templating library, but this isn&amp;rsquo;t important for our application. All of
the pages in our app will be static HTML files and we&amp;rsquo;ll use client side
Clojurescript to load data and respond to the user actions.&lt;/p&gt;</description></item><item><title>Webapps with Clojurescript</title><link>https://caffeinatedideas.com/2013/08/15/webapps-with-clojurescript.html</link><pubDate>Thu, 15 Aug 2013 00:00:00 +0000</pubDate><guid>https://caffeinatedideas.com/2013/08/15/webapps-with-clojurescript.html</guid><description>&lt;p&gt;In the late 90s and early 2000s, Java and C# sparked a fundamental change in
how software is developed. With the introduction of fast garbage collection and
VMs executing bytecode, developers stopped worrying about mundane issues and
were free to tackle much more complex problems. This has lead to large system
components like hadoop, cassandra and solr, which give the world a huge base to
build the future on. Yet, software development now has new problems in terms of
concurrency and correctness that Java and C# fail to provide ideal solutions to.&lt;/p&gt;</description></item><item><title>Smarter Architectures with NoSQL</title><link>https://caffeinatedideas.com/2013/06/16/smarter-architectures-with-nosql.html</link><pubDate>Sun, 16 Jun 2013 00:00:00 +0000</pubDate><guid>https://caffeinatedideas.com/2013/06/16/smarter-architectures-with-nosql.html</guid><description>&lt;p&gt;The pace of software development and the demands for teams to produce features
has been steadily increasing. This increasing pace has driven the industry to
innovate how we create software, like automating our tests and deployments. Another
tools that can help development teams deliver features faster are NoSQL databases.&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s unfortunate that a lot of conference talks about NoSQL end up focusing on the
technical scalability of the products. Most shops aren&amp;rsquo;t going to need to worry about
building web scale solutions initially, and may never need to build to web scale
standards. This doesn&amp;rsquo;t mean that we should then write off NoSQL databases. In addition
to handling higher loads, many NoSQL databases already implement a lot of functionality
modern apps use.&lt;/p&gt;</description></item><item><title>Autowiring Akka Actors with Spring</title><link>https://caffeinatedideas.com/2013/02/18/autowiring-akka-actors-with-spring.html</link><pubDate>Mon, 18 Feb 2013 00:00:00 +0000</pubDate><guid>https://caffeinatedideas.com/2013/02/18/autowiring-akka-actors-with-spring.html</guid><description>&lt;p&gt;We consume a lot of data in various formats to deliver our mobile shopping
experience and we need to process these data feeds quickly so we can offer
up-to-date pricing and inventory within our application. This means that we need
to avoid blocking operations as much as possible during our calculations and run
multiple elements through our import process concurrently. Instead of rewriting
tons of basic threading code, I wanted to leverage Akka&amp;rsquo;s actor based model so we
could focus our code on the actual business logic of importing the data and less
on threading.&lt;/p&gt;</description></item><item><title>Hibernate Tips</title><link>https://caffeinatedideas.com/2012/12/12/hibernate-tips.html</link><pubDate>Wed, 12 Dec 2012 00:00:00 +0000</pubDate><guid>https://caffeinatedideas.com/2012/12/12/hibernate-tips.html</guid><description>&lt;p&gt;I&amp;rsquo;ve decided to assemble a list of some cool features I found in the last week
working with Hibernate. If you&amp;rsquo;re going to use an ORM, you might as well learn to
use it effectively.&lt;/p&gt;
&lt;h2 id="tip-1-scan-for-entity-classes"&gt;Tip 1: Scan for Entity Classes&lt;/h2&gt;
&lt;p&gt;If you&amp;rsquo;re using Spring ORM and Hibernate like we are at QThru, you&amp;rsquo;ve probably
started off with a session factory that listed each of the entity objects in the
application context XML file. To avoid repeating what you&amp;rsquo;ve already declared with
annotations, use the packagesToScan property to have Hibernate discover those entity
objects for you:&lt;/p&gt;</description></item><item><title>My Journey with Seven Languages</title><link>https://caffeinatedideas.com/2012/09/17/my-journey-with-seven-languages.html</link><pubDate>Mon, 17 Sep 2012 00:00:00 +0000</pubDate><guid>https://caffeinatedideas.com/2012/09/17/my-journey-with-seven-languages.html</guid><description>&lt;p&gt;Being nearly a year behind on my reading list, I finally broke out my copy of
&lt;a href="http://www.amazon.com/Seven-Languages-Weeks-Programming-Programmers/dp/193435659X/ref=sr_1_1?ie=UTF8&amp;amp;qid=1348097921&amp;amp;sr=8-1&amp;amp;keywords=seven+languages+in+seven+weeks"&gt;Bruce Tate&amp;rsquo;s Seven Languages in Seven Weeks&lt;/a&gt; book for a little
mind expanding exercise. At first I was a little disappointed that I&amp;rsquo;ve already
worked with most of the languages back from my days in the CS program at UWM. Even
so, I decided to keep my mind open and I&amp;rsquo;m glad that I did.&lt;/p&gt;</description></item><item><title>Documenting ReST - Part 2</title><link>https://caffeinatedideas.com/2012/09/07/documenting-rest-part-2.html</link><pubDate>Fri, 07 Sep 2012 00:00:00 +0000</pubDate><guid>https://caffeinatedideas.com/2012/09/07/documenting-rest-part-2.html</guid><description>&lt;p&gt;In part 1 of this post, I laid out the problem facing us and how I was going
to tackle documenting our ReST API. After learning more about the JavaDoc tool,
extending it seemed like the logical solution that didn&amp;rsquo;t reinvent the wheel.
To make this whole project more interesting, I also decided that I&amp;rsquo;d try my hand
with Clojure. It&amp;rsquo;s a language I&amp;rsquo;ve been meaning to play with for awhile and this
seemed like a small enough task with some interesting meaty bits, such as exposing
Java classes to other tools.&lt;/p&gt;</description></item><item><title>Documenting ReST</title><link>https://caffeinatedideas.com/2012/08/20/documenting-rest.html</link><pubDate>Mon, 20 Aug 2012 00:00:00 +0000</pubDate><guid>https://caffeinatedideas.com/2012/08/20/documenting-rest.html</guid><description>&lt;p&gt;As a startup, we only have a limited number of resources and a huge product
backlog to get through (who doesn&amp;rsquo;t). To accelerate delivery of a bunch of
features, we had to de-agile our team and outsource parts of the development
efforts. While we decided to outsource important items, we don&amp;rsquo;t necessarily want
to loose control of the cloud platform. This has lead to a silo between our backend
service developers and the new outsourced group and some interesting communication
concerns. The largest is, how do we communicate our API to those using the API?&lt;/p&gt;</description></item><item><title>Apple's Mountain Lion Up-to-Date Program</title><link>https://caffeinatedideas.com/2012/07/25/apples-mountain-lion-up-to-date-program.html</link><pubDate>Wed, 25 Jul 2012 00:00:00 +0000</pubDate><guid>https://caffeinatedideas.com/2012/07/25/apples-mountain-lion-up-to-date-program.html</guid><description>&lt;p&gt;This year I made the decision to buy a new laptop. My MacBook Core Duo just was
struggling to keep up with all the programs that I use on a daily basis for
development. Running VMs with Linux and Windows didn&amp;rsquo;t help so I jumped on board
the new 15&amp;quot; MacBook with Retina display because I could get 16GB of RAM in it.
The added bonus was a free copy of Mountain Lion when it was released. I&amp;rsquo;m still
waiting on my download code from Apple&amp;rsquo;s up-to-date
program and that&amp;rsquo;s a bit surprising.&lt;/p&gt;</description></item><item><title>Scala Syntactical Heartburn</title><link>https://caffeinatedideas.com/2012/07/12/scala-syntactical-heartburn.html</link><pubDate>Thu, 12 Jul 2012 00:00:00 +0000</pubDate><guid>https://caffeinatedideas.com/2012/07/12/scala-syntactical-heartburn.html</guid><description>&lt;p&gt;This morning I was working through the Scala chapter from &amp;ldquo;Seven Languages in
Seven Weeks&amp;rdquo; by Bruce Tate and discovered there are three ways to apply a cumulative
operation across all items in a list using foldLeft().&lt;/p&gt;
&lt;p&gt;We start with the syntactical sugar version first:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;val list &lt;span style="color:#f92672"&gt;=&lt;/span&gt; List(1, 2, 3)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;val sum &lt;span style="color:#f92672"&gt;=&lt;/span&gt; (0 &lt;span style="color:#f92672"&gt;/&lt;/span&gt;: list) { (sum, i) &lt;span style="color:#f92672"&gt;=&amp;gt;&lt;/span&gt; sum &lt;span style="color:#f92672"&gt;+&lt;/span&gt; i }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The /: operator is just a shorthand notation for the function foldLeft and could be
written out in long form as&lt;/p&gt;</description></item><item><title>RIP LandlordCompanion.com</title><link>https://caffeinatedideas.com/2012/06/28/rip-landlordcompanion-com.html</link><pubDate>Thu, 28 Jun 2012 00:00:00 +0000</pubDate><guid>https://caffeinatedideas.com/2012/06/28/rip-landlordcompanion-com.html</guid><description>&lt;p&gt;I ran across &lt;a href="http://techcrunch.com/2012/06/25/rentobo/"&gt;this article&lt;/a&gt; about
Rentobo while
glancing through TechCrunch the other day. This sounds a lot like the idea I
had for a site I was working on from 2005-2010 called LandlordCompanion.com,
which failed to launch after many years of trying. Instead of yet another blog
posting about a success story, I figured I would write about my failure.
Hopefully someone else can learn from my mistakes.&lt;/p&gt;
&lt;p&gt;In 2005, I was in the search for a new place to rent with my girlfriend. We
wanted something a little bit more like a house and turned to Craigslist to find
rentals. The competition was pretty heavy, often with us sitting in the kitchen
filling out applications with other prospective tenants. Much of the process was
manual and often the landlords were individual people with day jobs. That made
the whole process of turning in application fees more difficult. I felt there had
to be a better way and why not use the Internet to do it.&lt;/p&gt;</description></item><item><title>ORM Rant, Continued</title><link>https://caffeinatedideas.com/2012/05/24/orm-rant-continued.html</link><pubDate>Thu, 24 May 2012 00:00:00 +0000</pubDate><guid>https://caffeinatedideas.com/2012/05/24/orm-rant-continued.html</guid><description>&lt;p&gt;Back in January, I wrote an entry about not being a fan of ORM frameworks in
software development. At the time, we were struggling to increase the performance
of the native mail, calendar and contact clients on the PlayBook. Our use of
SQLAlchemy hindered us by trying to abstract out database calls, sometimes in
ways that made the performance worse. Truly getting the performance numbers we
wanted often involved solving the data access problem and then spending just as
much time to figure out how to solve the problem again with SQLAlchemy. It would
have been easier to just write the SQL by hand and only used on level of abstraction.&lt;/p&gt;</description></item><item><title>Structuring and Naming Unit Tests</title><link>https://caffeinatedideas.com/2012/03/29/structuring-and-naming-unit-tests.html</link><pubDate>Thu, 29 Mar 2012 00:00:00 +0000</pubDate><guid>https://caffeinatedideas.com/2012/03/29/structuring-and-naming-unit-tests.html</guid><description>&lt;p&gt;Unit testing and automated unit testing is part of all conversations around
software development these days. It&amp;rsquo;s used by the agile groups to point out how
software gets developed without huge, monolithic testing ground and by quality
groups to prove that early testing reduces the overall cost on an organization.
Despite the topic being so wildly discussed and required in modern development,
we don&amp;rsquo;t really talk a lot about the nuts and bolts of development, specifically
how to structure and name the test code that we write.&lt;/p&gt;</description></item><item><title>Rumination on Social Forces</title><link>https://caffeinatedideas.com/2012/01/27/rumination-on-social-forces.html</link><pubDate>Fri, 27 Jan 2012 00:00:00 +0000</pubDate><guid>https://caffeinatedideas.com/2012/01/27/rumination-on-social-forces.html</guid><description>&lt;p&gt;Every morning, I start my day getting caught up on the tech news and latest
happenings in the world. All of these products continue to tout their social
capabilities or how they perform better with a social effect. Everywhere you
turn, it seems that tech companies are baking a social aspect into their products.
Is this always a good idea and should the inclusion of these social features help?
That depends entirely on the social forces involved.&lt;/p&gt;</description></item><item><title>Yup, I'm Still Not An ORM Fan</title><link>https://caffeinatedideas.com/2012/01/13/yup-im-still-not-an-orm-fan.html</link><pubDate>Fri, 13 Jan 2012 00:00:00 +0000</pubDate><guid>https://caffeinatedideas.com/2012/01/13/yup-im-still-not-an-orm-fan.html</guid><description>&lt;p&gt;Object-Relational Mappers (ORM) frameworks have taken off in the agile development
community in the last decade under the prose that relational databases are too
complex for developers to deal with and we should instead deal with objects in our
code. After working with a few different ORM frameworks, I&amp;rsquo;m still not sold. All the
perceived productivity gains are quickly a wash once the team starts to encounter the
common ORM problems. I see three large problems cropping up with code bases that
incorporate an ORM framework:&lt;/p&gt;</description></item><item><title>Task Queues Over Threads</title><link>https://caffeinatedideas.com/2012/01/06/task-queues-over-threads.html</link><pubDate>Fri, 06 Jan 2012 00:00:00 +0000</pubDate><guid>https://caffeinatedideas.com/2012/01/06/task-queues-over-threads.html</guid><description>&lt;p&gt;I hate threads.&lt;/p&gt;
&lt;p&gt;More accurately, I hate the abstraction the industry has settled on for trying
to do work in parallel. When the computer scientists sat down and created the
first threading API, they damned all future computer scientists to the wonderful
joy of debugging shared memory states and complex issues revolving around an
API that you can&amp;rsquo;t help but shoot yourself in the foot with. For instance, most
systems let you start a thread but then leave actually halting a thread to be this
complex, tangled mess of state signaling, join methods (which might not actually
join in the end) and a boat load of blocking issues.&lt;/p&gt;</description></item><item><title>Why Blog?</title><link>https://caffeinatedideas.com/2011/09/12/why-blog.html</link><pubDate>Mon, 12 Sep 2011 00:00:00 +0000</pubDate><guid>https://caffeinatedideas.com/2011/09/12/why-blog.html</guid><description>&lt;p&gt;I recently started reading the book
&lt;a href="http://www.codersatwork.com/"&gt;Coders At Work: Reflections on the Craft of Programming&lt;/a&gt;
and this snippet between Peter Seibel and Jamie Zawinski jumped out at me.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Seibel: Do you find that programming and writing are similar intellectual exercises?&lt;/p&gt;
&lt;p&gt;Zawinski: In some ways, yeah. Programming is obviously much more rigid. But as far as
the overall ability to express a thought, they&amp;rsquo;re very similar. Not rambling, having
an idea in your head of what you&amp;rsquo;re trying to say, and then being concise about
it. I think that kind of thinking is the overlap between programming and writing prose.&lt;/p&gt;</description></item><item><title>What Navy SEALs Can Teach Us About Software Development</title><link>https://caffeinatedideas.com/2011/05/09/what-navy-seals-can-teach-us-about-software-development.html</link><pubDate>Mon, 09 May 2011 00:00:00 +0000</pubDate><guid>https://caffeinatedideas.com/2011/05/09/what-navy-seals-can-teach-us-about-software-development.html</guid><description>&lt;p&gt;I was having a conversation with a co-worker last week about various bad scrum
practices that seem to creep into acceptance (often times called scrum-but). We
started to think about why we&amp;rsquo;ve seen scrum teams with these problems and what
the solution is. That&amp;rsquo;s when I asked, &amp;ldquo;how come the Navy SEALs don&amp;rsquo;t seem to have
as many problems even though they face great uncertainty and challenges?&amp;rdquo; After
thinking about it, I came up with three key lessons that we could learn from the
SEALs.&lt;/p&gt;</description></item><item><title>Stone Age Project Teams?</title><link>https://caffeinatedideas.com/2011/04/20/stone-age-project-teams.html</link><pubDate>Wed, 20 Apr 2011 00:00:00 +0000</pubDate><guid>https://caffeinatedideas.com/2011/04/20/stone-age-project-teams.html</guid><description>&lt;p&gt;Like everyone else in the industry, our team has embarked on the adventure to adopt
a variety of agile practices over the last couple of years. First, we picked up scrum
and started to develop features in iterations (despite our still waterfall like
release model). After a few projects with scrum, many members of the team took up
test driven development. After a lot of stumbling, we started to wrap our minds around
TDD and writing good unit tests. Now, we have some team members that want to adopt
pair programming. Yes, I&amp;rsquo;ll admit that I&amp;rsquo;m not a huge fan of pair programming but I
tried a couple of sessions with a few different people. The whole time I couldn&amp;rsquo;t get
over the biggest problem that I&amp;rsquo;ve found with pairing and that&amp;rsquo;s the need for a team
that works the same hours and is preferably co-located. In today&amp;rsquo;s world of globally
disperse teams, it seems wrong to sell people on the need to adopt a coding practice
that requires a team from the 20th century.&lt;/p&gt;</description></item><item><title>State of the Union: Application Logging</title><link>https://caffeinatedideas.com/2011/01/20/state-of-the-union-application-logging.html</link><pubDate>Thu, 20 Jan 2011 00:00:00 +0000</pubDate><guid>https://caffeinatedideas.com/2011/01/20/state-of-the-union-application-logging.html</guid><description>&lt;p&gt;Over the last week, I&amp;rsquo;ve been asked to help investigate some issues with a new
obfuscation process that our builds will now go through before deployment (we
can save the rants about obfuscating code for some other time). Per the norm
for this activity, the test group ran into issues in a section of code and needed
help investigating. As I dug into the issue, I turned to the log files and found
that they were absolutely worthless. While we suspected that the obfuscation
processor renamed or removed a class, we couldn&amp;rsquo;t find the telltale signs of
such an activity - no exceptions at all.&lt;/p&gt;</description></item><item><title>Desired Traits for Modern Software</title><link>https://caffeinatedideas.com/2011/01/19/desired-traits-for-modern-software.html</link><pubDate>Wed, 19 Jan 2011 00:00:00 +0000</pubDate><guid>https://caffeinatedideas.com/2011/01/19/desired-traits-for-modern-software.html</guid><description>&lt;p&gt;In my last entry, I mentioned that we need to look at more than correct execution
to determine if the software our dev teams produce is actually high quality
software and this requires us to determine what traits we want the code to have.
When asked, most people will probably include something about scalability, whereby
they want the most efficient memory footprint or to maximize the concurrent number
of jobs in process at any given time. This is a noble goal to have but let&amp;rsquo;s be
real - most of the software we write won&amp;rsquo;t suffer from the scale issues of eBay,
Google or Facebook. Even in that list, scalability as we&amp;rsquo;ve defined it wasn&amp;rsquo;t an
issue at first so it&amp;rsquo;s probably not a good quality to include up front.&lt;/p&gt;</description></item><item><title>Software QA: What the heck are they verifying?</title><link>https://caffeinatedideas.com/2011/01/09/software-qa-what-the-heck-are-they-verifying.html</link><pubDate>Sun, 09 Jan 2011 00:00:00 +0000</pubDate><guid>https://caffeinatedideas.com/2011/01/09/software-qa-what-the-heck-are-they-verifying.html</guid><description>&lt;p&gt;Ask layperson what a quality assurance tester does and, as you can guess, the
answer won&amp;rsquo;t clarify the situation much - they test the software to make sure
it has some level of quality. That answer didn&amp;rsquo;t really clear up the situation
any and it all revolves around the fact that we haven&amp;rsquo;t defined what quality
is. It&amp;rsquo;s a very interesting question to pose and one that I&amp;rsquo;m not sure has a
straight forward answer.&lt;/p&gt;</description></item><item><title>What's a Caffeinated Idea?</title><link>https://caffeinatedideas.com/2011/01/04/whats-a-caffeinated-idea.html</link><pubDate>Tue, 04 Jan 2011 00:00:00 +0000</pubDate><guid>https://caffeinatedideas.com/2011/01/04/whats-a-caffeinated-idea.html</guid><description>&lt;p&gt;Truth be told, the name was a domain that I registered sometime in 2005 when I was trying to build a tech startup in Milwaukee, WI at night while working a boring IT job during the day to support myself. I was naive back then and thought that there was no way I could fail in this venture because, let&amp;rsquo;s face it, I was the best developer in Milwaukee. I spent hours at night tinkering with python, MySQL and JavaScript in an insane attempt to create the next Google.&lt;/p&gt;</description></item></channel></rss>