<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>programming on Senior Software Engineer Reads</title><link>https://llcawthorne.github.io/tags/programming/</link><description>Recent content in programming on Senior Software Engineer Reads</description><generator>Hugo</generator><language>en-us</language><lastBuildDate>Fri, 16 Oct 2026 06:00:00 -0400</lastBuildDate><atom:link href="https://llcawthorne.github.io/tags/programming/index.xml" rel="self" type="application/rss+xml"/><item><title>Grokking Simplicity</title><link>https://llcawthorne.github.io/posts/grokking-simplicity/</link><pubDate>Fri, 16 Oct 2026 06:00:00 -0400</pubDate><guid>https://llcawthorne.github.io/posts/grokking-simplicity/</guid><description>&lt;p&gt;&lt;img alt="Grokking Simplicity cover" loading="lazy" src="https://llcawthorne.github.io/posts/grokking-simplicity/images/cover.jpg"&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Grokking Simplicity&lt;/em&gt; by Eric Normand teaches the difference between actions,
calculations, and data as a way to reason about mutation and side effects, and
it works better as a vocabulary book than a technique book. If you&amp;rsquo;ve already
internalized what &lt;code&gt;map&lt;/code&gt;, &lt;code&gt;filter&lt;/code&gt;, and &lt;code&gt;reduce&lt;/code&gt; are for, and I mean really
internalized it and not just being able to write the syntax, most of the core
material is going to read as confirmation of things you already believe instead
of new information. The higher-order function chapters and the copy-on-write
chapters fall right into that bucket. They&amp;rsquo;re clearly and patiently explained,
and useful for someone who&amp;rsquo;s never had the difference between mutating and
copying spelled out, but they&amp;rsquo;re slow going if you&amp;rsquo;ve been burned by shared
mutable state enough times to already distrust it on instinct.&lt;/p&gt;</description><content:encoded><![CDATA[<p><img alt="Grokking Simplicity cover" loading="lazy" src="/posts/grokking-simplicity/images/cover.jpg"></p>
<p><em>Grokking Simplicity</em> by Eric Normand teaches the difference between actions,
calculations, and data as a way to reason about mutation and side effects, and
it works better as a vocabulary book than a technique book. If you&rsquo;ve already
internalized what <code>map</code>, <code>filter</code>, and <code>reduce</code> are for, and I mean really
internalized it and not just being able to write the syntax, most of the core
material is going to read as confirmation of things you already believe instead
of new information. The higher-order function chapters and the copy-on-write
chapters fall right into that bucket. They&rsquo;re clearly and patiently explained,
and useful for someone who&rsquo;s never had the difference between mutating and
copying spelled out, but they&rsquo;re slow going if you&rsquo;ve been burned by shared
mutable state enough times to already distrust it on instinct.</p>
<p>The best material is outside that core. The architecture chapters cover both
stratified design and the onion model, and they were solid and worth having
read, though not so revelatory that I&rsquo;m in a hurry to go through them again. The
concurrency chapters were the standout. They introduce a diagramming technique
for reasoning about timelines and ordering that I hadn&rsquo;t run into before and
thought was really creative, and it&rsquo;s a lot different from the usual &ldquo;just use
locks or actors and hope&rdquo; approach most books take. Those are the chapters I&rsquo;d
go back to if a project involving concurrency comes up, since it&rsquo;s the kind of
technique you have to actually apply before it sticks.</p>
<p>The biggest miss for me was the immutable data chapters. I went in hoping for
advice on using immutable data structures in single-binding languages, the
discipline of writing code where a name, once bound, stays bound. What I got was
mostly copy-on-write technique, demonstrated with JavaScript objects that get
rebound on every update. That&rsquo;s a reasonable way to teach it in a language like
Elixir where rebinding is idiomatic, but it doesn&rsquo;t really carry over to the
habit I was actually after, which is reaching for <code>val</code> by default in Kotlin, or
treating a Haskell declaration as a one-time mathematical definition instead of
a variable that just happens not to change. The chapter shows you how to build
the immutable structure, but it doesn&rsquo;t really show you how to live in a
codebase that treats bindings as permanent.</p>
<p>Overall, it&rsquo;s a fast, well-explained, easy read that&rsquo;s clearly aimed at someone
running into these ideas for the first time. If that&rsquo;s not you, you&rsquo;ll skim more
than you expect, but the concurrency material deserves a second look, and the
architecture chapters were worth reading once, even if they weren&rsquo;t essential.</p>
]]></content:encoded></item><item><title>Fundamentals of Software Architecture</title><link>https://llcawthorne.github.io/posts/fundamentals-of-software-architecture/</link><pubDate>Wed, 14 Oct 2026 06:00:00 -0400</pubDate><guid>https://llcawthorne.github.io/posts/fundamentals-of-software-architecture/</guid><description>&lt;p&gt;&lt;img alt="Fundamentals of Software Architecture cover" loading="lazy" src="https://llcawthorne.github.io/posts/fundamentals-of-software-architecture/images/cover.jpg"&gt;&lt;/p&gt;
&lt;p&gt;The best part of the book was section 2, where it described different
architecture styles and gave each one star ratings across a variety of
characteristics, which I&amp;rsquo;m sure come from the authors&amp;rsquo; experience with each
style. I also liked how it framed microservices as part of a trend pendulum,
reacting against the reuse pain that SOA left behind, since I like noticing when
a new trend is really just correcting for the last one&amp;rsquo;s mistakes. I&amp;rsquo;m not an
architect currently, so I have no need for architecture decision records (ADRs),
except maybe for technical decisions made on personal projects so I can go back
and remember the thought that went into them. I may start using
&lt;a href="https://github.com/npryce/adr-tools"&gt;adr-tools&lt;/a&gt; on my own for that. Since I
mostly listened to this on runs, my notes don&amp;rsquo;t really do it justice. I want to
go back sometime when I&amp;rsquo;m not out of breath and write proper summaries of the
ratings for each architecture style.&lt;/p&gt;</description><content:encoded><![CDATA[<p><img alt="Fundamentals of Software Architecture cover" loading="lazy" src="/posts/fundamentals-of-software-architecture/images/cover.jpg"></p>
<p>The best part of the book was section 2, where it described different
architecture styles and gave each one star ratings across a variety of
characteristics, which I&rsquo;m sure come from the authors&rsquo; experience with each
style. I also liked how it framed microservices as part of a trend pendulum,
reacting against the reuse pain that SOA left behind, since I like noticing when
a new trend is really just correcting for the last one&rsquo;s mistakes. I&rsquo;m not an
architect currently, so I have no need for architecture decision records (ADRs),
except maybe for technical decisions made on personal projects so I can go back
and remember the thought that went into them. I may start using
<a href="https://github.com/npryce/adr-tools">adr-tools</a> on my own for that. Since I
mostly listened to this on runs, my notes don&rsquo;t really do it justice. I want to
go back sometime when I&rsquo;m not out of breath and write proper summaries of the
ratings for each architecture style.</p>
<p>Full <a href="https://github.com/llcawthorne/book-notes/blob/main/architecture/fundamentals-of-software-architecture/book-notes.md">book notes</a>.</p>
]]></content:encoded></item><item><title>The Pragmatic Programmer</title><link>https://llcawthorne.github.io/posts/the-pragmatic-programmer/</link><pubDate>Mon, 12 Oct 2026 06:00:00 -0400</pubDate><guid>https://llcawthorne.github.io/posts/the-pragmatic-programmer/</guid><description>&lt;p&gt;&lt;img alt="The Pragmatic Programmer cover" loading="lazy" src="https://llcawthorne.github.io/posts/the-pragmatic-programmer/images/cover.jpg"&gt;&lt;/p&gt;
&lt;p&gt;I first read &lt;em&gt;The Pragmatic Programmer&lt;/em&gt; years ago, and the 20th anniversary
edition holds up really well. It isn&amp;rsquo;t just a nostalgia lap, since the updates
feel necessary, folding in ideas like ETC (&amp;ldquo;Easier to Change&amp;rdquo;), functional-style
data pipelines, and more modern concurrency patterns without losing the voice
that made the original a classic. It reads less like a list of rules and more
like advice from people who have actually shipped things and learned from what
went wrong.&lt;/p&gt;</description><content:encoded><![CDATA[<p><img alt="The Pragmatic Programmer cover" loading="lazy" src="/posts/the-pragmatic-programmer/images/cover.jpg"></p>
<p>I first read <em>The Pragmatic Programmer</em> years ago, and the 20th anniversary
edition holds up really well. It isn&rsquo;t just a nostalgia lap, since the updates
feel necessary, folding in ideas like ETC (&ldquo;Easier to Change&rdquo;), functional-style
data pipelines, and more modern concurrency patterns without losing the voice
that made the original a classic. It reads less like a list of rules and more
like advice from people who have actually shipped things and learned from what
went wrong.</p>
<p>I listened to it as an audiobook, and it worked better than I expected for a
book this dense with concepts. The narration keeps a good pace, and the material
is conversational enough that it doesn&rsquo;t need diagrams on every page to land. If
you&rsquo;ve read the original, it&rsquo;s worth a revisit, and if you haven&rsquo;t, this is the
version to start with.</p>
<p>Full <a href="https://github.com/llcawthorne/book-notes/blob/main/architecture/the-pragmatic-programmer/book-notes.md">book notes</a>.</p>
]]></content:encoded></item><item><title>Advanced Functional Programming with Elixir</title><link>https://llcawthorne.github.io/posts/advanced-functional-programming-with-elixir/</link><pubDate>Fri, 09 Oct 2026 06:00:00 -0400</pubDate><guid>https://llcawthorne.github.io/posts/advanced-functional-programming-with-elixir/</guid><description>&lt;p&gt;&lt;img alt="Advanced Functional Programming with Elixir cover" loading="lazy" src="https://llcawthorne.github.io/posts/advanced-functional-programming-with-elixir/images/cover.jpg"&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Advanced Functional Programming with Elixir&lt;/em&gt; turned out to be a pretty good,
easy introduction to functional programming concepts, and it uses good domain
examples instead of math. It walks through Elixir&amp;rsquo;s protocol system with a DDD
slant, using a theme park domain with rides, patrons, and Fast Passes instead of
the numbers-only examples you get in most Haskell books. The code is built
around a companion library called &lt;code&gt;FunPark&lt;/code&gt;, a teaching-scale version of Koski&amp;rsquo;s
real production package, &lt;code&gt;Funx&lt;/code&gt;. The theme park was a good choice, and it paid
off most in the &lt;code&gt;Eq&lt;/code&gt;/&lt;code&gt;FastPass&lt;/code&gt; chapter, where a real business rule (two Fast
Passes with the same datetime conflict, but should still be equal by &lt;code&gt;id&lt;/code&gt;)
motivated &lt;code&gt;contramap&lt;/code&gt; far better than an abstract definition ever could have.&lt;/p&gt;</description><content:encoded><![CDATA[<p><img alt="Advanced Functional Programming with Elixir cover" loading="lazy" src="/posts/advanced-functional-programming-with-elixir/images/cover.jpg"></p>
<p><em>Advanced Functional Programming with Elixir</em> turned out to be a pretty good,
easy introduction to functional programming concepts, and it uses good domain
examples instead of math. It walks through Elixir&rsquo;s protocol system with a DDD
slant, using a theme park domain with rides, patrons, and Fast Passes instead of
the numbers-only examples you get in most Haskell books. The code is built
around a companion library called <code>FunPark</code>, a teaching-scale version of Koski&rsquo;s
real production package, <code>Funx</code>. The theme park was a good choice, and it paid
off most in the <code>Eq</code>/<code>FastPass</code> chapter, where a real business rule (two Fast
Passes with the same datetime conflict, but should still be equal by <code>id</code>)
motivated <code>contramap</code> far better than an abstract definition ever could have.</p>
<p>The quality was uneven, but in a predictable way. Eq, Ord, and Predicates were a
low bar that the book cleared easily. Monoid was the standout chapter, and the
one place where all the abstract machinery (<code>Eq.All</code>, comparators built with
<code>contramap</code>) paid off concretely enough to justify the ceremony. The monad
theory was thin and abstract on its own and only came together once Maybe and
Either gave it somewhere to land. The one real gap was motivation for Reader and
Effect, which never quite sold me. The mechanics were fine, but no example was
compelling enough to answer &ldquo;why bother wrapping this?&rdquo;</p>
<p>The Eq and Ord chapters are straightforward once you accept that Elixir
protocols dispatch on struct type only, which forces workarounds like
<code>contramap</code> and <code>to_eq_map</code> (comparators as plain maps, not just protocol
implementations) the moment your domain needs more than one valid notion of
equality for a type. That ties into DDD nicely, since equality isn&rsquo;t structural,
it depends on the bounded context, so the same type can have different valid
comparators depending on which part of the domain is asking.</p>
<p>The Predicates and Foldable chapter introduced <code>Foldable</code> for <code>Function</code> (a
predicate as a fold, with zero-arity thunk dispatch) with almost no explanation,
and I had to do some real reconstruction before it landed. It turned out to be a
catamorphism (one function per fixed shape) hiding under a name that sounds like
list reduction. I also caught a bug in the protocol declaration there.
<code>defprotocol</code> declared <code>fold_l(structure, transform_fn, base)</code>, but every real
implementation and call site used <code>(structure, acc, func)</code>, so the protocol&rsquo;s
own docs had the argument names reversed. It&rsquo;s harmless, since protocol callback
names aren&rsquo;t enforced, but it&rsquo;s misleading on a cold read.</p>
<p>Monoid was the best chapter. <code>Sum</code> is the toy case, and <code>Eq.All</code> and <code>Eq.Any</code>
are the real payoff, equality combinators as monoids, with <code>&amp;&amp;</code> and <code>||</code> doing
the combining. I caught one real typo there too (<code>default_not_eq</code> vs.
<code>default_not_eq?</code>), and it confirmed a design tension worth remembering: this
machinery is worth it once you have multiple domain-meaningful comparators that
need combining and reusing, but not for a one-off comparison you could write
with <code>&amp;&amp;</code> directly.</p>
<p>The monad theory chapter is careful to say it&rsquo;s &ldquo;inspired by category theory,
not a direct implementation.&rdquo; The laws (left identity, right identity, and
associativity) landed fine once I reverse-engineered <code>pure</code>, which shows up
without explanation, as the same idea as <code>Monoid</code>&rsquo;s <code>wrap</code>/<code>empty</code>, just
Monad-flavored. There&rsquo;s no dedicated Functor chapter, and <code>map</code> gets treated as
a free consequence of <code>bind</code> and <code>pure</code> instead of getting its own build-up,
unlike <em>From Objects to Functions</em>, which used Functor as the on-ramp to Monad.</p>
<p>Reader was clean mechanically (the environment as a deferred function,
<code>ask</code>/<code>asks</code>, and <code>run</code> as the escape hatch), but the worked examples were too
small to justify the ceremony over just passing an argument. The one clear win
was swapping <code>run(computation, prod_env)</code> for <code>run(computation, test_env)</code>,
which is a real dependency injection payoff, independent of the toy examples
around it.</p>
<p>Maybe and Either are where the book actually sold itself. You chain <code>bind</code>-based
computations and only check for failure once at the end, instead of doing
constant nil checks, which is a direct answer to how much Go&rsquo;s manual <code>err != nil</code> checking grates on me. <code>Either</code> wins over <code>Maybe</code> when you need to carry
<em>why</em> something failed. Choosing <code>bind</code> to fail fast versus <code>ap</code> to collect all
the errors was the most concrete moment in the whole book where an abstraction
proved its worth, since the same operations give you two different validation
strategies with one shared vocabulary.</p>
<p>Effect never made a compelling case for why actions specifically need to be
trapped in a monad, though the ride repository example was believable as a real
pattern. It was the weakest chapter at justifying its own existence.</p>
<p>I&rsquo;m not convinced the full ceremony is worth it over Kotlin&rsquo;s null safety for
the <code>Maybe</code> case, since that comparison feels close to a wash. Either doesn&rsquo;t
have an equally clean stand-in in Kotlin, though. Kotlin&rsquo;s <code>Result&lt;T&gt;</code> is tied
to <code>Throwable</code>, so a hand-rolled <code>Outcome</code> type or Arrow&rsquo;s <code>Either</code> are the real
equivalents, and that&rsquo;s the one idea from this book most likely to actually
change how I write Kotlin.</p>
<p>Overall, it&rsquo;s a good, easy introduction to FP for someone with some prior
exposure who wants examples grounded in a domain instead of math. I&rsquo;m glad I had
AI on hand to work through the parts the book left underexplained, especially
the Foldable predicate case, since it would&rsquo;ve been a rougher read alone.</p>
<p>Full <a href="https://github.com/llcawthorne/book-notes/blob/main/elixir/advanced-fp/book-notes.md">book notes</a>.</p>
]]></content:encoded></item><item><title>The Programmer's Brain</title><link>https://llcawthorne.github.io/posts/the-programmers-brain/</link><pubDate>Wed, 07 Oct 2026 06:00:00 -0400</pubDate><guid>https://llcawthorne.github.io/posts/the-programmers-brain/</guid><description>&lt;p&gt;&lt;img alt="The Programmer&amp;rsquo;s Brain cover" loading="lazy" src="https://llcawthorne.github.io/posts/the-programmers-brain/images/cover.jpg"&gt;&lt;/p&gt;
&lt;p&gt;I didn&amp;rsquo;t find a lot of the advice in this book terribly useful. It mostly seemed
like common sense backed by a bit of research. The onboarding advice was
probably the most useful part, if only because I&amp;rsquo;m senior enough now that it
might come in handy with junior colleagues. The idea is basically to focus on
single activities at first, starting with concrete code instead of diagrams, and
remembering that everything is new to them. It is easy to forget once you&amp;rsquo;ve
been steeped in a codebase for years.&lt;/p&gt;</description><content:encoded><![CDATA[<p><img alt="The Programmer&rsquo;s Brain cover" loading="lazy" src="/posts/the-programmers-brain/images/cover.jpg"></p>
<p>I didn&rsquo;t find a lot of the advice in this book terribly useful. It mostly seemed
like common sense backed by a bit of research. The onboarding advice was
probably the most useful part, if only because I&rsquo;m senior enough now that it
might come in handy with junior colleagues. The idea is basically to focus on
single activities at first, starting with concrete code instead of diagrams, and
remembering that everything is new to them. It is easy to forget once you&rsquo;ve
been steeped in a codebase for years.</p>
<p>The Roles of Variables Framework was new to me too. I actually paused my run to
jot down the key ideas since it felt worth remembering, even though I wasn&rsquo;t
sure how valuable it would be in practice. Looking at my own code though, I
mostly stick to &ldquo;fixed value&rdquo; variables over any of the other roles (<code>val</code>s in
Kotlin, and I&rsquo;m trying to do some Haskell on the side for fun). I also liked the
advice on dealing with interruptions by offloading as much of your thought
process as possible instead of trying to hold it all in your head. That&rsquo;s
basically what I use Obsidian for at home, and at work I&rsquo;ve had the same
<code>notes.txt</code> file open for ten years that&rsquo;s probably 50 pages long by now.</p>
<p>Full <a href="https://github.com/llcawthorne/book-notes/blob/main/architecture/the-programmers-brain/book-notes.md">book notes</a>.</p>
]]></content:encoded></item><item><title>Learn Functional Programming with Elixir</title><link>https://llcawthorne.github.io/posts/learn-functional-programming-with-elixir/</link><pubDate>Mon, 05 Oct 2026 06:00:00 -0400</pubDate><guid>https://llcawthorne.github.io/posts/learn-functional-programming-with-elixir/</guid><description>&lt;p&gt;&lt;img alt="Learn Functional Programming with Elixir cover" loading="lazy" src="https://llcawthorne.github.io/posts/learn-functional-programming-with-elixir/images/cover.jpg"&gt;&lt;/p&gt;
&lt;p&gt;A perfectly good introduction to the Elixir language, although it didn&amp;rsquo;t have
anything specific to learning functional programming in it beyond getting used
to doing things the Elixir way. I guess it had more recursion than most
introductory programming books&amp;hellip; It feels like a terrible introduction in
comparison to Dave Thomas&amp;rsquo; &lt;em&gt;Programming Elixir&lt;/em&gt; though, since it stops totally
short of introducing the Actor model and OTP, which are unique strengths of
Elixir, but that&amp;rsquo;s obviously a longer book to read.&lt;/p&gt;</description><content:encoded><![CDATA[<p><img alt="Learn Functional Programming with Elixir cover" loading="lazy" src="/posts/learn-functional-programming-with-elixir/images/cover.jpg"></p>
<p>A perfectly good introduction to the Elixir language, although it didn&rsquo;t have
anything specific to learning functional programming in it beyond getting used
to doing things the Elixir way. I guess it had more recursion than most
introductory programming books&hellip; It feels like a terrible introduction in
comparison to Dave Thomas&rsquo; <em>Programming Elixir</em> though, since it stops totally
short of introducing the Actor model and OTP, which are unique strengths of
Elixir, but that&rsquo;s obviously a longer book to read.</p>
<p>Full <a href="https://github.com/llcawthorne/book-notes/blob/main/elixir/learn-fp/book-notes.md">book notes</a>.</p>
]]></content:encoded></item><item><title>Build Websites with Hugo</title><link>https://llcawthorne.github.io/posts/build-websites-with-hugo/</link><pubDate>Thu, 01 Oct 2026 16:45:00 -0400</pubDate><guid>https://llcawthorne.github.io/posts/build-websites-with-hugo/</guid><description>&lt;p&gt;&lt;img alt="Build Websites with Hugo cover" loading="lazy" src="https://llcawthorne.github.io/posts/build-websites-with-hugo/images/cover.jpg"&gt;&lt;/p&gt;
&lt;p&gt;I picked up &lt;em&gt;Build Websites with Hugo&lt;/em&gt; because I&amp;rsquo;m a PragProg loyalist with
plans to revive my old blog, and if they have a book on something I&amp;rsquo;m using, I
like to have an opinion on it. My opinion is that it&amp;rsquo;s fine, but barely. The
book is from 2020, and Hugo has changed enough since then that half the
examples either don&amp;rsquo;t work or generate deprecation warnings. I was running Hugo
0.164 against a book written for 0.68, and the scaffolding generated by
&lt;code&gt;hugo new theme&lt;/code&gt; is completely different now, so it actively conflicted with
the book&amp;rsquo;s instructions at nearly every step.&lt;/p&gt;</description><content:encoded><![CDATA[<p><img alt="Build Websites with Hugo cover" loading="lazy" src="/posts/build-websites-with-hugo/images/cover.jpg"></p>
<p>I picked up <em>Build Websites with Hugo</em> because I&rsquo;m a PragProg loyalist with
plans to revive my old blog, and if they have a book on something I&rsquo;m using, I
like to have an opinion on it. My opinion is that it&rsquo;s fine, but barely. The
book is from 2020, and Hugo has changed enough since then that half the
examples either don&rsquo;t work or generate deprecation warnings. I was running Hugo
0.164 against a book written for 0.68, and the scaffolding generated by
<code>hugo new theme</code> is completely different now, so it actively conflicted with
the book&rsquo;s instructions at nearly every step.</p>
<p>Worse, the entire book has you building a custom theme from scratch, which is a
reasonable way to teach, except that anyone graduating from this book is going
to immediately throw that theme away for something maintained by people who
actually know CSS, so you spend 200 pages building something disposable. What
you do get out of it is an understanding of how Hugo thinks, with the template
hierarchy, partials, taxonomies, front matter, and the asset pipeline, and that
did turn out to be worth something, so just go in knowing you&rsquo;re reading it for
the concepts and not the site. Honestly, you&rsquo;d probably learn as much in an
afternoon of playing with Hugo directly and asking an AI assistant when you get
stuck.</p>
<p>There wasn&rsquo;t much else in it worth remembering, except maybe how to make a cool
&ldquo;This page will take X minutes to read&rdquo; summary.</p>
]]></content:encoded></item><item><title>From Objects to Functions</title><link>https://llcawthorne.github.io/posts/from-objects-to-functions/</link><pubDate>Sun, 27 Sep 2026 15:00:00 -0400</pubDate><guid>https://llcawthorne.github.io/posts/from-objects-to-functions/</guid><description>&lt;p&gt;&lt;img alt="From Objects to Functions cover" loading="lazy" src="https://llcawthorne.github.io/posts/from-objects-to-functions/images/cover.jpg"&gt;&lt;/p&gt;
&lt;p&gt;This was one of the better books I&amp;rsquo;ve read recently for actually changing how I think about programming. It combines domain-driven design, test-first development, and functional programming into one coherent story, which is pretty rare, since most books only tackle one of those at a time. Unlike some of my other recent reads, the Kotlin itself was well-structured and idiomatic throughout, not just functional-flavored Java.&lt;/p&gt;</description><content:encoded><![CDATA[<p><img alt="From Objects to Functions cover" loading="lazy" src="/posts/from-objects-to-functions/images/cover.jpg"></p>
<p>This was one of the better books I&rsquo;ve read recently for actually changing how I think about programming. It combines domain-driven design, test-first development, and functional programming into one coherent story, which is pretty rare, since most books only tackle one of those at a time. Unlike some of my other recent reads, the Kotlin itself was well-structured and idiomatic throughout, not just functional-flavored Java.</p>
<p>The book builds a real app, a to-do list called Zettai, outside-in with TDD, starting from acceptance tests and working down to the domain core. It uses http4k, which the author picked specifically for its &ldquo;everything is a function&rdquo; philosophy (an <code>HttpHandler</code> is just <code>(Request) -&gt; Response</code>), and Exposed for persistence. The book&rsquo;s repo only has the start and end states for each step (step1 through step7, spread loosely across 13 chapters) rather than the intermediate changes, so I had to lean on the book&rsquo;s prose to follow <em>why</em> the code evolved the way it did and not just <em>what</em> it ended up as.</p>
<p>The book starts with actor-based domain-driven testing and works its way through receiver-typed lambdas and extension functions, higher-order functions and purity, and a hub-and-spokes (ports and adapters) architecture before it gets into the theory. From there it covers monoids (with a door state machine example), functors, monads, and applicatives, then event sourcing and profunctors, and it finishes with a logging and JSON capstone that pulls everything together. The theory was mostly motivated with real code before the abstraction got a name, which I appreciated. Functors come out of <code>Holder</code>, <code>List</code>, and <code>Outcome</code>, and then <code>ProjectionQuery</code> deliberately breaks the container idea to push you into thinking of them as computations instead of containers. Monads come from a concrete <code>TxReader&lt;TxReader&lt;T&gt;&gt;</code> nesting problem instead of being introduced abstractly, and applicatives show up through error-accumulating validation with <code>`!`</code> and <code>`*`</code> operators, contrasted against the way monads short-circuit. The exceptions were the door monoid section and parts of chapter 7, where the vocabulary showed up before the payoff did. That was disorienting in the moment, even though the payoff did eventually arrive by the end of the chapter.</p>
<p>The Kotlin was the kind you&rsquo;d want to see in a strong codebase, with extension functions, receiver types, sealed classes, and generics all used the way they&rsquo;re meant to be used and not just as vehicles for FP theory. The actor-based test framework, Pesticide, was a neat pattern too, you write a test once and run it against the domain, a local HTTP server, or a deployed instance, even if I&rsquo;m not sure I&rsquo;d adopt the library itself over something mainstream like kotest.</p>
<p>The final third, especially the logging and JSON chapters, had a noticeably higher error rate than the rest of the book. Functions like <code>storeEvents</code> got used before they were shown, parameter counts didn&rsquo;t match, and field names had typos. The JSON chapter has you build a hand-rolled JSON library that even the author admits he was &ldquo;wary&rdquo; of introducing, and it&rsquo;s incomplete, since its own reflection-based code generation &ldquo;seldom works right without manual intervention.&rdquo; A thin adapter wrapping kotlinx.serialization in an <code>Outcome</code> probably would have served the book&rsquo;s own goals better than building JSON parsing from scratch. There&rsquo;s also an optional 50-page category theory appendix, which was a mixed bag. Functors, monads, and comonads mostly confirmed what the main text had already taught me, and Kleisli categories turned out to be <code>bind</code> with different notation once I decoded them, but profunctors and the Yoneda lemma were presented abstractly enough that I had to reconstruct them from the code examples myself before they landed.</p>
<p>Looking back at it now, after a stretch in Haskell, I remember a lot more about the DDD and TDD from this book than I do about the details of Kotlin. It was really into TDD, with the whole app built outside-in from acceptance tests, and I miss that now that I&rsquo;m working through 1000 pages of <em>Django 5 By Example</em> without a single test in them. Anyway, it&rsquo;s a dense book, but it was worth the length, and it changed how I think about combining DDD, testing, and FP instead of treating them as separate concerns. I&rsquo;d recommend it to someone with some Kotlin under their belt and the patience for some rough editing toward the end.</p>
<p>Full <a href="https://github.com/llcawthorne/book-notes/blob/main/kotlin/from-objects-to-functions/book-notes.md">book notes</a>.</p>
]]></content:encoded></item><item><title>Head First Kotlin</title><link>https://llcawthorne.github.io/posts/head-first-kotlin/</link><pubDate>Sat, 26 Sep 2026 21:05:00 -0400</pubDate><guid>https://llcawthorne.github.io/posts/head-first-kotlin/</guid><description>&lt;p&gt;&lt;img alt="Head First Kotlin cover" loading="lazy" src="https://llcawthorne.github.io/posts/head-first-kotlin/images/cover.jpg"&gt;&lt;/p&gt;
&lt;p&gt;Better than initially assessed: Chapter 2 introduces collections, good variance
coverage (with a Pet hierarchy), covers extensions and their role in the stdlib,
two lambda/HOF chapters. Unusual ordering: generics before lambdas.
map/filter/fold deferred to lambda chapters. Coroutines appendix exists but
dated.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Head First Kotlin&lt;/em&gt; uses the usual Head First spiral approach - introduce a
concept lightly, let it sit, circle back with depth later - which meant it
deferred anything not strictly load-bearing to the appendices. Labeled breaks
and enum classes, both things I&amp;rsquo;d consider core language features, got pushed
all the way to Appendix C rather than covered in the main chapters. That
appendix is even honest about it in the title: &amp;ldquo;The Top Ten Things (We Didn&amp;rsquo;t
Cover)&amp;rdquo; - ten separate topics, including packages, visibility modifiers, sealed
classes, and object declarations, that never made it into the twelve main
chapters at all.&lt;/p&gt;</description><content:encoded><![CDATA[<p><img alt="Head First Kotlin cover" loading="lazy" src="/posts/head-first-kotlin/images/cover.jpg"></p>
<p>Better than initially assessed: Chapter 2 introduces collections, good variance
coverage (with a Pet hierarchy), covers extensions and their role in the stdlib,
two lambda/HOF chapters. Unusual ordering: generics before lambdas.
map/filter/fold deferred to lambda chapters. Coroutines appendix exists but
dated.</p>
<p><em>Head First Kotlin</em> uses the usual Head First spiral approach - introduce a
concept lightly, let it sit, circle back with depth later - which meant it
deferred anything not strictly load-bearing to the appendices. Labeled breaks
and enum classes, both things I&rsquo;d consider core language features, got pushed
all the way to Appendix C rather than covered in the main chapters. That
appendix is even honest about it in the title: &ldquo;The Top Ten Things (We Didn&rsquo;t
Cover)&rdquo; - ten separate topics, including packages, visibility modifiers, sealed
classes, and object declarations, that never made it into the twelve main
chapters at all.</p>
<p>Compare that to <em>Head First Go</em>, which felt reasonably complete without needing to
punt a top-ten list to the back of the book - but that&rsquo;s not really a fair
fight. Go is a deliberately small language by design (that&rsquo;s Rob Pike&rsquo;s whole
philosophy. Minimal surface area, few ways to do anything), so a Head First
treatment of it has a real shot at covering the whole language in the main
chapters. Kotlin&rsquo;s surface area is just bigger: null safety, data classes,
sealed classes, extension functions, coroutines, object
expressions/declarations, operator overloading. So a book aimed at teaching it
from scratch in a similarly-sized page count is going to hit a wall and have to
defer something. It&rsquo;s less &ldquo;Head First Kotlin did a worse job&rdquo; and more &ldquo;the two
books picked structurally different-sized languages to cover with the same
format.&rdquo;</p>
<p>Full <a href="https://github.com/llcawthorne/book-notes/blob/main/kotlin/head-first-kotlin/book-notes.md">book notes</a>.</p>
]]></content:encoded></item><item><title>Kotlin from Scratch</title><link>https://llcawthorne.github.io/posts/kotlin-from-scratch/</link><pubDate>Sat, 26 Sep 2026 21:00:00 -0400</pubDate><guid>https://llcawthorne.github.io/posts/kotlin-from-scratch/</guid><description>&lt;p&gt;&lt;img alt="Kotlin from Scratch cover" loading="lazy" src="https://llcawthorne.github.io/posts/kotlin-from-scratch/images/cover.jpg"&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Kotlin from Scratch&lt;/em&gt; is a project book, and the projects are mostly math and computation: Euclid&amp;rsquo;s algorithm, the Sieve of Eratosthenes, Fibonacci, physics simulations, fractals, sorting, and A* search. It was good typing practice, and some of the math and algorithms were really interesting, but it was disappointing as a source of good Kotlin code. The first two chapters covered the language fundamentals in almost as much depth as all of &lt;em&gt;Head First Kotlin&lt;/em&gt;, but that depth never came back. Nothing after chapter 2 touches generics, sealed classes, delegation, or coroutines, extension functions never show up, and the language features stay limited. Chapter 3 was a whole detour into JavaFX that I didn&amp;rsquo;t ask for and won&amp;rsquo;t need for Android or Swift, though I don&amp;rsquo;t regret typing it, since the Stage and Scene boilerplate turned into a really cool spiral, and fighting the Gradle multi-module setup taught me more about the build system than the book itself did.&lt;/p&gt;</description><content:encoded><![CDATA[<p><img alt="Kotlin from Scratch cover" loading="lazy" src="/posts/kotlin-from-scratch/images/cover.jpg"></p>
<p><em>Kotlin from Scratch</em> is a project book, and the projects are mostly math and computation: Euclid&rsquo;s algorithm, the Sieve of Eratosthenes, Fibonacci, physics simulations, fractals, sorting, and A* search. It was good typing practice, and some of the math and algorithms were really interesting, but it was disappointing as a source of good Kotlin code. The first two chapters covered the language fundamentals in almost as much depth as all of <em>Head First Kotlin</em>, but that depth never came back. Nothing after chapter 2 touches generics, sealed classes, delegation, or coroutines, extension functions never show up, and the language features stay limited. Chapter 3 was a whole detour into JavaFX that I didn&rsquo;t ask for and won&rsquo;t need for Android or Swift, though I don&rsquo;t regret typing it, since the Stage and Scene boilerplate turned into a really cool spiral, and fighting the Gradle multi-module setup taught me more about the build system than the book itself did.</p>
<p>The author&rsquo;s code quality was the real letdown. He leans on mutable <code>var</code>s constantly, and worse, on global mutable state. If anything, spotting all those <code>var</code>s helped remind me to use more <code>val</code>s. The genetic algorithm chapter had <code>tournament()</code> calls with no parameters that still returned different results every time, because they were secretly reaching into a global population plus some randomness, so there&rsquo;s no referential transparency and no way to reason about a call site without reading the function body. The comments were often pure noise too, like <code>// Run the genetic algorithm</code> sitting right above <code>runGA()</code>. Project 16 was missing an entire function, which the errata later confirmed wasn&rsquo;t my mistake, so I pulled that one from the GitHub companion repo instead of fighting a broken example.</p>
<p>The <code>fold</code> and <code>map</code> chapter was a letdown in a different way. It only reached for the classic textbook examples of summing a list, calculating a product, and concatenating strings, and nothing that shows off what the tools are actually for. I ended up chewing on a much better example on my own, finding all the subsets of a set (the power set). I worked that out mostly by instinct, keeping the subsets so far and, for each new element, adding a copy of every existing subset with that element in it, before I ever realized <code>fold</code> was the idiomatic way to express it. Even where the book <em>does</em> introduce a powerful construct, it plays it safe with examples that don&rsquo;t show its range. One thing it did get right, which I wouldn&rsquo;t have assumed coming from Java, is its package-naming advice to &ldquo;join multiple words or use camelCase,&rdquo; which checks out against the official Kotlin coding conventions, since they explicitly allow both.</p>
<p>I skipped typing the Modeling/Simulation and Fractals chapters, since they were more JavaFX and more of the same mutable-state pattern, and just skimmed them on GitHub instead. The sorting and searching chapter (chapter 7) had the cleanest code in the book, with fewer <code>var</code>s, and the ones it had were properly scoped instead of global. In-place sorting algorithms are supposed to mutate anyway, so that&rsquo;s not really a knock.</p>
<p>The genetic algorithm (GA) chapter and the particle swarm optimization (PSO) and ant colony chapter were the highlight. I typed three GA variants by hand (a toy problem, a knapsack problem, and multivariate equation solving, by way of the &ldquo;weasel program&rdquo; Shakespeare quote demo), then took the GitHub shortcut for PSO and the traveling salesman ant simulation once I&rsquo;d internalized the pattern. PSO actually beat the GA on the Eggholder problem, it took fewer generations, found a solution the GA never found in multiple runs, and didn&rsquo;t get stuck in the same local optimum the GA kept falling into.</p>
<p>So it&rsquo;s worth reading for the algorithms and the typing reps, but not for the Kotlin, and I wouldn&rsquo;t recommend it as a &ldquo;here&rsquo;s good idiomatic Kotlin&rdquo; reference.</p>
<p>Full <a href="https://github.com/llcawthorne/book-notes/blob/main/kotlin/kotlin-from-scratch/book-notes.md">book notes</a>.</p>
]]></content:encoded></item><item><title>Automate the Boring Stuff with Python</title><link>https://llcawthorne.github.io/posts/automate-the-boring-stuff-with-python/</link><pubDate>Sat, 19 Sep 2026 15:00:00 -0400</pubDate><guid>https://llcawthorne.github.io/posts/automate-the-boring-stuff-with-python/</guid><description>&lt;p&gt;&lt;img alt="Automate the Boring Stuff with Python cover" loading="lazy" src="https://llcawthorne.github.io/posts/automate-the-boring-stuff-with-python/images/cover.jpg"&gt;&lt;/p&gt;
&lt;p&gt;Sometimes it&amp;rsquo;s fun to read easy books, and this was an easy, fun book. It didn&amp;rsquo;t
go into as much depth about Python as the Python Tutorial on the Python website,
but it covered the basics, then went on a romping overview of using all sorts of
libraries to perform tasks you might need to perform. Some of the tasks were
pretty relevant, like loading an Excel file, working with JSON, or sending
yourself an email; others were cool and could be put to creative uses, like
driving a web browser with Playwright or working with a SQLite database; and
some were kind of niche topics that I&amp;rsquo;d look back up if I ever needed to deal
with them, like working with XML, OCR, or speech recognition. They were all kind
of fun to play with, so I enjoyed reading this book.&lt;/p&gt;</description><content:encoded><![CDATA[<p><img alt="Automate the Boring Stuff with Python cover" loading="lazy" src="/posts/automate-the-boring-stuff-with-python/images/cover.jpg"></p>
<p>Sometimes it&rsquo;s fun to read easy books, and this was an easy, fun book. It didn&rsquo;t
go into as much depth about Python as the Python Tutorial on the Python website,
but it covered the basics, then went on a romping overview of using all sorts of
libraries to perform tasks you might need to perform. Some of the tasks were
pretty relevant, like loading an Excel file, working with JSON, or sending
yourself an email; others were cool and could be put to creative uses, like
driving a web browser with Playwright or working with a SQLite database; and
some were kind of niche topics that I&rsquo;d look back up if I ever needed to deal
with them, like working with XML, OCR, or speech recognition. They were all kind
of fun to play with, so I enjoyed reading this book.</p>
<p>Full <a href="https://github.com/llcawthorne/book-notes/blob/main/python/automate-the-boring-stuff/book-notes.md">book notes</a>.</p>
]]></content:encoded></item><item><title>Go Language Opinions</title><link>https://llcawthorne.github.io/posts/go-language-opinions/</link><pubDate>Sat, 12 Sep 2026 18:00:00 -0400</pubDate><guid>https://llcawthorne.github.io/posts/go-language-opinions/</guid><description>&lt;p&gt;Go&amp;rsquo;s tooling is what stuck with me the most. gofmt is flawless, even on case
statements, no matter how hard I try to trick it, it always formats the file
correctly. Cross-compilation with GOOS/GOARCH is excellent, shipping a
single self-contained binary is genuinely nice to hand off, and the command
line tooling is great too. I like that the implementation stays transparent
instead of hiding behind framework magic, and I prefer simple structs with
methods over deep inheritance hierarchies. &lt;em&gt;Head First Go&lt;/em&gt; gave me real
confidence with the language, and &lt;em&gt;Powerful Command-Line Applications in Go&lt;/em&gt;
taught me a lot about building command-line apps, even in languages other
than Go, like how easy it is to write a markdown previewer when the standard
library gives you so much for free, and to always check out a new language&amp;rsquo;s
argument-parsing frameworks early. Even &lt;code&gt;//&lt;/code&gt; comments felt natural to me.&lt;/p&gt;</description><content:encoded><![CDATA[<p>Go&rsquo;s tooling is what stuck with me the most. gofmt is flawless, even on case
statements, no matter how hard I try to trick it, it always formats the file
correctly. Cross-compilation with GOOS/GOARCH is excellent, shipping a
single self-contained binary is genuinely nice to hand off, and the command
line tooling is great too. I like that the implementation stays transparent
instead of hiding behind framework magic, and I prefer simple structs with
methods over deep inheritance hierarchies. <em>Head First Go</em> gave me real
confidence with the language, and <em>Powerful Command-Line Applications in Go</em>
taught me a lot about building command-line apps, even in languages other
than Go, like how easy it is to write a markdown previewer when the standard
library gives you so much for free, and to always check out a new language&rsquo;s
argument-parsing frameworks early. Even <code>//</code> comments felt natural to me.</p>
<p>Some of it is more neutral than a selling point. I appreciate Go&rsquo;s minimalism
as a deliberate design choice even though it isn&rsquo;t really my target use case.
Google&rsquo;s involvement makes me a little cautious. Binary size and startup time
don&rsquo;t matter much for what I build, and skipping a GC isn&rsquo;t a selling point
when I&rsquo;m not doing systems programming.</p>
<p>I&rsquo;m moving on from Go for now. Kotlin is more professionally applicable to
me, and it works as a better Java without leaving the JVM. Real app
development projects in Kotlin and Swift give me concrete motivation that Go
doesn&rsquo;t, and honestly my language list just needed trimming.</p>
<p>I might come back to it, though. <em>Distributed Systems in Go</em> looks like the
most transparent way to see microservice patterns without Spring hiding the
mechanics, and <em>Learn Go with Tests</em> looks good for picking up TDD patterns.
The books will still be there, and Go isn&rsquo;t going anywhere.</p>
<p>After trying ktlint in Kotlin, I&rsquo;m even more impressed with how reliable and
fast gofmt is. It&rsquo;s a benefit of working with such a simple language. ktlint
flags errors well but regularly gets stymied and unable to fix the file, so I
have to either fix it manually or ignore the error. Formatting is more
consistent in IntelliJ though, which is the main place I do Kotlin work. This
is just something that bugs me when I type in book code in Vim, and Kotlin
book code isn&rsquo;t even formatted to ktlint&rsquo;s specs either, whereas Go code
everywhere looks pretty much the same. I still have to deal with Go&rsquo;s odd
capitalization rules for function names, but at least everything else looks
reliably good.</p>
]]></content:encoded></item><item><title>Powerful Command-Line Applications in Go</title><link>https://llcawthorne.github.io/posts/powerful-command-line-applications-in-go/</link><pubDate>Fri, 28 Aug 2026 18:00:00 -0400</pubDate><guid>https://llcawthorne.github.io/posts/powerful-command-line-applications-in-go/</guid><description>&lt;p&gt;&lt;img alt="Powerful Command-Line Applications in Go cover" loading="lazy" src="https://llcawthorne.github.io/posts/powerful-command-line-applications-in-go/images/cover.jpg"&gt;&lt;/p&gt;
&lt;p&gt;This was a good way to see a number of non-trivial applications in Go. It
tackled real projects like a Markdown Previewer and a Port Scanner and used
production-grade libraries like Cobra for command-line arguments and Viper for
configuration settings. The Markdown Previewer was probably good enough for me
to consider using it. Honestly, Cobra and Viper were good enough libraries
that it makes me start looking at what my options are for command-line
parsing libraries early when studying a new language now. A lot of the
examples were big to type, but that is good since it made me feel more
comfortable with the language. They were also complicated enough that I made
mistakes and got to deal with error messages from the compiler. I will say I
was disappointed multiple times that Go&amp;rsquo;s compiler points out the first error
it finds and then stops, so when you fix it you might just be greeted by
another error. It&amp;rsquo;s not like Java or Kotlin where the compiler spits out 10
errors and 5 are probably caused by the earlier errors but the other 5 need
to be corrected. The pomodoro app was actually quite usable after I got past
the fact that it wouldn&amp;rsquo;t display correctly in tmux. That was a hard
debugging session wondering what was wrong with my output from typing up the
code before I finally pinned the blame on running it in a tmux session
though, since having a tmux session is just getting so normal to me. Not only
did I learn a lot about using Go for small to intermediate-sized projects,
but I learned a lot about writing good command-line apps that I can take
with me to other languages.&lt;/p&gt;</description><content:encoded><![CDATA[<p><img alt="Powerful Command-Line Applications in Go cover" loading="lazy" src="/posts/powerful-command-line-applications-in-go/images/cover.jpg"></p>
<p>This was a good way to see a number of non-trivial applications in Go. It
tackled real projects like a Markdown Previewer and a Port Scanner and used
production-grade libraries like Cobra for command-line arguments and Viper for
configuration settings. The Markdown Previewer was probably good enough for me
to consider using it. Honestly, Cobra and Viper were good enough libraries
that it makes me start looking at what my options are for command-line
parsing libraries early when studying a new language now. A lot of the
examples were big to type, but that is good since it made me feel more
comfortable with the language. They were also complicated enough that I made
mistakes and got to deal with error messages from the compiler. I will say I
was disappointed multiple times that Go&rsquo;s compiler points out the first error
it finds and then stops, so when you fix it you might just be greeted by
another error. It&rsquo;s not like Java or Kotlin where the compiler spits out 10
errors and 5 are probably caused by the earlier errors but the other 5 need
to be corrected. The pomodoro app was actually quite usable after I got past
the fact that it wouldn&rsquo;t display correctly in tmux. That was a hard
debugging session wondering what was wrong with my output from typing up the
code before I finally pinned the blame on running it in a tmux session
though, since having a tmux session is just getting so normal to me. Not only
did I learn a lot about using Go for small to intermediate-sized projects,
but I learned a lot about writing good command-line apps that I can take
with me to other languages.</p>
<p>Full <a href="https://github.com/llcawthorne/book-notes/blob/main/go/pragprog.com/rggo/book-notes.md">book notes</a>.</p>
]]></content:encoded></item><item><title>Head First Go</title><link>https://llcawthorne.github.io/posts/head-first-go/</link><pubDate>Tue, 11 Aug 2026 18:00:00 -0400</pubDate><guid>https://llcawthorne.github.io/posts/head-first-go/</guid><description>&lt;p&gt;&lt;img alt="Head First Go cover" loading="lazy" src="https://llcawthorne.github.io/posts/head-first-go/images/cover.jpg"&gt;&lt;/p&gt;
&lt;p&gt;Overall, it&amp;rsquo;s what I expect from a Head First book. It was a perfectly
serviceable introduction to the Go programming language. Although it&amp;rsquo;s a Head
First book, I feel like it treated me like an experienced programmer and
didn&amp;rsquo;t waste a lot of time explaining how an &lt;code&gt;if&lt;/code&gt; expression worked. Unlike
&lt;em&gt;Head First Kotlin&lt;/em&gt; which never got to a lot of things that it had to toss
into &lt;em&gt;Ten Brief Topics in the Appendix&lt;/em&gt;, it felt like it covered all the main
topics that needed to be covered to understand Go. It even includes coverage
of automated testing and a couple of chapters on web apps.&lt;/p&gt;</description><content:encoded><![CDATA[<p><img alt="Head First Go cover" loading="lazy" src="/posts/head-first-go/images/cover.jpg"></p>
<p>Overall, it&rsquo;s what I expect from a Head First book. It was a perfectly
serviceable introduction to the Go programming language. Although it&rsquo;s a Head
First book, I feel like it treated me like an experienced programmer and
didn&rsquo;t waste a lot of time explaining how an <code>if</code> expression worked. Unlike
<em>Head First Kotlin</em> which never got to a lot of things that it had to toss
into <em>Ten Brief Topics in the Appendix</em>, it felt like it covered all the main
topics that needed to be covered to understand Go. It even includes coverage
of automated testing and a couple of chapters on web apps.</p>
<p>Full <a href="https://github.com/llcawthorne/book-notes/blob/main/go/headfirstgo/book-notes.md">book notes</a>.</p>
]]></content:encoded></item><item><title>A Blog Reborn</title><link>https://llcawthorne.github.io/posts/a-blog-reborn/</link><pubDate>Tue, 04 Aug 2026 17:07:11 -0400</pubDate><guid>https://llcawthorne.github.io/posts/a-blog-reborn/</guid><description>&lt;p&gt;So, I haven&amp;rsquo;t been blogging for about ten years. To tell the truth, I spent
all day programming, so when I got off work, I spent my time reading history
or philosophy or anything else not computer related. I can see from my
previous posts that I was experimenting with video and had started reading
Agile Web Development with Rails. Well, I&amp;rsquo;m still a full stack web developer,
so I could do worse than looking back at the web framework that really started
it all. So I will read Agile Web Development with Rails 8 and get a taste of
convention before configuration. That doesn&amp;rsquo;t really fit with the new title
of the blog, but it&amp;rsquo;s still something I want to do, so I will get it done.
I was interested in functional programming and different approaches to web
development 10 years ago, and have never fully explored either, so I&amp;rsquo;m picking
up where I left off with a slightly updated approach.&lt;/p&gt;</description><content:encoded><![CDATA[<p>So, I haven&rsquo;t been blogging for about ten years. To tell the truth, I spent
all day programming, so when I got off work, I spent my time reading history
or philosophy or anything else not computer related. I can see from my
previous posts that I was experimenting with video and had started reading
Agile Web Development with Rails. Well, I&rsquo;m still a full stack web developer,
so I could do worse than looking back at the web framework that really started
it all. So I will read Agile Web Development with Rails 8 and get a taste of
convention before configuration. That doesn&rsquo;t really fit with the new title
of the blog, but it&rsquo;s still something I want to do, so I will get it done.
I was interested in functional programming and different approaches to web
development 10 years ago, and have never fully explored either, so I&rsquo;m picking
up where I left off with a slightly updated approach.</p>
<h2 id="haskell">Haskell</h2>
<p>But let&rsquo;s talk about the new title. It is &ldquo;Senior Software Engineer Learns
Functional Programming.&rdquo; One of the last things I did but never blogged about
was try to learn Haskell. I started with the venerable
<a href="https://haskellbook.com/">The Haskell Book</a>. I read a bit over half and
realized I still couldn&rsquo;t program much of anything in Haskell. This was after
spending previous effort learning functional programming. I learned some
Scala and the syntax of Clojure and felt ineffectual with both aside from
being able to use Scala as a better Java, so that&rsquo;s what led me to Haskell
to learn functional programming right. Well, I still want to do that. I didn&rsquo;t
think I wanted to really, but I spent some time reading <em>Advanced Functional
Programming with Elixir</em> and it made a perfectly good case for why Haskell is
a better programming language and featured a style that was not idiomatic
Elixir but instead very Haskell inspired, and it got me interested again. So
I&rsquo;m not going to start over with The Haskell Book and try to re-learn
programming from first principles. Instead I am going to read
<em>Haskell by Example</em> which is more hands on and dip into the explanations of
<em>The Haskell Book</em> whenever I need more theory. I&rsquo;m also about halfway
through <a href="https://learnyouahaskell.github.io/"><em>Learn You a Haskell</em></a> which
I started over vacation, since I&rsquo;m finding my intuition for working with
linked lists has degraded.</p>
<h2 id="elixir">Elixir</h2>
<p>The subtitle of the blog is &ldquo;With explorations in
Haskell, Elixir, and Clojure&rdquo;. I&rsquo;ve already read two Elixir books on the
basics of the language (reviews upcoming) and I have every intention of
spending more time with Elixir. The books I read didn&rsquo;t even touch on the cool
Actor model and OTP stuff that makes Elixir unique. It&rsquo;s not the best language
for learning to deal with immutable values since it allows you to rebind
variables, which feels a bit like cheating. Sure the data structure itself is
immutable, but you just end up pointing the same variable at the updated
copy. Haskell won&rsquo;t let you get away with that. I understand since the
variables aren&rsquo;t global and are local to the Actors working behind the scenes
it is safe even for concurrent code, but I intend to learn how to deal with
immutable data structures bound once to a name. So I will definitely spend
some time away with Haskell but eventually get back to Elixir. It overlaps
my other goal of trying web frameworks thanks to Phoenix, so my two big
projects (&ldquo;Learn Functional Programming&rdquo; and &ldquo;Try Web Frameworks&rdquo;) actually
meet.</p>
<h2 id="clojure">Clojure</h2>
<p>I have also bought the most recent edition of <em>Programming Clojure</em> and
<em>Clojure Brain Teasers</em> and plan to spend time with it again. I read
<em>Getting Clojure</em> and <em>Living Clojure</em> and <em>Clojure for the Brave and True</em>
years ago, and I felt pretty comfortable with the syntax of the languages and
all the parentheses, but I never was able to use it for much. So after I
spend some time writing code with Haskell, I&rsquo;ll spend some time with Clojure
again and see if I can do anything cool with it. I&rsquo;m a Java developer by trade,
so its position on the JVM feels quite welcome, and once I learn idiomatic
functional coding in a language where I can&rsquo;t back off and call Java code,
maybe it will be accessible to me. I&rsquo;ll probably spend a while with Haskell
and then Elixir first though. I do want to play around with Ring to try
writing my webapps with a minimalist Clojure library.</p>
<h2 id="web-frameworks">Web Frameworks</h2>
<p>Back to the web frameworks though&hellip; I was going to dive into <em>Agile Web
Development with Rails 8</em> and try Ruby. Then I will read through <em>Django 5
by Example</em>. This builds up four sizable projects which I plan to steal.
I don&rsquo;t really like any dynamic language all that much, but I do normally
prefer Python to Ruby for its usefulness with AI and its sensible stance
on one way to do things and lack of going crazy with metaprogramming. I have
every intention of stealing the Django projects to reimplement in other
frameworks to serve my own curiosity. First in Rails, then move on to the next
stop. So then I can read <em>Programming Elixir</em> and <em>Programming Phoenix
Liveview</em> to try doing a web framework. How do I plan to make time for all this?
Well, I think I can wrestle with Haskell for at most 30-60 minutes a day, so
my time beyond that can be spent toying with web frameworks which requires
less cognitive load. After Phoenix, there&rsquo;s other options. I can try writing
a typed API in Haskell with Servant or do something with Yesod. I also wouldn&rsquo;t
mind reading <em>Distributed Services in Go</em> and trying the same projects as
microservices. I happen to like Go for being so simple that you can&rsquo;t hide
anything behind the language. I&rsquo;ve recently read two books on it (reviews
forthcoming) and feel pretty comfortable with it. Aside from that, I wouldn&rsquo;t
mind trying an Angular frontend with a backend in another language, since we
actively use Angular in the new project at work. And I&rsquo;m not opposed to trying
React to just see the difference. Obviously, all JavaScript Single-Page
Applications are more the rage now than old school web frameworks like Rails,
and it fits my interests of seeing different ways to do things. I also have
been toying around with Kotlin and would love an excuse to go back, so I would
like to try Spring with Kotlin for the big enterprise way of doing a web
framework along with Ktor for a lighter weight framework in the same language.
I could code Spring in Java, but I do like not coding in Java when I&rsquo;m away
from work and find Kotlin a fun alternative. Spring and Angular are probably
the most professionally relevant interests that I&rsquo;ll be pursuing, but it&rsquo;s
obvious that I&rsquo;m not trying to maximize for utility. I do really think it
very clever that the new project at work is leaning into a modern Angular UI
with a Java backend instead of using any of the trainwreck front end projects
available on the Java platform. JSF was bad enough to make me never want to
see a Java frontend again. Anyway, that&rsquo;s as far as I&rsquo;ve thought
these two projects through, but if I make it that far with them, I&rsquo;ll have
a better idea of what I want to do next. Put together, they should keep me
busy for a while, and assuming I don&rsquo;t give up blogging for ten years or so
again, it will give me something to blog about.</p>
<h2 id="why-now">Why Now?</h2>
<p>Why do I think blogging will catch on this time? Well, what made me give up
my side projects and blogging before was primarily being burnt out on spending
all day coding at work to get off and do more of it at night. Now that my kid
is older and I&rsquo;ve got more time to focus on personal development, I figured
why not fire the blog back up so I can shout my book reviews and whatnot into
the void. Aside from that, work has us leaning a lot more on AI for writing
code these days, so it&rsquo;s as good an excuse as any to keep my own skills sharp
with some side projects. I&rsquo;ve also been rather good lately at putting my mind
to stuff and keeping it going.
I lost about 40 pounds and run 10K every day I don&rsquo;t lift weights. So maybe
I can stay focused on something intellectual too. Also, I still run over an
hour most days a week, which gives me a great opportunity to listen to a
history audiobook or fictional work, so it isn&rsquo;t like I&rsquo;m giving up my hobby
reading. I&rsquo;m just cutting into other spare time with a new project. As a busy
dad, I really get 1-2 hours of free time that I&rsquo;m not working out most days,
so it&rsquo;s easy to spend 30-60 minutes on Haskell and the remainder if there is
any on something else. Or so I think. We&rsquo;ll see if this blog rebirth lasts.
So far, I&rsquo;ve read about 8 technical books that I&rsquo;ll end up posting reviews
for, so I already have more content than I had last time before
discontinuing it, and it seems something fun to do. I&rsquo;ve already been reading
a minimum of 30 minutes a day for over a year, and often for hours, so I&rsquo;m just
going to read different stuff.</p>
<p>I didn&rsquo;t put this in the first draft, because it feels kinda silly to get
inspired by a book about a famous person, but there&rsquo;s also another thing
that motivated me to do more programming on the side. I listened to the
audiobook on Steve Jobs while I was running. Really, I don&rsquo;t care that much
about Steve Jobs and still don&rsquo;t after listening to his life story. He
definitely had vision and did good things with Apple, and I&rsquo;m writing this
on a Mac so can&rsquo;t complain about the results, but I consider him more of
a visionary businessman than a real hacker. I liked Isaacson&rsquo;s biography
of Benjamin Franklin and figured Steve Jobs would be another accessible work
by him for my runs. But you can&rsquo;t read about the founding of Apple without
encountering Woz. A true engineer that would&rsquo;ve gladly made computers and
gave them away, because he loved tinkering with circuitboards. I don&rsquo;t really
care about circuitboards either; I&rsquo;ve always been a software guy. But being
exposed to a story with that type of passion reminded me I used to be
passionate about computers.</p>
<p>I&rsquo;ve always had a bit of a love-hate relationship with Apple. I still have
Linux on my desktop PC and am a proud member of the Columbia Linux User&rsquo;s
Group despite not attending meetings all that often.
The early Apple computers were toys with no CLI and one button mice
because multiple buttons are confusing. But after OS X was reborn with BSD
under the hood and a full fledged terminal, I found that having a computer
that mostly worked with the default configuration and
actually looked pretty good made it easier for me to focus
on writing code and not spend so much time tinkering around with Linux. I
learned from the Steve Jobs book that the first Macs were expandable
because Woz thought people should be able to tinker with their own computers.
Maybe I would&rsquo;ve liked those better than the Macs at school.</p>
<p>Anyway, back to passion, I didn&rsquo;t take my computer apart and hide all the
pieces because I thought it would be faster when I put it back together
hours later. I did it because I wanted to learn how a computer was put
together (I didn&rsquo;t know I wasn&rsquo;t really a hardware guy back then; I honestly
prefer buying them off the shelf now).
I also didn&rsquo;t learn C and relational databases because I thought they would be
profitable (although database knowledge is the gift that keeps on giving).
I loved solving problems in C in the middle of the night on my hand-me-down
computer. I didn&rsquo;t found an ISP in the 90&rsquo;s to get rich quick,
I founded it to have fast Internet access and to have cool problems to
figure out. Likewise, I didn&rsquo;t make straight A&rsquo;s in school because I
expected it to help my
job prospects. No one cares about my GPA. I loved the material! It was
fascinating to learn about algorithms, operating systems, and, after
programming so long, compilers. Somewhere along the way, it just became work
like any other job. So it&rsquo;s a combination of factors: having more free time
now that my kid&rsquo;s a little older, work leaning harder on AI for the actual
code these days so I want to keep my own chops sharp on the side, a refound
passion for programming inspired by a rather unlikely source, and the fact
I&rsquo;ve been reading every day over a year anyway, so why not make it technical.
I still don&rsquo;t know functional programming beyond how to apply a good
map and filter, and I still haven&rsquo;t tried a lot of different web frameworks.
They&rsquo;re all likely to be better than the Java EE/Spring hybrid monstrosity
that I work on most of the time. Almost anything beats JSF.</p>
<p>And as an aside, this will probably be my last time trying to learn
&ldquo;functional programming&rdquo;. If I try to learn the secrets of Haskell again
and bounce off, I am just going to adopt Go as my programming language of
choice and write lots of simple procedural code with structs and <code>err</code>
checks every other line. As an old school C hacker and Perl scripter before
they bolted on OOP, it feels quite natural to write straightforward procedural
code, but I&rsquo;m trying to work outside my comfort zone even if I think the
benefits of functional programming might be overpromised.</p>
<p>But I really kinda understood the point of functional programming with
<em>Advanced Functional
Programming with Elixir</em>, and all those <code>err</code> checks in Go grated at
my nerves, so the beauty of being able to chain a bunch of calls together then
deal with errors or results at the end was quite appealing to me. Monads
aren&rsquo;t really the Elixir way though. Your average Elixir programmer would
do some simple pattern matching to catch <code>:err</code> and deal with it instead, but
<em>Advanced Functional Programming with Elixir</em> featured a Haskell inspired
functional programming library and monads. And while I wasn&rsquo;t ultimately
convinced of the utility of the Reader or Effect monads (I&rsquo;m open to learning
more about those in Haskell, and I will have to anyway if I spend time with
it), I really liked Maybe and liked Either even more. Even Java has Option,
but Either is a lot more useful. Plus parallel validations with Applicative
were kinda cool. They weren&rsquo;t a reason to re-learn programming, but I&rsquo;ll take
them along with my Either and roll with it a bit.</p>
<h2 id="conclusion">Conclusion</h2>
<p>So that&rsquo;s it. The blog is reborn. I&rsquo;ve got one project that meshes with the
title of learning functional programming. I have another of trying web
frameworks that has some limited overlap built in and picks up where the
blog left off. I transferred my old posts over and rebuilt the site in Hugo
and moved over what I could from the old Jekyll files. And I&rsquo;ve written a
very long coming back
post plus already have a stash of book reviews in my Obsidian. So I guess
I&rsquo;m back and doing this for now and we&rsquo;ll see where it goes. I may get
tired of posting updates here and just read the books, but I like having
somewhere to collect my thoughts and review what I read.</p>
]]></content:encoded></item><item><title>O'Reilly Spring Framework Essentials</title><link>https://llcawthorne.github.io/posts/oreilly-spring-framework-essentials/</link><pubDate>Mon, 26 Jun 2017 00:00:00 +0000</pubDate><guid>https://llcawthorne.github.io/posts/oreilly-spring-framework-essentials/</guid><description>&lt;p&gt;This time I&amp;rsquo;m working on reinforcing some of the Spring and Spring Boot
knowledge I&amp;rsquo;ve picked up from other videos, while seeing if I can learn
a couple of new tricks while at it. I&amp;rsquo;m watching
&lt;a href="https://www.safaribooksonline.com/library/view/spring-framework-essentials/9781491942680/"&gt;Spring Framework Essentials&lt;/a&gt; through my Safari Books Online membership.
It&amp;rsquo;s presented by Ken Kousen, who often hosts the Groovy Podcast. He has a
series of three Groovy videos in Safari Books Online that I wouldn&amp;rsquo;t mind
going through sometime in the future. The video series runtime is 5 hours,
14 minutes and it has a five star rating from 35 reviewers. Not bad, let&amp;rsquo;s
see what it covers.&lt;/p&gt;</description><content:encoded><![CDATA[<p>This time I&rsquo;m working on reinforcing some of the Spring and Spring Boot
knowledge I&rsquo;ve picked up from other videos, while seeing if I can learn
a couple of new tricks while at it.  I&rsquo;m watching
<a href="https://www.safaribooksonline.com/library/view/spring-framework-essentials/9781491942680/">Spring Framework Essentials</a> through my Safari Books Online membership.
It&rsquo;s presented by Ken Kousen, who often hosts the Groovy Podcast.  He has a
series of three Groovy videos in Safari Books Online that I wouldn&rsquo;t mind
going through sometime in the future.  The video series runtime is 5 hours,
14 minutes and it has a five star rating from 35 reviewers.  Not bad, let&rsquo;s
see what it covers.</p>
<p>So, these videos are going to focus on the core Spring Framework.  So we
won&rsquo;t be getting back into Spring Data or even Spring MVC in this video
series.  It says that it will talk a little about Spring Boot, since that&rsquo;s
the general way to get projects started these days.  &ldquo;One thing that you&rsquo;ll
notice about the Spring Framework, is that they never met a class or package
name too long.&rdquo;  Tell me about it.  Spring makes you appreciate autocomplete.
He uses gradle to manage projects, which is fine.  Maven or gradle are both
fine options.</p>
<p>He did a fine demonstration of basic injection in
XML, annotations, and Java config setup and quick intro to aspect
oriented programming that included an example of the <code>@Around</code> advice.  Then
he gave a quick introduction to Spring testing.  Finally someone that doesn&rsquo;t
ignore testing.  It turns out you can annotate you test class with
<code>@RunWith(SpringJUnit4ClassRunner)</code> to have Spring aware tests, and you
can add the <code>@ContextConfiguration(classes = AppConfig.class</code> so that you
have a cached ApplicationContext shared between tests in the class and the
ability to <code>@Autowire</code> any of your beans.  You can even <code>@Autowire</code> an
<code>ApplicationContext ctx</code> variable to inject a reference to your
ApplicationContext to use in tests to fetch beans you don&rsquo;t autowire.  The
fact that <code>@ContextConfiguration</code> takes a classes argument lets you have a
different configuration class for tests than the running application if
necessary.  You can also add the <code>@Transactional</code> annotation to your test
class to make all your tests occur in a transaction that gets rolled back
after test completion.  His toy app that he used to demonstrate early
principles didn&rsquo;t have any database interaction to show-off transactional
tests, but this is the part of the course that he switches from a toy app
to something a little more complicated.  He also mentions that the Spring
pet-clinic demo app makes good use of transactional tests.</p>
<p>The new application has a Service and a Repository interface.  Instead of
using Spring Data, he does all the database operations with an in-memory
and a JDBC implementation.  Everything is marked <code>@Transactional</code> at the
Service level.  He had to make a &ldquo;transactionManager&rdquo; Bean and use an
<code>@EnableTransactionManagement</code> on his Configuration class, neither of which
I recall being required when doing a Spring Boot app with <code>@Transactional</code>.
The JDBC is using the Spring JDBC Template and is a lot cleaner than straight
JDBC.  The JDBC Template does a lot of work for you.  For example, the
following one-liner works for getting a count: <code>int rowCount =  this.jdbcTemplate.queryForObject(&quot;select count(*) from t_actor&quot;), Integer.class);</code>  I like the way he looks up what he is talking about in the
online API, the same way you likely would when programming with the various
API elements.  He shows off using &ldquo;test&rdquo; and &ldquo;prod&rdquo; profiles to differentiate
between an H2 in-memory database and an Apache data connection pool backed
by MySQL.  Each repository method with the JDBC Template ends up being two
to four lines long, depending upon what he&rsquo;s try to do.  Pretty simple, but
not as simple as not defining implementation methods with Spring Data JPA.</p>
<p>Yay!  More testing.  This time we&rsquo;re testing repositories.  Just set the
annotations on the test class and annotate the test profile, then autowire
the repository and you&rsquo;re good to go.  Each test is transactional, so they
roll back changes at the end of each test.  He uses Hamcrest matchers, so
he can make assertions like <code>assertThat(accounts.size(), is(3));</code>, which
flows a bit better than standard assertEquals.  He points out that since
he is using gradle he can show the really cool gradle test report.  The
tests he ran were all quick, even with firing up and setting up the
in-memory database.  First one took half a second, but the all six of them
took less than a second total.  He succeeded in exercising all his
repository methods and making sure they worked as expected.</p>
<p>I was wrong that we weren&rsquo;t going into Spring Data.  He reimplements his
repository using Spring Data JPA for the next project.  Spring Data JPA
repositories are just interfaces.  You get queries generated for free based
upon how you name the methods in the interfaces.  You can also use the
<code>@Query</code> annotation above a method in the interface to give it a custom
query if the autogenerated language can&rsquo;t handle what you&rsquo;re after.  He defined
the JpaVendorAdapter and LocalContainerEntityManagerFactoryBean manually in
the Java Spring configuration file, which normally weren&rsquo;t require with
Spring Boot.  It&rsquo;s interesting to see how this is all done by hand, and it
isn&rsquo;t that much in total lines of configuration.  He didn&rsquo;t use the feature
of Spring Data JPA to allow repository autogeneration of methods and just
defining an interface.  Instead he defined a JpaAccountRepository that
implemented its various methods directly through an EntityManager.  He does
use <code>@PersistenceContext</code> annotation to inject his EntityManager.  Most of
the methods now are one or two lines long.  He did have to add JPA
annotations to his entity class, but most of them defaulted through good
name selection for class and fields.  Only <code>@Entity</code> on the class and <code>@Id</code>
on the primary key field actually needed to be added to the domain object.
He shows that you can use the same service with the JPA repository as was
used with the JDBC Template repository, since he designed the methods to
take the same arguments.  He uses the same tests also, which makes sense as
the interface and expected outputs are the same.</p>
<p>I forgot to mention it earlier, but this presenter uses IntelliJ for
everything.  Always nice to see!  Oh, he was just using JPA in the last
project.  The next project is where he&rsquo;s adding in Spring Data to get
the free implementations of DAO methods.  So, it turns out he uses Spring
Data for the last 12 minute segment of the presentation, and then switches
to showing the same app with Spring Boot for the last 15 minutes of the
presentation.  The app keeps getting simpler each time he introduces
more Spring features.  He actually extended JpaRepository for his
repository, where I am more accustomed to seeing CrudRepository or
PagingAndSortingRepository extended.  JpaRepository extends both.  He had
to change the method names in his service and tests to match the ones
freely given by having an interface extend on of the Spring Data interfaces,
but got to delete a lot of code that was the repository class implementation
and previous repository interface which was more complicated.  Interesting
to see that his tests run quicker now too, taking a little under 0.4 seconds.
He&rsquo;s still using an H2 in-memory database for testing and setting it up
with the same sql scripts.  He points out that all his earlier work really
was unnecessary.  The final project is to show how much of his configuration
he can get rid of also by using Spring Boot.  It&rsquo;s still interesting to
know how to do it by hand, since everything we&rsquo;ve seen is still happening
under the hood in Spring Boot.</p>
<p>So, at the end, he claims that a Spring Boot focused course is coming.  I
don&rsquo;t see it as available yet.  He had mentioned earlier this video course
would be the start of a series.  I really enjoyed Ken&rsquo;s presentation, and
would definitely watch more in this series by him.  It was a neat change
seeing Spring used for non-web apps.  I hope in the future videos he shows
off Spring MVC though, because Spring makes some nice web apps too.  He
recommends the book Spring Boot in Action at the end, but I found that book
fairly worthless.  The source code for it didn&rsquo;t match up with what was
described in the text.  Maybe now that I actually have a grasp on some of
this stuff, it would be useful and I could figure out why the sample source
code and the text don&rsquo;t match up.  Anyway, despite his poor book
recommendation at the end, I really enjoyed this video series.  It&rsquo;s worth
a watch if you&rsquo;re looking for something to view with your Safari Books Online
membership.</p>
]]></content:encoded></item><item><title>Udemy - Spring Boot Intro</title><link>https://llcawthorne.github.io/posts/udemy-spring-boot-intro/</link><pubDate>Thu, 22 Jun 2017 00:00:00 +0000</pubDate><guid>https://llcawthorne.github.io/posts/udemy-spring-boot-intro/</guid><description>&lt;p&gt;I figured since I am a professional Java programmer that I might as well
spent some time getting familiar with some Java technologies that I don&amp;rsquo;t
get to use at work. With this in mind, I purchased Udemy&amp;rsquo;s &amp;ldquo;Spring Boot
Intro&amp;rdquo; course for $10 when they had a sale.&lt;/p&gt;
&lt;p&gt;This course moved a lot quicker than the last course I took from Udemy.
It covered basic dependency injection in Spring in probably an hour or less,
where the last class focused on dependency injection fundamentals for the
entire time. I appreciated the faster pace, as there&amp;rsquo;s a lot of stuff
to cover with Spring Boot. It handles autoconfiguring all the main projects
that make up Spring&amp;hellip; Spring MVC, Spring Rest, Spring Data, Spring Security,
etc.&lt;/p&gt;</description><content:encoded><![CDATA[<p>I figured since I am a professional Java programmer that I might as well
spent some time getting familiar with some Java technologies that I don&rsquo;t
get to use at work.  With this in mind, I purchased Udemy&rsquo;s &ldquo;Spring Boot
Intro&rdquo; course for $10 when they had a sale.</p>
<p>This course moved a lot quicker than the last course I took from Udemy.
It covered basic dependency injection in Spring in probably an hour or less,
where the last class focused on dependency injection fundamentals for the
entire time.  I appreciated the faster pace, as there&rsquo;s a lot of stuff
to cover with Spring Boot.  It handles autoconfiguring all the main projects
that make up Spring&hellip;  Spring MVC, Spring Rest, Spring Data, Spring Security,
etc.</p>
<p>This author made it really hard to code along with him.  He did things
like restart a project with unknown initializr settings in between
videos.  He also copied and pasted a lot of code, so you couldn&rsquo;t really
type along with him.  As long as you don&rsquo;t mind pausing and typing
something in, it wasn&rsquo;t unworkable, but it got a little old.  I ended up
checking out his repo of code samples and following along with them.
He does have exercises at the end of each section, which are a good
chance to code some stuff up on your own.  He doesn&rsquo;t mention specifically
when he changes projects from the repo either, so it&rsquo;s a little hit and
miss making sure you&rsquo;re looking at the right code that he&rsquo;s working on.</p>
<p>One nice thing is this guy used IntelliJ instead of Eclipse.  He admitted
that you need the paid for version to work with Spring, but just told
people to sign up for the 30 day trial.  Fortunately, I still have my student
license, so I had all the features to play along.  It might be annoying to
people that have already done the IntelliJ trial, since it makes it harder
to follow along.  Of course, he&rsquo;s pretty hard to follow along with as it is,
so using STS or Eclipse wouldn&rsquo;t be that much worse.  Anyway, I was excited
at first that he used IntelliJ, but then he switched to Eclipse STS halfway
through the videos.  I kept following along in IntelliJ.</p>
<p>I liked the Spring Boot way of doing apps.  It felt like convention over
configuration brought to the Java world, the way it autoconfigures so much
stuff based upon what it finds loaded in your class path.  I really liked
Spring Data, which allows you to pair up standard JPA entities with
Repository interfaces that automatically generate the implementation with
queries based upon the names of the method defined in your interface.<br>
For example, if you make a method called <code>findByLastName(String lastName)</code>
in your interface, you get the query you would expect for free.  The
instructor didn&rsquo;t go into this, but it also works with QueryDSL predicates
to fill in the queries, which is pretty cool since I use QueryDSL at work. He
also showed how to do everything by hand with JDBC, but I liked the JPA
approach better.  He also showed that you can drop in mongo DB and swap
out Entity annotation for Document pretty easily in an app with very little
changes.  It was a weird choice doing JPA backed by a Microsoft SQL Server
database, and since I didn&rsquo;t feel like signing up for an Azure trial, I
just kept using H2.</p>
<p>I really liked the Dev Tools with live reload.  He showed that you have to
change a few settings in IntelliJ.  In the registry you check
compiler.automake.allow.when.app.running and in the
Preferences-&gt;Build, Execution, Deployment-&gt;Compiler you check the
Build project automatically.  Then you install a browser extension from
<a href="http://livereload.com/extensions/">http://livereload.com/extensions/</a> and it will reload automatically when
anything changes in your code. It isn&rsquo;t that much work really to save
hitting refresh all the time.  He doesn&rsquo;t use that in most of his projects,
but I kept it turned on in all the ones I did by hand.</p>
<p>I like Spring Security, but found the course&rsquo;s presentation of it to be
a little light.  It does explain how you get free security headers, some XSS
prevention, and CSRF tokens just by including Spring Security, and in his
example he works up to a custom login form backed by a database (this time
MySQL) of users, but he stores the passwords in plain text, so his app
wouldn&rsquo;t be that useful a model to look at if I ever wanted to do this for
real.</p>
<p>The REST presentation was more thorough than it needed to be.  It seems
like every talk about REST has to go over what the different status codes
mean first thing.  Why not just link out to HTTP Status Cats website.
I want to know how he gets his JSON formatted so pretty in the browser.
I&rsquo;m sure it&rsquo;s a plugin, but it isn&rsquo;t one I already have.  Oh, he finally
mentioned what it is during the REST videos.  &ldquo;JSON Viewer&rdquo; extension for
Chrome.  Nice.  Anyway, I thought REST frameworks were easy to setup when
we were doing them the hard way (RestController annotations and services),
but it turns out you can get rid of your controllers and services and
directly expose your repo through a default build REST API if you don&rsquo;t
need a lot of custom logic.  There&rsquo;s even a built in HAL Browser for
discovery and interaction with the API, if you choose to include it.
HAL Browser dependency comes from org.springframework.data and not
org.springframework.boot.  That tripped me up for a minute in the exercises.</p>
<p>For the final series of lectures, he expects you to work along with him
starting from an initial setup.  We&rsquo;ll see if this works any better&hellip;  Nope!
He still does a lot of stuff off-screen between videos.  Anyway, the final
project is a blogging website.  It uses bootstrap to look good, thymeleaf
for the templates, spring data jpa for the database interaction, and
spring security to enforce editing only by those with admin level privileges.
I still need to read the docs on thymeleaf templates to feel like I know
much about them, since he always provides the templates and doesn&rsquo;t explain
much.  They look pretty simple.  Extra attributes to HTML tags causes you
to override content that is present in the source and do other modifications.
Like <code>&lt;span sec:authentication=&quot;name&quot;&gt;Guest&lt;/span&gt;</code> will default to Guest,
but will override that value with the name of whoever is currently
authenticated.  Judging from the upcoming titles, he&rsquo;s going to throw in
some validation, which is a topic he hasn&rsquo;t covered in the previous sections.</p>
<p>I couldn&rsquo;t get his instructions for customizing validation messages to work
at all.  I got validation working pretty good with the default error
messages at least.  He claims you just need to put your custom messages
in a messages.properties file, but I did that and they didn&rsquo;t get picked up.
I assume I have to do something to get it to look in message.properties.
Everyone on stack overflow with a related problem seems to be running WARs,
so those questions don&rsquo;t seem to apply to my setup.  I&rsquo;ll dig in the
documentation later and see what&rsquo;s going on.</p>
]]></content:encoded></item><item><title>AWDWR 5.1 - 03-05 - Theory</title><link>https://llcawthorne.github.io/posts/awdwr51-03-05-theory/</link><pubDate>Mon, 05 Jun 2017 00:00:00 +0000</pubDate><guid>https://llcawthorne.github.io/posts/awdwr51-03-05-theory/</guid><description>&lt;p&gt;Chapters 3 through 5 focus on a little bit of theory before we get to
building the tutorial application.&lt;/p&gt;
&lt;h3 id="chapter-3---the-architecture-of-rails-applications"&gt;Chapter 3 - The Architecture of Rails Applications&lt;/h3&gt;
&lt;p&gt;Chapter 3 jumps into explaining MVC.
It&amp;rsquo;s a pretty simple concept. MVC stands for Model, View, and Controller.
The &lt;em&gt;model&lt;/em&gt; is responsible for the state of the application, often the data
you store in a database. It&amp;rsquo;s also more than data; it enforces the business
rules that apply to your data. The model is both a gatekeeper and a data
store. The &lt;em&gt;view&lt;/em&gt; is responsible for generating some type of user
interface. The view&amp;rsquo;s job is done once the data is displayed.
Multiple possible views of the same data are a common case. The
&lt;em&gt;controller&lt;/em&gt; orchestrates the application. Controllers receive events from
the outside world, interact with the model, and display the appropriate
view. The book provides a simple diagram:&lt;/p&gt;</description><content:encoded><![CDATA[<p>Chapters 3 through 5 focus on a little bit of theory before we get to
building the tutorial application.</p>
<h3 id="chapter-3---the-architecture-of-rails-applications">Chapter 3 - The Architecture of Rails Applications</h3>
<p>Chapter 3 jumps into explaining MVC.
It&rsquo;s a pretty simple concept.  MVC stands for Model, View, and Controller.
The <em>model</em> is responsible for the state of the application, often the data
you store in a database.  It&rsquo;s also more than data; it enforces the business
rules that apply to your data.  The model is both a gatekeeper and a data
store.  The <em>view</em> is responsible for generating some type of user
interface.  The view&rsquo;s job is done once the data is displayed.
Multiple possible views of the same data are a common case.  The
<em>controller</em> orchestrates the application.  Controllers receive events from
the outside world, interact with the model, and display the appropriate
view.  The book provides a simple diagram:</p>
<p><img alt="MVC" loading="lazy" src="/posts/awdwr51-03-05-theory/images/mvc-diagram.png"></p>
<p>There&rsquo;s a fine introductory article on
<a href="https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller">Wikipedia</a>
if the concept is new to you.  One of the main advantages is that each
concept or action can be expressed in a single, well-known place.  Like
many modern web frameworks, Rails is designed with MVC in mind.  Rails
first sends your request to a router, which then maps it to a method of a
controller (called an <em>action</em>), and then the action looks at data in the
request to decide how to interact with the model and ultimately it prepares
information for the view, which renders the result.</p>
<p><img alt="Rails MVC" loading="lazy" src="/posts/awdwr51-03-05-theory/images/rails-mvc.png"></p>
<p>The request contains a path (<code>/line_items?product_id=2</code>) and a method
(GET, POST, PUT, PATCH, DELETE).  By default rails takes the first part of
the path, <code>line_items</code>, as the controller name and the <code>product_id</code> as the
ID of a product, which it passes to the <code>create()</code> method of a
<code>LineItemsController</code> if we assume this is a POST request.  Different types
of request are routed to different methods of the controller.</p>
<p>Rails handles a lot of the low level details of an MVC app, so you can focus
on the core application logic.  One example of this is in its ORM (object-
relational mapping) libraries which map database tables to classes.  If you
have a class called <code>Order</code>, you know it maps to a database table called
<code>orders</code>.  The <code>Order</code> object has methods to set all the data fields in the
<code>orders</code> table.  The Rails classes also wrap our database tables with
class-level methods that perform table-level operations.  For example, you
might want to look up an <code>Order</code> by ID.  Code to do so might look like:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ruby" data-lang="ruby"><span class="line"><span class="cl"><span class="n">order</span> <span class="o">=</span> <span class="no">Order</span><span class="o">.</span><span class="n">find</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="nb">puts</span> <span class="s2">&#34;Customer </span><span class="si">#{</span><span class="n">order</span><span class="o">.</span><span class="n">customer_id</span><span class="si">}</span><span class="s2">, amount=$</span><span class="si">#{</span><span class="n">order</span><span class="o">.</span><span class="n">amount</span><span class="si">}</span><span class="s2">&#34;</span>
</span></span></code></pre></div><p>Or you could have a class level method that searches by a where clause and
returns a collection of objects:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ruby" data-lang="ruby"><span class="line"><span class="cl"><span class="no">Order</span><span class="o">.</span><span class="n">where</span><span class="p">(</span><span class="nb">name</span><span class="p">:</span> <span class="s1">&#39;dave&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">each</span> <span class="k">do</span> <span class="o">|</span><span class="n">order</span><span class="o">|</span>
</span></span><span class="line"><span class="cl">  <span class="nb">puts</span> <span class="n">order</span><span class="o">.</span><span class="n">amount</span>
</span></span><span class="line"><span class="cl"><span class="k">end</span>
</span></span></code></pre></div><p>In addition to accessing field values, you can set values via the object
and then save it to the database:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ruby" data-lang="ruby"><span class="line"><span class="cl"><span class="no">Order</span><span class="o">.</span><span class="n">where</span><span class="p">(</span><span class="nb">name</span><span class="p">:</span> <span class="s1">&#39;dave&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">each</span> <span class="k">do</span> <span class="o">|</span><span class="n">order</span><span class="o">|</span>
</span></span><span class="line"><span class="cl">  <span class="n">order</span><span class="o">.</span><span class="n">pay_type</span> <span class="o">=</span> <span class="s2">&#34;Purchase order&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="n">order</span><span class="o">.</span><span class="n">save</span>
</span></span><span class="line"><span class="cl"><span class="k">end</span>
</span></span></code></pre></div><p>So an ORM layer maps tables to classes, rows to objects, and columns to
attributes of those objects.  Class methods are used to perform table-level
operations, and instance methods perform operations on individual rows.
<em>Active Record</em> is the ORM layer provided by Rails.  It relies on
convention over configuration and starts with sensible defaults to minimize
manual configuration by developers.</p>
<p><em>Action Pack</em> is the part of Rails that supports the views and controllers.
At its simplest, the view is a chunk of HTML code that displays some static
content, but you normally want dynamic content generated by templates.  Rails
offers templates in three flavors:</p>
<ol>
<li>Embedded Ruby (ERB), which is the most common, embeds snippets of Ruby
within an HTML document</li>
<li>ERB used to construct JavaScript fragments on the server to execute
in the browser to form the view</li>
<li>an XML builder to construct XML documents using Ruby code.</li>
</ol>
<p>The controller acts as the logical center of an application, coordinating
interaction among the user, the views, and the model.  It&rsquo;s responsible
for routing URLs to actions, it manages caching, it manages helper modules,
and it also manages sessions.  The way Rails handles most of the interaction
behind-the scenes makes controller code easy to develop and maintain.</p>
<h3 id="chapter-4---introduction-to-ruby">Chapter 4 - Introduction to Ruby</h3>
<p>All of Chapter 4 is focused on a quick review of Ruby.  I&rsquo;d recommend
a refresher at <a href="https://learnxinyminutes.com/docs/ruby/">learnxiyminutes</a>
if your Ruby is a little rusty or checkout the
<a href="http://www.zenspider.com/ruby/quickref.html">zenspider quickref</a>.<br>
The one thing those don&rsquo;t cover that is
relevant is YAML (YAML Ain&rsquo;t Markup Language).  YAML is used to define
configuration of things in Rails.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">development</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">adapter</span><span class="p">:</span><span class="w"> </span><span class="l">sqlite3</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">database</span><span class="p">:</span><span class="w"> </span><span class="l">db/development.sqlite3</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">pool</span><span class="p">:</span><span class="w"> </span><span class="m">5</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">timeout</span><span class="p">:</span><span class="w"> </span><span class="m">5000</span><span class="w">
</span></span></span></code></pre></div><p>Indentation is import in YAML, and the above snippet defines four key-value
pairs.</p>
<h3 id="chapter-5---the-depot-application">Chapter 5 - The Depot Application</h3>
<p>Chapter 5 focuses on the design of the application that is being built in
the upcoming tutorial chapters.  We&rsquo;re going to build a basic bookstore,
based upon the <a href="https://pragprog.com/">Pragmatic Bookshelf</a> website.  It
approaches the problem from a mindset of incremental development and starts
out from basic back-of-the-napkin style sketches of functionality.  It
points out that Ruby on Rails shines for this style of development, because
it doesn&rsquo;t heavily penalize changing your mind about something
mid-development.  It also points out that we&rsquo;ll be building tests as we go.
Yay!</p>
<p>To start with, we want an outline of how the application will work at a
high level.  We identify two roles: the <em>buyer</em> and the <em>seller</em>.  The
buyer browses for products, selects some to purchase, and creates an order.
The seller uses the application to maintain a list of products to sell, to
determine order awaiting shipment, and to mark orders shipped.  Here is a
first sketch of the buyer flow:</p>
<p><img alt="buyer flow" loading="lazy" src="/posts/awdwr51-03-05-theory/images/buyer-flow.png"></p>
<p>It&rsquo;s a pretty traditional and simple flow.  There&rsquo;s also the seller flow:</p>
<p><img alt="seller flow" loading="lazy" src="/posts/awdwr51-03-05-theory/images/seller-flow.png"></p>
<p>In both cases, we&rsquo;re not overspecifying things we are unsure about, like
details of the shipping method or payment methods.  We also need to think
about what the data is going to look like:</p>
<p><img alt="data" loading="lazy" src="/posts/awdwr51-03-05-theory/images/data-model.png"></p>
<p>There&rsquo;s obviously some questions left, like what goes in cart, but this is
enough to get started, and we can figure out the other details once we&rsquo;re
in a better position of knowledge later after we&rsquo;ve started.  With these
diagrams in hand to get us started and an imaginary customer to show our
progress, we&rsquo;re ready to get started on the book&rsquo;s tutorial application.</p>
]]></content:encoded></item><item><title>Misc Reading</title><link>https://llcawthorne.github.io/posts/misc-reading/</link><pubDate>Fri, 02 Jun 2017 00:00:00 +0000</pubDate><guid>https://llcawthorne.github.io/posts/misc-reading/</guid><description>&lt;p&gt;I&amp;rsquo;m still going back to finish my Agile Web Development with Rails 5.1
series. I finished reading the main project in the book a while back
now. I just haven&amp;rsquo;t made time with the computer to create the demo
project, and I want to have it in a repo to upload and talk about
the code a little. I didn&amp;rsquo;t read the reference chapters, since
they were still incomplete. I think I&amp;rsquo;ll read Agile Web Development
with Rails 5 on Safari Books in its entirety, and that will give me a
good perspective to see what changes with the project in the Rails 5.1
version of the book. The only thing that I noticed so far that was 5.1
specific is the ActionCable Websocket stuff they throw in, so that if a price
changes on the backend it pushes the update to customers. Pretty neat
to see Websockets used for something so small, instead of big examples
of chat servers and what not like you commonly see.&lt;/p&gt;</description><content:encoded><![CDATA[<p>I&rsquo;m still going back to finish my Agile Web Development with Rails 5.1
series.  I finished reading the main project in the book a while back
now. I just haven&rsquo;t made time with the computer to create the demo
project, and I want to have it in a repo to upload and talk about
the code a little.  I didn&rsquo;t read the reference chapters, since
they were still incomplete.  I think I&rsquo;ll read Agile Web Development
with Rails 5 on Safari Books in its entirety, and that will give me a
good perspective to see what changes with the project in the Rails 5.1
version of the book.  The only thing that I noticed so far that was 5.1
specific is the ActionCable Websocket stuff they throw in, so that if a price
changes on the backend it pushes the update to customers.  Pretty neat
to see Websockets used for something so small, instead of big examples
of chat servers and what not like you commonly see.</p>
<p>I&rsquo;ve read several things since finishing Agile Web Development with Rails 5.1.
One I might dedicate multiple blogposts to: &ldquo;Practical Object-Oriented Design
in Ruby&rdquo;.  It was really good, and I highlighted large sections of the book
that are worth talking about.  Some of the stuff I had seen before in places
like &ldquo;Clean Code&rdquo; and in my Software Engineering class, but it had a lot of
good direct advice on designing things properly from an object-oriented
perspective.  The examples were in Ruby, but it didn&rsquo;t linger much on
language specifics.</p>
<p>Speaking of Ruby, I&rsquo;ve been refreshing my Ruby skills after spending
time with the Agile Web Development in Rails 5.1 book and before
delving into some other Rails books (primarily Hartl&rsquo;s
<a href="https://www.railstutorial.org/">&ldquo;Ruby on Rails Tutorial: Learn Web Development with Rails&rdquo;</a>
which I read in an old version and the new rough cut of
<a href="https://www.safaribooksonline.com/library/view/the-rails-5/9780134657691/">&ldquo;The Rails 5 Way&rdquo;</a>
).  I re-read the 10th anniversary edition of
<a href="https://pragprog.com/book/ruby4/programming-ruby-1-9-2-0">the Pickaxe</a>
, since I had a hardcopy of
it on the shelf.  That link takes you to the fourth edition, rather
than the 10th anniversary edition.  It was focused on Ruby 1.9.
Then I re-read
<a href="http://poignant.guide/">Why&rsquo;s (Poignant) Guide to Ruby</a>.
It&rsquo;s a little dated, but still relevant.  And finally
for something a little more up to date, I started reading the latest
edition of <a href="http://therubyway.io">&ldquo;The Ruby Way&rdquo;</a>.</p>
<p>I like the Pickaxe best for a fast moving
introduction to the language that is worth a couple of reads, paired with
detailed chapters on various topics relating to Ruby in its setting.
Why&rsquo;s guide is classic, and gets into some neat metaprogramming topics,
although it has a lot of charmingly weird stuff in it and not so much code.
&ldquo;The Ruby Way&rdquo; is starting to feel like a bit of a slog to make it through
reading from cover to cover.  It feels like it would be a handy desk
reference, but from a reader&rsquo;s perspective, do I really want to read
how to build a GUI using five different libraries back-to-back.  It was
good for establishing a comparison of several different ways to do GUI
stuff at least.  I think I&rsquo;ll try out Shoes.  Anyway, so now I feel
like I know Ruby again, and I&rsquo;ve been using it for
<a href="http://www.codewars.com/">Code Wars</a> to get lots of practice with
toy problems.</p>
<p>Oh, I&rsquo;ve also signed up for a MOOC that teaches Software Engineering concepts
with Rails.
<a href="https://www.edx.org/course/agile-development-using-ruby-rails-uc-berkeleyx-cs169-1x-0">Agile Development Using Ruby on Rails - Basics</a>.
I signed up for the matching advanced course too.  So, if you want more Rails
material, I have some coming up to write about at least.  I&rsquo;ll write my
opinion of the MOOC after I get a chance to watch through the videos and try
the exercises.  Between the MOOC and the other Rails books I have on my
reading list, I should get a couple of nice blogposts that have some
code blocks in them.  Now that I have syntax highlighting working, might
as well use it.  There&rsquo;s also an Infinite Skills video that I have access to
through Safari Books Online that I wouldn&rsquo;t mind trying out.
<a href="https://www.safaribooksonline.com/library/view/hands-on-with-react/9781771375061/">Hands-on with React and Ruby on Rails</a>.
I don&rsquo;t have much React experience past doing the Tic-Tac Toe tutorial, but
I can probably manage it as the video doesn&rsquo;t claim you need React experience.
Anyway, I&rsquo;ll get back to reading and watching and coding stuff now, and come
back with some blogposts that include code soon.</p>
]]></content:encoded></item><item><title>AWDWR 5.1 - 02 - Instant Gratification</title><link>https://llcawthorne.github.io/posts/awdwr51-02-instant-gratification/</link><pubDate>Thu, 18 May 2017 00:00:00 +0000</pubDate><guid>https://llcawthorne.github.io/posts/awdwr51-02-instant-gratification/</guid><description>&lt;p&gt;First I&amp;rsquo;d like to say sorry the images are a little big. Not used to
screencaps on this retina Macbook.&lt;/p&gt;
&lt;p&gt;So, I fixed my mistake from last time. I had originally installed ruby via
homebrew, but now that I&amp;rsquo;ve read up on rbenv, it seems a lot nicer than the
old rvm, and I might want multiple versions of Ruby on my home PC. So I
uninstalled Ruby 2.4 and went with &lt;code&gt;brew install rbenv&lt;/code&gt; and then used
it to install the latest Ruby. I see why the book authors prefer it over
RVM now. It&amp;rsquo;s a lot less invasive than the old RVM.&lt;/p&gt;</description><content:encoded><![CDATA[<p>First I&rsquo;d like to say sorry the images are a little big.  Not used to
screencaps on this retina Macbook.</p>
<p>So, I fixed my mistake from last time.  I had originally installed ruby via
homebrew, but now that I&rsquo;ve read up on rbenv, it seems a lot nicer than the
old rvm, and I might want multiple versions of Ruby on my home PC.  So I
uninstalled Ruby 2.4 and went with <code>brew install rbenv</code> and then used
it to install the latest Ruby.  I see why the book authors prefer it over
RVM now.  It&rsquo;s a lot less invasive than the old RVM.</p>
<p>Anyway, on with Chapter 2, &ldquo;Instant Gratification&rdquo;.  I went ahead and
completed the code for this chapter and the exercises.  Both were fairly
trivial.  I checked it in at <a href="http://github.com/llcawthorne/demo51">demo51</a>.
If you clone that and run <code>bin/rails server</code> from the directory, you&rsquo;re
greeted by the site at http://localhost:3000/.  You get a lot for very
little with Rails.  The site you get just from running <code>rails new demo51</code>
looks like this:</p>
<p><img alt="rails welcome" loading="lazy" src="/posts/awdwr51-02-instant-gratification/images/rails.png"></p>
<p>It also looks like the default server has changed from WEBrick to Puma now.
But a page with a picture isn&rsquo;t all that impressive.  I must say that I
find it pleasant how fast the server starts.  I&rsquo;ve become used to my
Java EE servers with multiple minute startup times before you can see
changes, but not only does this server start fast, it loads changes on the
fly when in development mode, so you seldom have to restart it.  What is
also impressive is how easy it is to modify with a new route.  What is
slightly intimidating is that the rails new command actually generated
forty-six files spread across thirty-four directories.  The nice thing is
that everything is in its proper place, and hopefully by reading this book
and working with the applications a bit more we&rsquo;ll come to understand the
logic behind it.</p>
<p>The whole application in this chapter is a Hello World modified with a
timestamp to show something dynamic.  To do this, we need to generate a
new controller.  Going to the directory of our app and running
<code>bin/rails generate controller Say hello goodbye</code> will generate a
controller named Say with methods (in Rails terms, these controller
methods are called actions) hello and goodbye that will respond
to requests to <code>/say/hello</code> and <code>/say/goodbye</code>.  It puts the say controller
in <code>demo51/app/controllers/say_controller.rb</code>.  This is the controller
that contains methods for all the <code>/say/</code> routes.  Its starting code
that was generated is simply:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ruby" data-lang="ruby"><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">SayController</span> <span class="o">&lt;</span> <span class="no">ApplicationController</span>
</span></span><span class="line"><span class="cl">  <span class="k">def</span> <span class="nf">hello</span>
</span></span><span class="line"><span class="cl">  <span class="k">end</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="k">def</span> <span class="nf">goodbye</span>
</span></span><span class="line"><span class="cl">  <span class="k">end</span>
</span></span><span class="line"><span class="cl"><span class="k">end</span>
</span></span></code></pre></div><p>Those methods obviously don&rsquo;t do much.  Because it inherits from
<code>ApplicationController</code>, our <code>SayController</code> automatically gets all the
default controller behavior.  Even though the controller methods don&rsquo;t
have any logic, they still return a site when you navigate to the URL,
because by convention they are associated with certain views.</p>
<p><img alt="Say#hello" loading="lazy" src="/posts/awdwr51-02-instant-gratification/images/say-hello.png"></p>
<p>The route informs of the file it is currently serving
<code>app/views/say/hello.html.erb</code>, which was also automatically generated
when we created our controller with the command above.  If we edit the file
it points us to, we find what looks like a normal html file body:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-erb" data-lang="erb"><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">h1</span><span class="p">&gt;</span>Say#hello<span class="p">&lt;/</span><span class="nt">h1</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">p</span><span class="p">&gt;</span>Find me in app/views/say/hello.html.erb<span class="p">&lt;/</span><span class="nt">p</span><span class="p">&gt;</span>
</span></span></code></pre></div><p>This is the view that was generated by our command.  The views for the
<code>SayController</code> we created by default are placed in the <code>app/views/say</code>
directory, and there is a view for each of the hello and goodbye methods.
The book has us change this view to instead say:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-erb" data-lang="erb"><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">h1</span><span class="p">&gt;</span>Hello from Rails!<span class="p">&lt;/</span><span class="nt">h1</span><span class="p">&gt;</span>
</span></span></code></pre></div><p>If we refresh our browser window (without restarting the server), we see
the new output:</p>
<p><img alt="Hello from Rails" loading="lazy" src="/posts/awdwr51-02-instant-gratification/images/hello.png"></p>
<p>So far, we&rsquo;ve learned the place two things go.  Controllers go in
<code>app/controllers</code> and views go in <code>app/views</code>.  The book shows it with
the diagram:</p>
<p><img alt="directory structure" loading="lazy" src="/posts/awdwr51-02-instant-gratification/images/diagram.png"></p>
<p>The book goes on to add the time display to the page directly, then refactor
it to have the time generated by the controller and displayed in the view.
We&rsquo;ll just skip to that.  We modify say_controller.rb to generate the time:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ruby" data-lang="ruby"><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">SayController</span> <span class="o">&lt;</span> <span class="no">ApplicationController</span>
</span></span><span class="line"><span class="cl">  <span class="k">def</span> <span class="nf">hello</span>
</span></span><span class="line"><span class="cl">    <span class="vi">@time</span> <span class="o">=</span> <span class="no">Time</span><span class="o">.</span><span class="n">now</span>
</span></span><span class="line"><span class="cl">  <span class="k">end</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="k">def</span> <span class="nf">goodbye</span>
</span></span><span class="line"><span class="cl">  <span class="k">end</span>
</span></span><span class="line"><span class="cl"><span class="k">end</span>
</span></span></code></pre></div><p>and modify the view to display the variable set for it by the controller:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-erb" data-lang="erb"><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">h1</span><span class="p">&gt;</span>Hello from Rails!<span class="p">&lt;/</span><span class="nt">h1</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">p</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  It is now <span class="cp">&lt;%=</span> <span class="vi">@time</span> <span class="cp">%&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">p</span><span class="p">&gt;</span>
</span></span></code></pre></div><p>The time is <em>data</em>, so it is supplied to the view by the controller.  The
book forewarns us we&rsquo;ll see a lot more of this once we introduce models.
It goes on to explain the step-by-step process of what the server goes
through when responding to a request, at a very high level.  We then
customize our goodbye page, but you can checkout the git repo if you want
to see that or the results of completing either of the chapter&rsquo;s two
exercises.  The one remaining item of interest it does in the app is add a
link from the Hello page to the Goodbye page and vice versa.  It does
this using built in helper methods rather than hardcoding URL&rsquo;s.  The new
hello.html.erb looks like:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-erb" data-lang="erb"><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">h1</span><span class="p">&gt;</span>Hello from Rails!<span class="p">&lt;/</span><span class="nt">h1</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">p</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  It is now <span class="cp">&lt;%=</span> <span class="vi">@time</span> <span class="cp">%&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">p</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">p</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  Time to say
</span></span><span class="line"><span class="cl">  <span class="cp">&lt;%=</span> <span class="n">link_to</span> <span class="s2">&#34;Goodbye&#34;</span><span class="p">,</span> <span class="n">say_goodbye_path</span> <span class="cp">%&gt;</span>!
</span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">p</span><span class="p">&gt;</span>
</span></span></code></pre></div><p>The first parameter in the call to <code>link_to()</code> is the text to be displayed
in the hyperlink, and the next parameter tells Rails to generate the link
to the goodbye action of the say controller.</p>
<p>Finally in this chapter, they display what happens when things break.  As
the authors put it &ldquo;the true test of the developer friendliness of a
framework is how it responds when things go wrong.&rdquo;  First, they ask
what would happen if we misspelled Time.now as Time.know in our controller.
Rails not only tells you the exact spot of the error, it also asks if you
meant to type &ldquo;now&rdquo; and offers an interactive debugging console:</p>
<p><img alt="rails error page" loading="lazy" src="/posts/awdwr51-02-instant-gratification/images/rails_know_error.png"></p>
<p>And before you start worrying, the web console is only shown if you&rsquo;re on the
same machine as the web server and running in development mode, so there
shouldn&rsquo;t be any chance of anyone getting into it in production unless
you specifically whitelist more ips and run the server in development mode.
Likewise, if you attempt to go to <code>http://localhost:3000/say/h3llo</code> instead
of <code>/say/hello</code>, you get:</p>
<p><img alt="rails error page" loading="lazy" src="/posts/awdwr51-02-instant-gratification/images/rails_h3llo_error.png"></p>
<p>It gives you a list of possible routes along with what controller and action
they are associated with and a helpful search box to trim it down.</p>
<p>Altogether, the app presented here is totally trivial, but in this chapter
they did manage to cover:</p>
<ul>
<li>How to create a new Rails application and how to create a new controller
in that application</li>
<li>How to create dynamic content in the controller and display it via the view</li>
<li>How to link pages together</li>
<li>How to debug problems in code or the URL</li>
</ul>
<p>Looks like the next chapter covers a bit of MVC theory, and chapter 4 is a
Rails review.  I&rsquo;ll probably comment on both in one quick post.  Then in
Chapter 5, we dig into building a bigger application.</p>
]]></content:encoded></item><item><title>AWDWR 5.1 - 01 - Introduction</title><link>https://llcawthorne.github.io/posts/awdwr51-01-introduction/</link><pubDate>Tue, 16 May 2017 00:00:00 +0000</pubDate><guid>https://llcawthorne.github.io/posts/awdwr51-01-introduction/</guid><description>&lt;p&gt;So, what do I have to blog about? I&amp;rsquo;m always trying out new stuff and reading
books, so I figure I&amp;rsquo;ll talk about that. I happen to have just gotten a
beta copy of
&lt;a href="https://pragprog.com/book/rails51/agile-web-development-with-rails-5-1"&gt;Agile Web Development with Rails 5.1&lt;/a&gt;
and since my Ruby and Rails
experience from my résumé is a little rusty, I figure I&amp;rsquo;ll
read that and blog about the experience. Starting this site using Jekyll
has made me think about Ruby lately anyway. It&amp;rsquo;s been many years since I&amp;rsquo;ve
read &amp;ldquo;Agile Web Development with Rails&amp;rdquo;, and I think it was the version that
covered Rails 1.2, so this should be a pretty new experience for me; both a
great refresher and an introduction to what is new in the Rails world these
days.&lt;/p&gt;</description><content:encoded><![CDATA[<p>So, what do I have to blog about?  I&rsquo;m always trying out new stuff and reading
books, so I figure I&rsquo;ll talk about that.  I happen to have just gotten a
beta copy of
<a href="https://pragprog.com/book/rails51/agile-web-development-with-rails-5-1">Agile Web Development with Rails 5.1</a>
and since my Ruby and Rails
experience from my résumé is a little rusty, I figure I&rsquo;ll
read that and blog about the experience.  Starting this site using Jekyll
has made me think about Ruby lately anyway.  It&rsquo;s been many years since I&rsquo;ve
read &ldquo;Agile Web Development with Rails&rdquo;, and I think it was the version that
covered Rails 1.2, so this should be a pretty new experience for me; both a
great refresher and an introduction to what is new in the Rails world these
days.</p>
<p>The obvious question is why rails when I could play with the hot new
Javascript framework.  Well, I&rsquo;ve played with React some, along with Ember,
and Angular.  I might go back to messing with them and blog about the
results later.  Right now, I&rsquo;m just in a Ruby/Rails mood.  I&rsquo;ve always liked
how the Ruby community seems to emphasize good programming practices that
carry over to any language you work in, and I recall the Agile Web Development
book being a good source of sound programming advice.  As a side note, I
understand that the book now includes information on doing a Javascript
front-end with a Rails backend, so I&rsquo;ll get in some Javascript before I&rsquo;m
through.</p>
<p>The introduction is well paced.  The parts I feel worth mentioning are
its argument that &ldquo;Rails Simply Feels Right&rdquo;, which I am inclined to agree
with.  I&rsquo;ve always thought of Rails as the cadillac of web frameworks.
There&rsquo;s a lot of ways to do the same old CRUD in other frameworks, it&rsquo;s
just rails has polish and a certain thoughtfulness of layout that makes it
all click.  It achieves a level of conciseness thanks to &ldquo;Convention over
configuration&rdquo;, adhering to the philosophy of DRY (Don&rsquo;t Repeat Yourself),
and the natural conciseness of the Ruby programming language (a trait that
I miss a lot now in my job, where my Java code tends to include a lot of
boiler plate by necessity).</p>
<p>The introduction shares a link to the guiding philosophy of
Rails, the <a href="http://rubyonrails.org/doctrine/">Rails Doctrine</a>.  It can be
argued that the Rails Doctrine is what makes Rails continue to be a strong
choice as a web framework, even though it&rsquo;s no longer the new darling on
the block, and as an aside is also one of the reasons I favor Ember of the
Javascript frameworks, since the Ember community were obviously
heavily influenced by the Ruby/Rails community.  The number one item on the
Rails Doctrine is &ldquo;Optimize for programmer happiness&rdquo;.  This is lifted
straight from Ruby, but is still something that many languages don&rsquo;t put
among the considerations, much less as a guiding principle.  I forgive them
for taking a shot at one of my other favorite language mottos, Python&rsquo;s
&ldquo;one and preferably only one way to do something&rdquo;, which I also believe has
it&rsquo;s place.  But I get their meaning that having a choice of ways to express
a solution and being able to choose among them adds a certain bit of
artistry to the craft of programming.</p>
<p>I really appreciate the 2nd principle of the Rails doctrine, &ldquo;Convention over
Configuration&rdquo;.  Right now, my primary day job is working on an app that&rsquo;s
been around for 15 years, and it seems for every problem encountered the
people came up with a way from scratch for how to handle it.  There&rsquo;s no
conventional way to do anything.  But as the author says, &ldquo;Part of the Rails’
mission is to swing its machete at the thick, and ever growing, jungle of
recurring decisions that face developers creating information systems for
the web.&rdquo;  Sane defaults make a lot of things possible with little effort,
as is shown by the demo app in the next chapter.  Just like the Principle of
Least Surprise, it begs the question of &ldquo;Sane (or least surprise) to who?&rdquo;,
but in general the framework itself is built with enough consistency that
once your steeped in its general way of doing things, they make sense as a
whole.  I endorse the idea that freedom from choice is sometimes exactly
what is needed, rather than freedom of choice to do it a different way.
&ldquo;A place for everything and everything in its place. Constraints liberate
even the most able minds.&rdquo;  This is the same type of consistency that
Python&rsquo;s motto helps provide, but with some wiggle room left for expression
in implementation.</p>
<p>I could go on analyzing tenets of the Rails Doctrine, but let&rsquo;s get back to
the book.  I will argue that I sometimes feel &ldquo;monkey patching&rdquo; is more
power than programmers need, even if it allows some cool tricks.  But I
haven&rsquo;t used it much.  It just seems a nightmare that you might end up
having to look at someone&rsquo;s legacy code down the line where they completely
misused it and nothing makes sense.  But then again, I like having sharp
knives in my kitchen too.  I just don&rsquo;t have to cook after many other chefs.
Even good programmers sometimes make questionable decisions when pushed for
time assuming the language allows certain shortcuts.  It&rsquo;s the sharp knives
offered by Ruby and Rails that sometimes make me want to stick to the easy
consistency of Python and Django, even if they require a little more
boilerplate to accomplish similar tasks.</p>
<p>I did promise to get back to the book.  It points out also that &ldquo;Rails is
Agile&rdquo;.  It&rsquo;s too easy to forget the core tenets of Agile development; they
become easily lost to a focus on the ceremonies of Agile.  The book restates
the four preferences of the Agile Manifesto:</p>
<ul>
<li>Individuals and interactions over processes and tools</li>
<li>Working software over comprehensive documentation</li>
<li>Customer collaboration over contract negotiation</li>
<li>Responding to change over following a plan</li>
</ul>
<p>As someone who works at an organization that is permanently mid-transition
between doing things waterfall and approaching them with more agility, I
like to remember the core philosophy of the Agile Manifesto and ask if the
particular procedure we&rsquo;re seeking to follow embodies those ideas.  It&rsquo;s
too easy for the core ideas to get lost in the ceremony of scrums and
sprint planning meetings and the artifacts of burndown charts.</p>
<p>Who is this book for?  It&rsquo;s aimed at application programmers who want to
build and deploy web based applications.  It&rsquo;s fine if you&rsquo;re new to Rails,
and it might be fine even if you&rsquo;re new to Ruby.  My Ruby is rusty enough
that I had to review at
<a href="https://learnxinyminutes.com/docs/ruby/">Learn X in Y Minutes</a>,
but that&rsquo;s a good sign I should
be alright.  I have a whole catalog of <a href="http://exercism.io/">Exercism</a>
problems that I worked in Ruby to review with too, in the worst case.  This
book is more about how to get things done, and doesn&rsquo;t attempt to act as
a detailed reference book.  There&rsquo;s online API references for that type of
stuff.</p>
<p>That was just the introduction!  We&rsquo;ll be a bit quicker now.  Especially
since the first chapter is all about getting setup.  It has useful
instructions for a variety of platforms, including working from a vagrant
box or using the cloud9 online IDE.  I figure that I like having a recent
version of ruby around at the command line anyway, so I followed the OS X
instructions and used homebrew (which I already had installed).  I&rsquo;m
tempted to try Cloud9 sometime, especially since a quick Google tells me
that it does have Vim keybindings.  Maybe some other time.  It looks like
in addition to rails, we need yarn and chromedriver.  I don&rsquo;t have yarn
installed yet, as I&rsquo;ve just used npm for packages, and I&rsquo;m looking forward
to using chromedriver from Ruby.  I use selenium and chromedriver at work
to do end-to-end testing of some of my applications, so I&rsquo;m used to working
with chromedriver in Java.  I needed to uninstall rvm to get the new version
of ruby on my OS X box.  It seems that rbenv is the book&rsquo;s preferred way
for managing multiple Ruby&rsquo;s these days.</p>
<p>On an unrelated note, when did OS X get the ability to remap Caps Lock to
Escape without addons?  I always used to use Seil and Karbiner, but they
quit working in the latest version of OS X.  I was about to try Karbiner
Elements, but when I checked modifier keys under Keyboard in System
Preferences, I saw that it had Caps Lock there and an Escape option.
Sorry to toss this in the middle of everything else, but it&rsquo;s really been
bugging me in Vim to not have my Caps Lock act as Escape.  Unless I stay
on a Ruby kick, the next book I review might be
<a href="https://pragprog.com/book/dnvim2/practical-vim-second-edition">Practical Vim</a>.  I
believe I saw the second edition was on
<a href="https://www.safaribooksonline.com/">Safari Books</a> the other day.
Sorry for the aside,
but I got distracted while waiting for homebrew to update all my packages.</p>
<p>Back to the book.  After covering installing in the environment of your
choice, along with some advice for when/if things go wrong, we get to
Chapter 2, &ldquo;Instant Gratification&rdquo;.  In this chapter, we&rsquo;ll make a quick
demo app to get our feet wet with Rails.  I&rsquo;ve put the demo app with
completed exercises up at <a href="http://github.com/llcawthorne/demo51">demo51</a>.
I&rsquo;ll cover Chapter 2 next blogpost, this one is already getting pretty
large.</p>
]]></content:encoded></item></channel></rss>