<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

  <title>Matt Newman</title>
  <link href="/feed/" rel="self"/>
  <link href="/"/>
  <updated>2026-03-26T00:00:04+00:00</updated>
  <id>/feed/</id>
  <author>
    <name>Matt Newman</name>
  </author>

  
  <entry>
    <title>Jan/Feb/Mar 2019 travel</title>
    <link href="/2019/04/2019-q1-travel/"/>
    <updated>2019-04-30T00:00:00+00:00</updated>
    <id>/2019/04/2019-q1-travel/</id>
    <category term="travel" label="Travel"></category>
    <content type="html">&lt;p&gt;After the stay in California, I didn’t do a load of travel in the first three
months of 2019, mostly due to being staffed in Chicago &amp;amp; spending some time
there. Also, there isn’t a lot of easily accessible hiking in winter!&lt;/p&gt;

&lt;p&gt;This post covers what I was up to for the first three months of the year, and
is mostly about Chicago.&lt;/p&gt;

&lt;h2 id=&quot;chicago&quot;&gt;Chicago&lt;/h2&gt;

&lt;h3 id=&quot;early-weather&quot;&gt;Early weather&lt;/h3&gt;

&lt;p&gt;Chicago in winter is a level of cold that I’m not well acquainted with 🥶&lt;/p&gt;

&lt;p&gt;I drove up from Cincinnati, and was blessed with a snow storm the night before my drive:&lt;/p&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2019/q1/drive-from-cinci.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2019/q1/drive-from-cinci.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;p&gt;I guess it was a sign of things to come - a fortnight later was the &lt;a href=&quot;https://en.wikipedia.org/wiki/January%E2%80%93February_2019_North_American_cold_wave&quot;&gt;2019 polar
vortex&lt;/a&gt;,
which shut down most of the city for a couple of days. It was the only time I
saw the river completely frozen over:&lt;/p&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2019/q1/polar-vortex-1.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2019/q1/polar-vortex-1.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2019/q1/polar-vortex-2.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2019/q1/polar-vortex-2.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;p&gt;I was staying a very short distance from work and decided to walk during the
cold weather, which was an experience. My face was completely covered, except
for my eyes, which watered. Of course the water from my struggling eyes froze,
along with the tiny bit of hair that was exposed and water condensing in my
nose (producing a satisfying crunch when I pinched my nostrils).&lt;/p&gt;

&lt;h3 id=&quot;field-museum&quot;&gt;Field Museum&lt;/h3&gt;

&lt;p&gt;I went full tourist in Chicago and purchased a
&lt;a href=&quot;https://www.citypass.com/chicago&quot;&gt;CityPASS&lt;/a&gt;, good for entry into 5
attractions. The first I visited was the &lt;a href=&quot;https://www.fieldmuseum.org/&quot;&gt;Field
Museum&lt;/a&gt;. For some reason I don’t have loads of
photos here, but the main things I remember are&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;the huge collection of taxidermied animals&lt;/li&gt;
  &lt;li&gt;SUE the T. rex&lt;/li&gt;
  &lt;li&gt;the &lt;a href=&quot;https://www.fieldmuseum.org/exhibitions/underground-adventure&quot;&gt;Underground Adventure&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;art-institute-of-chicago&quot;&gt;Art Institute of Chicago&lt;/h3&gt;

&lt;p&gt;I’m not normally one for art museums, but &lt;a href=&quot;https://www.artic.edu/&quot;&gt;The Art
Institute&lt;/a&gt; has a great collection, including a number
of paintings by van Gogh, Picasso, Pollock, Warhol and more. &lt;a href=&quot;https://www.artic.edu/exhibitions/2353/the-deering-family-galleries-of-medieval-and-renaissance-art-arms-and-armor&quot;&gt;The Deering
Family Galleries of Medieval and Renaissance Art, Arms, and
Armor&lt;/a&gt;
(an ongoing exhibit) was another highlight, and I was amazed at the detail in
the 68 &lt;a href=&quot;https://www.artic.edu/highlights/12/thorne-miniature-rooms&quot;&gt;Thorne Miniature
Rooms&lt;/a&gt;.&lt;/p&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2019/q1/thorne-room.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2019/q1/thorne-room.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;h3 id=&quot;skydeck-chicago&quot;&gt;Skydeck Chicago&lt;/h3&gt;

&lt;p&gt;I’ve been told by locals that under no circumstances am I to refer to the Sears
Tower by it’s new name, The Willis Tower. Regardless of the name, the views
from the &lt;a href=&quot;https://theskydeck.com/&quot;&gt;The Skydeck&lt;/a&gt; are spectacular:&lt;/p&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2019/q1/skydeck-1.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2019/q1/skydeck-1.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2019/q1/skydeck-2.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2019/q1/skydeck-2.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2019/q1/skydeck-3.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2019/q1/skydeck-3.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2019/q1/skydeck-4.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2019/q1/skydeck-4.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2019/q1/skydeck-5.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2019/q1/skydeck-5.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2019/q1/skydeck-6.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2019/q1/skydeck-6.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;h3 id=&quot;museum-of-science-and-industry&quot;&gt;Museum of Science and Industry&lt;/h3&gt;

&lt;p&gt;I think the &lt;a href=&quot;https://www.msichicago.org&quot;&gt;Museum of Science and Industry&lt;/a&gt; in
Chicago is my new favourite museum, with the &lt;a href=&quot;/2016/07/europe/&quot;&gt;Deutsches Museum&lt;/a&gt; in Munich a close second.&lt;/p&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2019/q1/field-museum-exterior.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2019/q1/field-museum-exterior.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;p&gt;It’s absolutely huge, I could easily spend far more than a day there. A few
highlights, in no particular order:&lt;/p&gt;

&lt;figure&gt;
  &lt;video style=&quot;max-width: 100%; display: block;&quot; autoplay=&quot;&quot; loop=&quot;&quot; muted=&quot;&quot;&gt;
    &lt;source src=&quot;/public/images/2019/q1/msi-avalanche.webm&quot; type=&quot;video/webm; codecs=vp9&quot; /&gt;
  &lt;/video&gt;
  &lt;figcaption&gt;Avalanche simulation in the Science Storms exhibit.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2019/q1/msi-mirror-maze.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2019/q1/msi-mirror-maze.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    Mirror maze in Numbers in Nature exhibit.
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;p&gt;The mirror maze was oddly peaceful for the few seconds I was in there alone!
For the rest of the time I was just trying to avoid running into the kids that
were barrelling though.&lt;/p&gt;

&lt;figure&gt;
  &lt;video style=&quot;max-width: 100%; display: block;&quot; autoplay=&quot;&quot; loop=&quot;&quot; muted=&quot;&quot;&gt;
    &lt;source src=&quot;/public/images/2019/q1/msi-storm.webm&quot; type=&quot;video/webm; codecs=vp9&quot; /&gt;
  &lt;/video&gt;
  &lt;figcaption&gt;Tornado simulation in the Science Storms exhibit.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2019/q1/msi-u-505.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2019/q1/msi-u-505.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    U-505 submarine, captured during World War II.
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;h3 id=&quot;st-patricks-day&quot;&gt;St Patrick’s Day&lt;/h3&gt;

&lt;p&gt;St Patrick’s Day in Chicago was an experience … I knew it was a huge event,
but I didn’t expect the streets to be packed from 7:30 AM.&lt;/p&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2019/q1/green-river.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2019/q1/green-river.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    The Chicago River is dyed a vibrant green on St Patrick&apos;s day.
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;h3 id=&quot;-spring&quot;&gt;… Spring?&lt;/h3&gt;

&lt;p&gt;I’ve been warned that March warm weather in Chicago only lulls you into a false
sense of security. As I’m writing this it’s closer to the end of April &amp;amp; I’m
hopeful the worst of the cold weather is finished. As a reference, here’s a
recent photo of Maggie Daley Park &amp;amp; Grant Park - it looks a little more
inviting than the photo earlier in this post!&lt;/p&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2019/q1/chicago-spring.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2019/q1/chicago-spring.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;h1 id=&quot;la--spartan-race&quot;&gt;LA &amp;amp; Spartan Race&lt;/h1&gt;

&lt;p&gt;I visited LA briefly in December on a trip to go hiking in &lt;a href=&quot;https://www.nps.gov/jotr/index.htm&quot;&gt;Joshua Tree
National Park&lt;/a&gt;, but most of the time in LA
itself was spent sitting in traffic.&lt;/p&gt;

&lt;p&gt;I went back in January to do the Spartan SoCal Sprint just outside of LA, and
had a chance to see a little more of LA itself.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://www.griffithobservatory.org/&quot;&gt;Griffith Observatory&lt;/a&gt; is definitely worth
a visit, for the exhibits as well as the views of LA.&lt;/p&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2019/q1/la-skyline.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2019/q1/la-skyline.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2019/q1/griffith-observatory-evening.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2019/q1/griffith-observatory-evening.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;p&gt;On Saturday we spent some time in Venice Beach area, including the Venice
Canals and a ride along the boardwalk and ocean front walk. It was a nice
change from the winter in Chicago!&lt;/p&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2019/q1/canals.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2019/q1/canals.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2019/q1/santa-monica-pier.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2019/q1/santa-monica-pier.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;figure&gt;
  &lt;video style=&quot;max-width: 100%; display: block;&quot; autoplay=&quot;&quot; loop=&quot;&quot; muted=&quot;&quot;&gt;
    &lt;source src=&quot;/public/images/2019/q1/venice-ride.webm&quot; type=&quot;video/webm; codecs=vp9&quot; /&gt;
  &lt;/video&gt;
&lt;/figure&gt;

&lt;h1 id=&quot;seattle&quot;&gt;Seattle&lt;/h1&gt;

&lt;p&gt;I had planned a trip to Chicago the weekend after the polar vortex hit Chicago,
but my flight out was cancelled due to the weather. I still made it out of
Chicago the next day, but that made for a fairly short trip, so I changed my
plans to spend the time in Seattle itself and ditched the hiking I was planning
in Mt Rainier National Park.&lt;/p&gt;

&lt;p&gt;I stayed right near &lt;a href=&quot;https://en.m.wikipedia.org/wiki/Pike_Place_Market&quot;&gt;Pike Place
Market&lt;/a&gt; which turned out to
be a great spot.&lt;/p&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2019/q1/pike-place-market.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2019/q1/pike-place-market.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;p&gt;Some notable places:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.piroshkybakery.com/&quot;&gt;Piroshky Piroshky&lt;/a&gt; bakery: I may have
returned here more than once, fodder was delicious but not entirely
compatible with my desire to be somewhat healthy 🤣&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Gum_Wall&quot;&gt;The Gum Wall&lt;/a&gt;: one of the most germ
ridden attractions in existence&lt;/li&gt;
&lt;/ul&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2019/q1/gum-wall.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2019/q1/gum-wall.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;
&lt;ul&gt;
  &lt;li&gt;The original Starbucks&lt;/li&gt;
  &lt;li&gt;Underground tour: it was interesting hearing about how Seattle was built, it
is honestly a miracle they didn’t just give up.
&lt;a href=&quot;https://en.wikipedia.org/wiki/Seattle_Underground&quot;&gt;Wikipedia&lt;/a&gt; has some info on
the underground.&lt;/li&gt;
  &lt;li&gt;Seattle Center: I’d like to go back here, there is loads to do. It was the
site of the 1962 World’s Fair. The Space Needle, MoPOP and the Chihuly Garden
and Glass are apparently all worth a visit, but I just walked around the area
without going in.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;south-lake-tahoe&quot;&gt;South Lake Tahoe&lt;/h1&gt;

&lt;p&gt;My first trip in March was to &lt;a href=&quot;https://en.wikipedia.org/wiki/South_Lake_Tahoe,_California&quot;&gt;South Lake
Tahoe&lt;/a&gt; for a
weekend of skiing. There was a little more snow there than I’ve seen in
Australia before 😂.&lt;/p&gt;

&lt;p&gt;The base of the resort is at 1,907 m and the top is 3,068 m, so it isn’t super
high but its location near the lake means lots of snow (the peak of Mount
Kosciuszko is 2,228 m, so most of the Thredbo resort in Australia is less than
2,000 m).&lt;/p&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2019/q1/tahoe-from-heavenly.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2019/q1/tahoe-from-heavenly.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2019/q1/cold.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2019/q1/cold.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2019/q1/tahoe-lake%20level.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2019/q1/tahoe-lake%20level.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2019/q1/tahoe-nevada.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2019/q1/tahoe-nevada.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2019/q1/tahoe-california.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2019/q1/tahoe-california.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;h1 id=&quot;toronto&quot;&gt;Toronto&lt;/h1&gt;

&lt;p&gt;The second trip for March was to Toronto, again a short trip so I really only
had time to explore part of Old Toronto near where I was staying:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;St. Lawrence Market&lt;/li&gt;
  &lt;li&gt;Distillery District&lt;/li&gt;
  &lt;li&gt;Yonge-Dundas Square&lt;/li&gt;
  &lt;li&gt;CF Toronto Eaton Centre&lt;/li&gt;
  &lt;li&gt;Kensington Market&lt;/li&gt;
&lt;/ul&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2019/q1/toronto-sign.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2019/q1/toronto-sign.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2019/q1/cn-tower.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2019/q1/cn-tower.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

</content>
  </entry>
  
  <entry>
    <title>California</title>
    <link href="/2019/01/california/"/>
    <updated>2019-01-01T00:00:00+00:00</updated>
    <id>/2019/01/california/</id>
    <category term="travel" label="Travel"></category>
    <content type="html">&lt;p&gt;I’ve been fortunate to spend some time in &lt;a href=&quot;https://en.wikipedia.org/wiki/California&quot;&gt;The Golden State&lt;/a&gt; in November
and December. I haven’t made it over here much, as it’s a long way from where I
have been based in the east of the states.&lt;/p&gt;

&lt;h2 id=&quot;part-1---san-francisco&quot;&gt;Part 1 - San Francisco&lt;/h2&gt;

&lt;p&gt;After working most of Friday from the ThoughtWorks office in the SoMa (South of
Market) area, we took a walk through Chinatown to Coit Tower on Telegraph Hill,
where I got my first views of the bay.&lt;/p&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2019/01/california/20181102-coit-tower.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2019/01/california/20181102-coit-tower.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;p&gt;Despite being very hilly, SF is a walkable city. We continued down to
Fisherman’s Wharf and on to the &lt;a href=&quot;https://en.wikipedia.org/wiki/Palace_of_Fine_Arts&quot;&gt;Palace of Fine Arts&lt;/a&gt; in the
Marine District. I didn’t get many photos, but it’s an interesting place
originally constructed for the &lt;a href=&quot;https://en.wikipedia.org/wiki/Panama%E2%80%93Pacific_International_Exposition&quot;&gt;1915 Panama-Pacific Exposition&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;We rented bikes on Saturday, and rode from &lt;a href=&quot;https://goo.gl/maps/o29dQm3W5P22&quot;&gt;North Beach&lt;/a&gt; across
the Golden Gate Bridge, back to Sutro Heights and through the Presidio on the
way back. Lots of great views, the photos below don’t really do it justice!&lt;/p&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2019/01/california/20181102-coit-tower.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2019/01/california/20181102-coit-tower.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2019/01/california/20181103-gg-bridge.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2019/01/california/20181103-gg-bridge.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2019/01/california/20181103-gg-bridge-2.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2019/01/california/20181103-gg-bridge-2.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2019/01/california/20181103-ocean-beach.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2019/01/california/20181103-ocean-beach.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2019/01/california/20181103-sunset.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2019/01/california/20181103-sunset.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;p&gt;I think this might have been the first time I’ve seen the sun setting over an
ocean … I’ve always lived near eastern coasts so sunrise over the ocean feels
more normal! 😂&lt;/p&gt;

&lt;h2 id=&quot;part-2---los-angeles-and-joshua-tree-national-park&quot;&gt;Part 2 - Los Angeles and Joshua Tree National Park&lt;/h2&gt;

&lt;p&gt;In early December I was in LA for a couple of days before flying back to
Australia for the Christmas break. We did a bit of hiking, and saw a little of
LA as well.&lt;/p&gt;

&lt;p&gt;The first hike was the &lt;a href=&quot;https://www.alltrails.com/trail/us/california/mount-zion-loop-sturtevant-to-winter-creek-trails&quot;&gt;Mount Zion Loop - Sturtevant to Winter Creek
Trail&lt;/a&gt;&lt;/p&gt;

&lt;div class=&quot;embed-container&quot;&gt;
  &lt;iframe frameborder=&quot;0&quot; allowtransparency=&quot;true&quot; scrolling=&quot;no&quot; src=&quot;https://www.strava.com/activities/2005518938/embed/074b807223830592bd5d1b564b573300bf02e53f&quot;&gt;
  &lt;/iframe&gt;
&lt;/div&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2019/01/california/20181207-mt-zion-loop.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2019/01/california/20181207-mt-zion-loop.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2019/01/california/20181207-take-care.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2019/01/california/20181207-take-care.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;p&gt;For the second day we drove to &lt;a href=&quot;https://www.nps.gov/jotr/index.htm&quot;&gt;Joshua Tree National Park&lt;/a&gt; and did the
&lt;a href=&quot;https://www.alltrails.com/trail/us/california/lost-horse-mine&quot;&gt;Lost Horse Mine Loop Trail&lt;/a&gt;.&lt;/p&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2019/01/california/20181208-jtree-view-1.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2019/01/california/20181208-jtree-view-1.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2019/01/california/20181208-jtree-tree.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2019/01/california/20181208-jtree-tree.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2019/01/california/20181208-jtree-cap-rock.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2019/01/california/20181208-jtree-cap-rock.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;p&gt;I managed to sneak in a visit to &lt;a href=&quot;https://en.wikipedia.org/wiki/J._Paul_Getty_Museum&quot;&gt;The Getty&lt;/a&gt;:&lt;/p&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2019/01/california/20181209-getty.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2019/01/california/20181209-getty.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;p&gt;And to &lt;a href=&quot;https://en.wikipedia.org/wiki/Griffith_Observatory&quot;&gt;Griffith Observatory&lt;/a&gt; to get the obligatory selfie with the
Hollywood sign before flying out on Sunday:&lt;/p&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2019/01/california/20181209-hollywood.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2019/01/california/20181209-hollywood.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;h2 id=&quot;part-3---drive-from-la--sf&quot;&gt;Part 3 - Drive from LA → SF&lt;/h2&gt;

&lt;p&gt;After landing in LA on Boxing Day morning, I took a couple of days to drive up
to San Francisco, mostly along &lt;a href=&quot;https://en.wikipedia.org/wiki/California_State_Route_1&quot;&gt;California State Route 1&lt;/a&gt; (a.k.a. the
Pacific Coast Highway). It’s a lovely drive, a few highlights include:&lt;/p&gt;

&lt;p&gt;Beautiful beaches along the way:&lt;/p&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2019/01/california/20181226_104036-beaches.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2019/01/california/20181226_104036-beaches.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;p&gt;Elephant seals:&lt;/p&gt;

&lt;video style=&quot;max-width: 100%; display: block;&quot; autoplay=&quot;&quot; loop=&quot;&quot; muted=&quot;&quot;&gt;
  &lt;source src=&quot;/public/images/2019/01/california/20181227_110553-seals.webm&quot; type=&quot;video/webm; codecs=vp9&quot; /&gt;
&lt;/video&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;The Buzzards Roost trail in &lt;a href=&quot;https://www.parks.ca.gov/?page_id=570&quot;&gt;Big Sur State Park&lt;/a&gt;:&lt;/p&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2019/01/california/20181227_133656-big-sur.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2019/01/california/20181227_133656-big-sur.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;p&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Carmel-by-the-Sea,_California&quot;&gt;Carmel-by-the-Sea&lt;/a&gt;:&lt;/p&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2019/01/california/20181227_145831-carmel-by-the-sea.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2019/01/california/20181227_145831-carmel-by-the-sea.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;p&gt;And finally Monterey:&lt;/p&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2019/01/california/20181227_155218-monterey.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2019/01/california/20181227_155218-monterey.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;h2 id=&quot;part-4---san-francisco-again&quot;&gt;Part 4 - San Francisco (again)&lt;/h2&gt;

&lt;p&gt;I spent the last four days of 2018 running, walking and hiking my way primarily
through SF, in an effort to work of combined Thanksgiving/holiday
party/Christmas calories 😂&lt;/p&gt;

&lt;p&gt;The only visits outside SF were to Sausalito and a hike in the Claremont Canyon
Regional Preserve in Berkeley. Some select photos:&lt;/p&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2019/01/california/20181228_114103-pier-39.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2019/01/california/20181228_114103-pier-39.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2019/01/california/20181228_153117-gg-bridge-from-bakers-beach.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2019/01/california/20181228_153117-gg-bridge-from-bakers-beach.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2019/01/california/20181229_114417-lombard-st.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2019/01/california/20181229_114417-lombard-st.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2019/01/california/20181230_092405-sf-from-berkeley.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2019/01/california/20181230_092405-sf-from-berkeley.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2019/01/california/20181230_164732-sf-from-sausalito.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2019/01/california/20181230_164732-sf-from-sausalito.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2019/01/california/20190101_001531-fireworks.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2019/01/california/20190101_001531-fireworks.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

</content>
  </entry>
  
  <entry>
    <title>Pawleys Island</title>
    <link href="/2018/11/pawleys-island/"/>
    <updated>2018-11-26T00:00:00+00:00</updated>
    <id>/2018/11/pawleys-island/</id>
    <category term="travel" label="Travel"></category>
    <content type="html">&lt;p&gt;For Thanksgiving this year I stayed with some friends at a house in &lt;a href=&quot;https://en.wikipedia.org/wiki/Pawleys_Island,_South_Carolina&quot;&gt;Pawleys
Island&lt;/a&gt;, a town and island in Georgetown County, South Carolina.&lt;/p&gt;

&lt;p&gt;It was a relaxing time, with lots of walks on the beach and way too much food.&lt;/p&gt;

&lt;p&gt;We were also there for a king tide, which produced some minor flooring and had
us worried for out rental car. It was amazing to me how many of these places
are so close to the ocean, you could see the dunes getting washed away during
the higher tides.&lt;/p&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2018/11/pawleys-island/1.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2018/11/pawleys-island/1.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2018/11/pawleys-island/2.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2018/11/pawleys-island/2.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2018/11/pawleys-island/3.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2018/11/pawleys-island/3.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2018/11/pawleys-island/4.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2018/11/pawleys-island/4.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2018/11/pawleys-island/5.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2018/11/pawleys-island/5.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

</content>
  </entry>
  
  <entry>
    <title>Acadia National Park</title>
    <link href="/2018/10/acadia-national-park/"/>
    <updated>2018-10-22T00:00:00+00:00</updated>
    <id>/2018/10/acadia-national-park/</id>
    <category term="travel" label="Travel"></category>
    <content type="html">&lt;p&gt;My fourth trip in what has turned into a very busy October was to &lt;a href=&quot;https://www.nps.gov/acad/index.htm&quot;&gt;Acadia
National Park&lt;/a&gt; in Maine, the easternmost
state of the US. I flew into Boston, drove up to Acadia &amp;amp; stayed in Airbnbs
nearby.&lt;/p&gt;

&lt;p&gt;Acadia National Park is beautiful, and is the first coastal park I’ve visited
(other than the &lt;a href=&quot;/2018/04/miami-keys-everglades/&quot;&gt;Everglades NP&lt;/a&gt;, it’s nice in a different way).&lt;/p&gt;

&lt;p&gt;The first hike I did there was up Cadillac Mountain along the &lt;a href=&quot;https://www.alltrails.com/trail/us/maine/cadillac-mountain-south-ridge-trail&quot;&gt;South Ridge
Trail&lt;/a&gt;. Cadillac Mountain is the highest point along
the North Atlantic seaboard (though it’s still not very high at 466 meters).&lt;/p&gt;

&lt;div class=&quot;embed-container&quot;&gt;
  &lt;iframe frameborder=&quot;0&quot; allowtransparency=&quot;true&quot; scrolling=&quot;no&quot; src=&quot;https://www.strava.com/activities/1917163320/embed/31b00d9d51ec1a74590987901c80c1fd214d39ec&quot;&gt;
  &lt;/iframe&gt;
&lt;/div&gt;

&lt;p&gt;The weather wasn’t great to start, but the views were still worth the effort.&lt;/p&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2018/10/acadia/cadillac-1.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2018/10/acadia/cadillac-1.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2018/10/acadia/cadillac-2.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2018/10/acadia/cadillac-2.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;p&gt;Some pretty strong winds had the clouds blown away in no time!&lt;/p&gt;

&lt;video style=&quot;max-width: 100%; display: block;&quot; autoplay=&quot;&quot; loop=&quot;&quot; muted=&quot;&quot;&gt;
  &lt;source src=&quot;/public/images/2018/10/acadia/cadillac-3.webm&quot; type=&quot;video/webm; codecs=vp9&quot; /&gt;
&lt;/video&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2018/10/acadia/cadillac-4.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2018/10/acadia/cadillac-4.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2018/10/acadia/cadillac-5.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2018/10/acadia/cadillac-5.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;p&gt;The last part of the loop went down part of the &lt;a href=&quot;https://www.alltrails.com/trail/us/maine/a-murray-young-path-via-canon-brook-and-dorr-south-ridge-trail&quot;&gt;A. Murray Young
Path&lt;/a&gt; which had amazing fall colours on display.&lt;/p&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2018/10/acadia/cadillac-6.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2018/10/acadia/cadillac-6.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2018/10/acadia/cadillac-7.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2018/10/acadia/cadillac-7.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;p&gt;The second hike for the day was &lt;a href=&quot;https://www.alltrails.com/trail/us/maine/the-beehive-loop-trail&quot;&gt;The Beehive Loop Trail&lt;/a&gt;,
plus a little of the Champlain North Ridge Trail.&lt;/p&gt;

&lt;div class=&quot;embed-container&quot;&gt;
  &lt;iframe frameborder=&quot;0&quot; allowtransparency=&quot;true&quot; scrolling=&quot;no&quot; src=&quot;https://www.strava.com/activities/1917162852/embed/b4a519b045edae60d0bd3646e2822ff4cd0358e4&quot;&gt;
  &lt;/iframe&gt;
&lt;/div&gt;

&lt;p&gt;The clouds had been well and truly blown away by this point!&lt;/p&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2018/10/acadia/beehive-1.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2018/10/acadia/beehive-1.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2018/10/acadia/beehive-2.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2018/10/acadia/beehive-2.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2018/10/acadia/beehive-3.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2018/10/acadia/beehive-3.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2018/10/acadia/beehive-4.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2018/10/acadia/beehive-4.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;p&gt;Sunset at the &lt;a href=&quot;https://acadiamagic.com/BassHarborLight.html&quot;&gt;The Bass Harbor Head Lighthouse&lt;/a&gt; was a great finish to the day.&lt;/p&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2018/10/acadia/sunset-1.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2018/10/acadia/sunset-1.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

</content>
  </entry>
  
  <entry>
    <title>Salt Lake City</title>
    <link href="/2018/10/salt-lake-city-hiking/"/>
    <updated>2018-10-15T00:00:00+00:00</updated>
    <id>/2018/10/salt-lake-city-hiking/</id>
    <category term="travel" label="Travel"></category>
    <content type="html">&lt;p&gt;Last weekend I was able to do some hiking near Salt Lake City in Utah. There
were some stunning views of &lt;a href=&quot;https://en.wikipedia.org/wiki/Great_Salt_Lake&quot;&gt;Great Salt Lake&lt;/a&gt; from the flight. The &lt;a href=&quot;https://en.wikipedia.org/wiki/Lucin_Cutoff&quot;&gt;Lucin
Cutoff&lt;/a&gt; causes differences in salinity in three parts of the
lake. The corresponding difference in algae growth is visible in the photo
below.&lt;/p&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2018/10/slc/great-salt-lake.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2018/10/slc/great-salt-lake.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;p&gt;The first hike we did on Friday was the &lt;a href=&quot;https://www.alltrails.com/trail/us/utah/mount-olympus-trail&quot;&gt;Mount Olympus trail&lt;/a&gt;:&lt;/p&gt;

&lt;div class=&quot;embed-container&quot;&gt;
  &lt;iframe frameborder=&quot;0&quot; allowtransparency=&quot;true&quot; scrolling=&quot;no&quot; src=&quot;https://www.strava.com/activities/1900970223/embed/4221c964a0e393669ad30dd24af96870ca6ed757&quot;&gt;
  &lt;/iframe&gt;
&lt;/div&gt;

&lt;p&gt;It was a long, steep climb but the views from the top were worth it!&lt;/p&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2018/10/slc/summit-view-mountains.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2018/10/slc/summit-view-mountains.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2018/10/slc/summit-view-clouds.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2018/10/slc/summit-view-clouds.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;p&gt;The group I was with continued on to Lake Tahoe on Saturday, but I stayed in
the area to do a couple more hikes. First up was the &lt;a href=&quot;https://www.alltrails.com/trail/us/utah/lake-blanche-trail&quot;&gt;Lake Blanche
Trail&lt;/a&gt;:&lt;/p&gt;

&lt;div class=&quot;embed-container&quot;&gt;
  &lt;iframe frameborder=&quot;0&quot; allowtransparency=&quot;true&quot; scrolling=&quot;no&quot; src=&quot;https://www.strava.com/activities/1902668365/embed/8951e71c047d8bef47a4d2c306a7173d803fd838&quot;&gt;
  &lt;/iframe&gt;
&lt;/div&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2018/10/slc/lake-blanche-1.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2018/10/slc/lake-blanche-1.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2018/10/slc/lake-blanche-2.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2018/10/slc/lake-blanche-2.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2018/10/slc/lake-blanche-3.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2018/10/slc/lake-blanche-3.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2018/10/slc/lake-blanche-4.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2018/10/slc/lake-blanche-4.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;p&gt;After Lake Blanche was &lt;a href=&quot;https://www.alltrails.com/trail/us/utah/bells-canyon-trail-to-lower-falls&quot;&gt;Bells Canyon Trail&lt;/a&gt;:&lt;/p&gt;

&lt;div class=&quot;embed-container&quot;&gt;
  &lt;iframe frameborder=&quot;0&quot; allowtransparency=&quot;true&quot; scrolling=&quot;no&quot; src=&quot;https://www.strava.com/activities/1903069395/embed/394548f676a830e5f86f27f2d3ea8c6e58fdfadc&quot;&gt;
  &lt;/iframe&gt;
&lt;/div&gt;

&lt;p&gt;This trail started out looking very different to the snow that was at Lake
Blanche, but there was lots of snow on the trail by the top.&lt;/p&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2018/10/slc/bells-canyon-2.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2018/10/slc/bells-canyon-2.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2018/10/slc/bells-canyon-3.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2018/10/slc/bells-canyon-3.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2018/10/slc/bells-canyon-4.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2018/10/slc/bells-canyon-4.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2018/10/slc/bells-canyon-5.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2018/10/slc/bells-canyon-5.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2018/10/slc/bells-canyon-7.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2018/10/slc/bells-canyon-7.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;p&gt;I’m happy anywhere aspen leaves are shaking in the wind!&lt;/p&gt;

&lt;!-- ffmpeg -ss 00:00:04 -i 20181013_165624.mp4 -t 00:00:05 -vcodec libvpx-vp9 -b:v 700K -filter:v scale=-1:480 -threads 4 -an bells-canyon-6.webm  --&gt;
&lt;video style=&quot;max-width: 100%; display: block;&quot; autoplay=&quot;&quot; loop=&quot;&quot; muted=&quot;&quot;&gt;
  &lt;source src=&quot;/public/images/2018/10/slc/bells-canyon-6.webm&quot; type=&quot;video/webm; codecs=vp9&quot; /&gt;
&lt;/video&gt;

</content>
  </entry>
  
  <entry>
    <title>Alaska</title>
    <link href="/2018/10/alaska-denali/"/>
    <updated>2018-10-02T00:00:00+00:00</updated>
    <id>/2018/10/alaska-denali/</id>
    <category term="travel" label="Travel"></category>
    <content type="html">&lt;p&gt;I flew into Anchorage after work on Thursday night, landing at a reasonable
time thanks to Alaska being four hours behind Eastern Time. We stayed in
Anchorage on Thursday, did some work from there in the morning and drove up
towards Denali National Park on Friday afternoon.&lt;/p&gt;

&lt;p&gt;Before leaving Alaska, we stopped at an outdoor store to buy some bear
deterrent spray.  This &lt;a href=&quot;https://www.nps.gov/media/video/view.htm?id=565AC921-1DD8-B71B-0BCC2B0E7BF552A6&quot;&gt;National Park Service
video&lt;/a&gt;
convinced us, though it was unlikely we’d run into a grizzly on the hikes we
had planned. Neither of us fancied running into a male bear given they can tip
the scales at 680 kg and stand 3 m tall.&lt;/p&gt;

&lt;p&gt;The drive was nice, we were lucky with the weather for the whole
weekend. We did a couple of short hikes on the way, at &lt;a href=&quot;https://www.alltrails.com/trail/us/alaska/thunderbird-falls-trail&quot;&gt;Thunderbird
Falls&lt;/a&gt; and
&lt;a href=&quot;https://www.alltrails.com/trail/us/alaska/little-coal-creek-trail&quot;&gt;Little Coal
Creek&lt;/a&gt;
before arriving at our accomodation for Friday and Saturday nights. On Friday I
saw a little of the &lt;a href=&quot;https://en.wikipedia.org/wiki/Aurora&quot;&gt;northern lights&lt;/a&gt;;
our host woke us up as they were out. When he woke me up I raced outside in my
pajamas with a jacket on top which was inadequate given the weather! In
hindsight I wish I’d gotten dressed and stayed out there longer. It
was a bit bright where I was standing so didn’t get any good photos.&lt;/p&gt;

&lt;p&gt;We were staying about 35 minutes south of the park entrance, so we still had a
short way to go on Saturday morning. We ended up driving further north in
search of coffee, and ended up at the nearest ‘large town’ of Healy (population
around 1,000) where we found somewhere that was still open. We drove through a
few small communities that were all boarded up for the winter which was bizarre
to see. A lot of the businesses shut down completely and the people
working there move south to somewhere warmer for the winter!&lt;/p&gt;

&lt;p&gt;The drive along the eastern edge of Denali National Park featured some
breathtaking views of the mountains. Denali Mountain was almost always &lt;a href=&quot;https://photos.google.com/share/AF1QipMhytWglc3XpWNn8PFJwqoQ7qIiZmrJFTtFrrmQF6YaogNr7nujWWSgvXp8ZsmccA/photo/AF1QipMP-eZikMVqg2pysqkkJuWkJh8akCdWUQlxo_uk?key=R0hiU2hjRm1VQ0swa19rSFRLZkQ3d0lrdEkwa3N3&quot;&gt;visible
in the
distance&lt;/a&gt;.
It’s the highest mountain peak in North America, with a summit of 6,190 m (for
reference, the highest mountain in Australian peaks at 2,228 m). The upper half
is permanently snowy.&lt;/p&gt;

&lt;p&gt;The first hike was the &lt;a href=&quot;https://www.alltrails.com/trail/us/alaska/savage-alpine-trail--2?u=m&quot;&gt;Savage Alpine
Trail&lt;/a&gt;,
the &lt;a href=&quot;https://photos.google.com/share/AF1QipMhytWglc3XpWNn8PFJwqoQ7qIiZmrJFTtFrrmQF6YaogNr7nujWWSgvXp8ZsmccA/photo/AF1QipNgwJdv3bLRuribYWjvwO2HPx9kTTeTSbWUnCVb?key=R0hiU2hjRm1VQ0swa19rSFRLZkQ3d0lrdEkwa3N3&quot;&gt;first
photo&lt;/a&gt;
I took on the hike was of a ‘bears frequent this area’ warning sign so we were
happy to have the spray. It was super windy in some parts, here’s a
&lt;a href=&quot;https://photos.google.com/share/AF1QipMhytWglc3XpWNn8PFJwqoQ7qIiZmrJFTtFrrmQF6YaogNr7nujWWSgvXp8ZsmccA/photo/AF1QipPgFoAbKgbW3cwH8HNqhW9WMrea1xRiI_JofiTi?key=R0hiU2hjRm1VQ0swa19rSFRLZkQ3d0lrdEkwa3N3&quot;&gt;video&lt;/a&gt;
which tries to capture it (turn your volume down before opening it).  After the
hike we drove into the park until reaching the point where the road is closed
for the winter at the &lt;a href=&quot;https://en.wikipedia.org/wiki/Teklanika_River&quot;&gt;Teklanika
River&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;On the way out we got our wish of seeing a bear from a safe distance, I’m
glad we got to see one in the wild. It’s a fair distance in &lt;a href=&quot;https://photos.google.com/share/AF1QipMhytWglc3XpWNn8PFJwqoQ7qIiZmrJFTtFrrmQF6YaogNr7nujWWSgvXp8ZsmccA/photo/AF1QipMZyHRJeh6Xoa0yisqM_ucVYTdVKBOkgEunNb3l?key=R0hiU2hjRm1VQ0swa19rSFRLZkQ3d0lrdEkwa3N3&quot;&gt;this
video&lt;/a&gt;,
but it gives you some idea of the size. A group of people assembled to watch
and as you can see about half way through the video it must have got a bit
spooked! We didn’t do loads more on Saturday, but did head out again late at
night to try and see the northern lights.&lt;/p&gt;

&lt;p&gt;Sunday was a late start, but we did a full on hike at &lt;a href=&quot;https://www.alltrails.com/trail/us/alaska/bison-gulch?u=m&quot;&gt;Bison
Gulch&lt;/a&gt; (a ‘gulch’ is
the name for a valley formed by erosion). I recorded the hike &lt;a href=&quot;https://www.strava.com/activities/1877069065&quot;&gt;on
Strava&lt;/a&gt; and plotted it on Google
Maps:&lt;/p&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2018/10/alaska/bison-gulch.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2018/10/alaska/bison-gulch.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;p&gt;Photos from the hike start
&lt;a href=&quot;https://photos.google.com/share/AF1QipMhytWglc3XpWNn8PFJwqoQ7qIiZmrJFTtFrrmQF6YaogNr7nujWWSgvXp8ZsmccA/photo/AF1QipNaEyHXtZVEx8SJVK4PeZgo0kMr-Q6C4eqlcEQk?key=R0hiU2hjRm1VQ0swa19rSFRLZkQ3d0lrdEkwa3N3&quot;&gt;here&lt;/a&gt;
in the album. It was pretty brutal, we climbed 1,259 m and a lot of that
towards the end was over very loose shale. Here’s one of us up near the top:&lt;/p&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2018/10/alaska/near-summit.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2018/10/alaska/near-summit.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;p&gt;It’s lucky we went when we did; a couple of weeks later and it would have been
rather chilly! I think the snow there is from some early falls a week before we
arrived. We were ridiculously fortunate with the weather. It was relatively
warm, with clear skies. The whole place seemed so remote, the air was super
fresh and the stars were all out. Other than the bear, we also saw a couple of
moose and a pair of mountain goats.&lt;/p&gt;

&lt;p&gt;All the photos from the trip are in an album on &lt;a href=&quot;https://photos.app.goo.gl/CkW6bCpwjiaRmYFU7&quot;&gt;Google
Photos&lt;/a&gt; (some of the links above
should jump to certain spots in the album).&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>Philadelphia</title>
    <link href="/2018/09/philadelphia/"/>
    <updated>2018-09-23T00:00:00+00:00</updated>
    <id>/2018/09/philadelphia/</id>
    <category term="travel" label="Travel"></category>
    <content type="html">&lt;p&gt;This weekend I visited Philadelphia, Pennsylvania’s largest city. It has plenty
of historic sites from the American Revolution, as well as a fairly famous
prison and the Philadelphia Museum of Art which is potentially better known for
“Rocky” than the art.&lt;/p&gt;

&lt;p&gt;I didn’t have big plans (I was looking for a relatively quiet weekend after the
week tripping around CO/UT), but still had a busy Saturday. The day started
with a train to the &lt;a href=&quot;https://www.visitphilly.com/things-to-do/attractions/wissahickon-valley-park/&quot;&gt;Wissahickon Valley
Park&lt;/a&gt;.
From there I did some hiking/walking through Wissahickon Valley and on to
Boathouse Row, along the &lt;a href=&quot;https://en.wikipedia.org/wiki/Schuylkill_River&quot;&gt;Schuylkill
River&lt;/a&gt;. That leg (recorded &lt;a href=&quot;https://www.strava.com/activities/1858425404&quot;&gt;on
Strava&lt;/a&gt;) came to 18.5 km, and the
walk downtown came to roughly another 12 km, so I definitely got my steps in
for the day! Here’s the route I took through the city centre:&lt;/p&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2018/09/philly/downtown-route.png&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2018/09/philly/downtown-route.png&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;p&gt;That took me past &lt;a href=&quot;https://www.visitphilly.com/things-to-do/attractions/boathouse-row/&quot;&gt;Boathouse
Row&lt;/a&gt;,
Philadelphia Museum of Art, &lt;a href=&quot;https://www.easternstate.org/&quot;&gt;Eastern State
Penitentiary&lt;/a&gt;, Washington Monument Fountain,
Rodin Museum, Parkway Central Library, Logan Square, Love Park, &lt;a href=&quot;https://readingterminalmarket.org/&quot;&gt;Reading
Terminal Market&lt;/a&gt;, &lt;a href=&quot;https://www.sonnyscheesesteaks.com/&quot;&gt;Sonny’s Famous
Steaks&lt;/a&gt; for a Philly cheesesteak, and a
load of spots in &lt;a href=&quot;https://www.nps.gov/inde/index.htm&quot;&gt;Independence National Historical
Park&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The walk from Wissahickon Valley also included lots of historic buildings and
bridges. A few highlights of the day follow.&lt;/p&gt;

&lt;h2 id=&quot;statue-of-tedyuscung&quot;&gt;Statue of Tedyuscung&lt;/h2&gt;

&lt;p&gt;At a point along the trail in Wissahickon Valley, there is a statue positioned
fairly high up the valley, showing a Native American looking out over the
valley. It’s a fairly huge statue, and I didn’t expect to come across it, but
I’ve done some reading about it since. The history of the sculpture is here
(the marble version I saw was dedicated in 1902), though apparently it’s a bit
contentions with one local calling it &lt;a href=&quot;https://hiddencityphila.org/2013/01/a-monument-to-ignorance/&quot;&gt;“a monument to
ignorance”&lt;/a&gt;.&lt;/p&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2018/09/philly/tedyuscung.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2018/09/philly/tedyuscung.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;h2 id=&quot;eastern-state-penitentiary&quot;&gt;Eastern State Penitentiary&lt;/h2&gt;

&lt;p&gt;Eastern State Penitentiary was the first major prison based on the principle of
keeping prisoners in solitary confinement. The idea was the inmates would
practice penance through silent reflection upon their crimes and behaviour. The
whole prison is designed around this idea. Inmates never saw anyone for the
entire duration of their sentence. The walls are solid and at least a foot
thick. Each prisoner has their own exercise yard. The guards even wore socks
over their shoes so the silence wasn’t disturbed. This understandably went
fairly terribly, with lots of inmates mental health taking a hit. The prison
operated using solitary confinement from 1829 until 1913, and it closed in
1971.&lt;/p&gt;

&lt;p&gt;The city council intended to redevelop it, but the site was abandoned for
around a decade and fell to ruin. It was ‘stabilised’ before opening to the
public as a museum in 1994, but large parts of the prison are as they were
after the period of abandonment:&lt;/p&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2018/09/philly/20180922_115959.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2018/09/philly/20180922_115959.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2018/09/philly/20180922_121211.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2018/09/philly/20180922_121211.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2018/09/philly/20180922_124950.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2018/09/philly/20180922_124950.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;p&gt;There was also an exhibit at the end of the tour about prisons today and mass
incarceration, which was pretty sobering.&lt;/p&gt;

&lt;p&gt;More photos from the day are in an album on &lt;a href=&quot;https://photos.app.goo.gl/GQD5KDWshcHDGk64A&quot;&gt;Google
Photos&lt;/a&gt;.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>Colorado &amp; Utah hiking</title>
    <link href="/2018/09/colorado-and-east-utah-hiking/"/>
    <updated>2018-09-16T00:00:00+00:00</updated>
    <id>/2018/09/colorado-and-east-utah-hiking/</id>
    <category term="travel" label="Travel"></category>
    <content type="html">&lt;p&gt;I attended &lt;a href=&quot;http://exploreddd.com/&quot;&gt;Explore DDD&lt;/a&gt; in Denver again this year,
&lt;a href=&quot;/2017/09/denver-rocky-mountains/&quot;&gt;after enjoying the conference and Denver itself so much last year&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This year I took a couple of days off work before the conference, and planned a
road trip to do some hiking in the area. I made it to one of the parks near
Boulder, five national parks in the area, and a quick hike near Colorado
Springs on the way back to Denver.&lt;/p&gt;

&lt;div class=&quot;embed-container&quot;&gt;
  &lt;iframe src=&quot;https://www.google.com/maps/d/embed?mid=1XJPhd8-ZP3TWR_VysoSY3jKWchkrHLMT&quot; width=&quot;640&quot; height=&quot;480&quot;&gt;
  &lt;/iframe&gt;
&lt;/div&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;It was a fun week of hiking (89 km) and driving (2,261 km), with a little planning required:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.alltrails.com/&quot;&gt;AllTrails&lt;/a&gt; worked really well for organising
hikes. I paid for a lifetime Pro membership, which meant I could download
trails for offline use (very handy in the more remote parks)&lt;/li&gt;
  &lt;li&gt;Airbnb rooms near the hiking spots meant I could get up early and beat the
crowds &amp;amp; heat&lt;/li&gt;
  &lt;li&gt;An &lt;a href=&quot;https://www.nps.gov/planyourvisit/passes.htm&quot;&gt;America the Beautiful Pass&lt;/a&gt;
covered the entrance fees at all the national parks&lt;/li&gt;
  &lt;li&gt;A &lt;a href=&quot;https://www.rei.com/product/896905/osprey-raptor-14-hydration-pack-3-liters&quot;&gt;3L Osprey Raptor 14
pack&lt;/a&gt;
kept me hydrated&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.rei.com/product/119906/keen-targhee-iii-low-wp-hiking-shoes-mens&quot;&gt;KEEN Targhee III Low WP hiking
shoes&lt;/a&gt;
ensured that my feet stayed dry and had decent support&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;boulder-open-space&quot;&gt;Boulder Open Space&lt;/h2&gt;

&lt;p&gt;First up was Chautauqua Park in Boulder, CO. A couple of colleagues based in
Denver/Boulder recommended hiking here, and I’m glad I listened.&lt;/p&gt;

&lt;p&gt;The route below is a combination of the &lt;a href=&quot;https://www.alltrails.com/explore/trail/us/colorado/royal-arch-trail&quot;&gt;Royal Arch
Trail&lt;/a&gt;,
&lt;a href=&quot;https://www.alltrails.com/explore/trail/us/colorado/first-and-second-flatiron-hike&quot;&gt;First and Second Flatiron
Loop&lt;/a&gt;
and the &lt;a href=&quot;https://www.alltrails.com/explore/trail/us/colorado/green-mountain-loop&quot;&gt;Green Mountain
Loop&lt;/a&gt;.&lt;/p&gt;

&lt;div class=&quot;embed-container&quot;&gt;
  &lt;iframe frameborder=&quot;0&quot; allowtransparency=&quot;true&quot; scrolling=&quot;no&quot; src=&quot;https://www.strava.com/activities/1826180233/embed/ad5917711b8d46570bd7a50d95d43120ed0af8fc&quot;&gt;
  &lt;/iframe&gt;
&lt;/div&gt;

&lt;p&gt;The hike had amazing views of the
&lt;a href=&quot;https://en.wikipedia.org/wiki/Flatirons&quot;&gt;Flatirons&lt;/a&gt; &amp;amp; Royal Arch:&lt;/p&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2018/09/hiking/20180907_100708.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2018/09/hiking/20180907_100708.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2018/09/hiking/20180907_105437.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2018/09/hiking/20180907_105437.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2018/09/hiking/20180907_123823.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2018/09/hiking/20180907_123823.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;h2 id=&quot;rocky-mountain-national-park&quot;&gt;Rocky Mountain National Park&lt;/h2&gt;

&lt;p&gt;I visited the &lt;a href=&quot;https://www.nps.gov/romo/index.htm&quot;&gt;Rocky Mountains National
Park&lt;/a&gt; last year, but as you can see from
the earlier post linked above, the weather was a little different this time.&lt;/p&gt;

&lt;p&gt;I was lucky enough to drive past a fairly huge elk chilling very close to the
road.&lt;/p&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2018/09/hiking/20180908_071649.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2018/09/hiking/20180908_071649.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;p&gt;Most of the hiking I did was in the Bear Lake area, on the &lt;a href=&quot;https://www.alltrails.com/explore/trail/us/colorado/emerald-lake-trail&quot;&gt;Emerald
Lake&lt;/a&gt;
and &lt;a href=&quot;https://www.alltrails.com/explore/trail/us/colorado/sky-pond-via-glacier-gorge-trail&quot;&gt;Sky Pond via Glacier
Gorge&lt;/a&gt;
trails.&lt;/p&gt;

&lt;div class=&quot;embed-container&quot;&gt;
  &lt;iframe frameborder=&quot;0&quot; allowtransparency=&quot;true&quot; scrolling=&quot;no&quot; src=&quot;https://www.strava.com/activities/1828596174/embed/c73a156c2f567edc61b0dcb1d0e1cd9d5735ae04&quot;&gt;
  &lt;/iframe&gt;
&lt;/div&gt;

&lt;p&gt;The mountain lakes &amp;amp; aspens were spectacular:&lt;/p&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2018/09/hiking/20180908_081514.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2018/09/hiking/20180908_081514.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2018/09/hiking/20180908_084608.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2018/09/hiking/20180908_084608.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2018/09/hiking/20180908_101009.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2018/09/hiking/20180908_101009.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2018/09/hiking/20180908_121445.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2018/09/hiking/20180908_121445.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;p&gt;There was a very friendly marmot up near Sky Pond, though he was probably just
looking for food:&lt;/p&gt;

&lt;!-- ffmpeg -i *.mp4 -vcodec libvpx-vp9 -b:v 700K -filter:v scale=-1:480 -threads 4 -an marmot.webm --&gt;

&lt;video style=&quot;width: 100%; height: 100%;&quot; autoplay=&quot;&quot; loop=&quot;&quot; muted=&quot;&quot;&gt;
  &lt;source src=&quot;/public/images/2018/09/hiking/marmot.webm&quot; type=&quot;video/webm; codecs=vp9&quot; /&gt;
&lt;/video&gt;

&lt;h2 id=&quot;arches-national-park&quot;&gt;Arches National Park&lt;/h2&gt;

&lt;p&gt;Sunday saw me driving from Boulder to &lt;a href=&quot;https://www.nps.gov/arch/index.htm&quot;&gt;Arches National
Park&lt;/a&gt; in Utah, through Grand Valley.&lt;/p&gt;

&lt;p&gt;The &lt;a href=&quot;https://www.alltrails.com/explore/trail/us/utah/devils-garden-loop-trail-with-7-arches&quot;&gt;Devils
Garden&lt;/a&gt;
trail was amazing, with the 88 meter Landscape Arch a highlight.&lt;/p&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2018/09/hiking/20180909_160527.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2018/09/hiking/20180909_160527.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;div class=&quot;embed-container&quot;&gt;
  &lt;iframe frameborder=&quot;0&quot; allowtransparency=&quot;true&quot; scrolling=&quot;no&quot; src=&quot;https://www.strava.com/activities/1831433196/embed/0b453ca28509905f90e9ae3caf8278529fa44172&quot;&gt;
  &lt;/iframe&gt;
&lt;/div&gt;

&lt;h2 id=&quot;canyonlands-national-park&quot;&gt;Canyonlands National Park&lt;/h2&gt;

&lt;p&gt;Next up was &lt;a href=&quot;https://www.nps.gov/cany/index.htm&quot;&gt;Canyonlands National Park&lt;/a&gt;. I
stayed near La Sal on Sunday night, which made the Needles section of the park
a better option than heading back north to Island in the Sky.&lt;/p&gt;

&lt;p&gt;The &lt;a href=&quot;https://www.alltrails.com/explore/trail/us/utah/chesler-park&quot;&gt;Chesler Park
Loop&lt;/a&gt; was one of
the highlights of the whole trip. The landscape looks other-wordly at times,
and it was a lightly trafficked trail.&lt;/p&gt;

&lt;div class=&quot;embed-container&quot;&gt;
  &lt;iframe frameborder=&quot;0&quot; allowtransparency=&quot;true&quot; scrolling=&quot;no&quot; src=&quot;https://www.strava.com/activities/1833122015/embed/13de98620c7a67cec52cf774f35e6f55f65b668d&quot;&gt;
  &lt;/iframe&gt;
&lt;/div&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2018/09/hiking/20180910_085945.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2018/09/hiking/20180910_085945.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2018/09/hiking/20180910_093206.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2018/09/hiking/20180910_093206.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2018/09/hiking/20180910_095407.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2018/09/hiking/20180910_095407.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2018/09/hiking/20180910_103511.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2018/09/hiking/20180910_103511.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;h2 id=&quot;mesa-verde-national-park&quot;&gt;Mesa Verde National Park&lt;/h2&gt;

&lt;p&gt;After staying in Cortez on Monday night, I visited &lt;a href=&quot;https://www.nps.gov/meve/index.htm&quot;&gt;Mesa Verde National
Park&lt;/a&gt;, a UNESCO World Heritage Site. The
park is best known for the cliff dwellings built by the &lt;a href=&quot;https://en.wikipedia.org/wiki/Ancestral_Puebloans&quot;&gt;Ancestral
Puebloans&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I managed to get in early and score a ticket to a guided tour of &lt;a href=&quot;https://en.wikipedia.org/wiki/Cliff_Palace&quot;&gt;Cliff
Palace&lt;/a&gt;, a dwelling built around
year 1200.&lt;/p&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2018/09/hiking/20180911_085132.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2018/09/hiking/20180911_085132.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2018/09/hiking/20180911_101217.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2018/09/hiking/20180911_101217.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;p&gt;Other than the Cliff Palace tour, the only hike I did here was &lt;a href=&quot;https://www.alltrails.com/explore/trail/us/colorado/petroglyph-point-trail&quot;&gt;Petroglyph
Point&lt;/a&gt;,
which passes a large &lt;a href=&quot;https://en.wikipedia.org/wiki/Petroglyph&quot;&gt;petroglyph&lt;/a&gt;
panel. The carvings were likely made around the same time as the cliff
dwellings were built.&lt;/p&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2018/09/hiking/20180911_114156.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2018/09/hiking/20180911_114156.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;h2 id=&quot;great-sand-dunes-national-park&quot;&gt;Great Sand Dunes National Park&lt;/h2&gt;

&lt;p&gt;The final national park I visited was &lt;a href=&quot;https://www.nps.gov/grsa/index.htm&quot;&gt;Great Sand
Dunes&lt;/a&gt;. This was a rushed visit, but I
wanted to make a stop in the park to see the contrast of sand dunes and
mountains. In my mind dunes belong in deserts or at the coast, not at 8,200
feet elevation in the foothills of mountains.&lt;/p&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2018/09/hiking/20180911_174442.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2018/09/hiking/20180911_174442.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;
</content>
  </entry>
  
  <entry>
    <title>Zion National Park and Las Vegas</title>
    <link href="/2018/06/zion-national-park-and-las-vegas/"/>
    <updated>2018-06-23T00:00:00+00:00</updated>
    <id>/2018/06/zion-national-park-and-las-vegas/</id>
    <category term="travel" label="Travel"></category>
    <content type="html">&lt;p&gt;Last weekend a I took a couple of days off to see some of the western United
States, with a visit to &lt;a href=&quot;https://en.wikipedia.org/wiki/Zion_National_Park&quot;&gt;Zion National
Park&lt;/a&gt; and &lt;a href=&quot;https://en.wikipedia.org/wiki/Las_Vegas&quot;&gt;Las
Vegas&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Zion National Park is absolutely stunning. We did a couple of hikes, the first
was to the peak of Angels Landing, a 454 m high rock formation (total elevation
1,760 m). The trail was built in 1926 and is cut into solid rock most of the
way. It’s only 3.9 km to the top, but it felt much longer given the elevation
and the temperature (it was about 40 °C).&lt;/p&gt;

&lt;div class=&quot;embed-container&quot;&gt;
  &lt;iframe frameborder=&quot;0&quot; allowtransparency=&quot;true&quot; scrolling=&quot;no&quot; src=&quot;https://www.strava.com/activities/1657750517/embed/9db6088168e13072810be6087f41781930c9bd25&quot;&gt;
  &lt;/iframe&gt;
&lt;/div&gt;

&lt;p&gt;The photo below was taken from somewhere near the start of the trail, Angels
Landing is the peak in the foreground of the photo on the left side.&lt;/p&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2018/06/zion-national-park-and-las-vegas/20180622_124315.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2018/06/zion-national-park-and-las-vegas/20180622_124315.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;p&gt;The view from the top was worth it though!&lt;/p&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2018/06/zion-national-park-and-las-vegas/20180622_141814.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2018/06/zion-national-park-and-las-vegas/20180622_141814.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2018/06/zion-national-park-and-las-vegas/20180622_142819.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2018/06/zion-national-park-and-las-vegas/20180622_142819.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2018/06/zion-national-park-and-las-vegas/20180622_143415.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2018/06/zion-national-park-and-las-vegas/20180622_143415.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;p&gt;Given how hot it was on the first day, we set out a little earlier for our
second hike to &lt;a href=&quot;https://utah.com/hiking/zion-national-park/observation-point-trail&quot;&gt;Observation
Point&lt;/a&gt;. The
line for the buses into the Canyon was already quite long, so we took the
opportunity to walk the Pa’rus Trail to the second bus stop.&lt;/p&gt;

&lt;div class=&quot;embed-container&quot;&gt;
  &lt;iframe frameborder=&quot;0&quot; allowfullscreen=&quot;&quot; src=&quot;https://www.google.com/maps/embed/v1/directions?key=AIzaSyD6cA8LWv7uQJ1xjY-0JRY5EUZmYQ4c5tM&amp;amp;mode=walking&amp;amp;maptype=satellite&amp;amp;waypoints=37.206516,-112.979377|37.212537,-112.976610&amp;amp;origin=37.2018188,-112.9867853&amp;amp;destination=37.2181360,-112.9740688&quot;&gt;
  &lt;/iframe&gt;
&lt;/div&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;I’m glad the buses were full, as the Pa’rus Trail provided some amazing views
along a fairly flat and safe path. It was nice to have a casual stroll and look
around without needing to worry about veering off the track!&lt;/p&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2018/06/zion-national-park-and-las-vegas/20180623_074657.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2018/06/zion-national-park-and-las-vegas/20180623_074657.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2018/06/zion-national-park-and-las-vegas/20180623_081118.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2018/06/zion-national-park-and-las-vegas/20180623_081118.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2018/06/zion-national-park-and-las-vegas/20180623_082517.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2018/06/zion-national-park-and-las-vegas/20180623_082517.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2018/06/zion-national-park-and-las-vegas/20180623_083314.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2018/06/zion-national-park-and-las-vegas/20180623_083314.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;p&gt;The walk up to Observation Point runs through Echo Canyon Passage, which was a
nice change of landscape and the canyon walls also offered some protection from
the sun.&lt;/p&gt;

&lt;div class=&quot;embed-container&quot;&gt;
  &lt;iframe frameborder=&quot;0&quot; allowtransparency=&quot;true&quot; scrolling=&quot;no&quot; src=&quot;https://www.strava.com/activities/1657750209/embed/fecc7c4af20cb5f69ef4773f137cab65032c7ab9&quot;&gt;
  &lt;/iframe&gt;
&lt;/div&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2018/06/zion-national-park-and-las-vegas/20180623_093726.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2018/06/zion-national-park-and-las-vegas/20180623_093726.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;p&gt;Observation Point itself made the hike worthwhile, it’s a great vantage point
for almost all of Zion Canyon.&lt;/p&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2018/06/zion-national-park-and-las-vegas/20180623_105852.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2018/06/zion-national-park-and-las-vegas/20180623_105852.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;p&gt;We were all flying out of Las Vegas, so on Sunday afternoon we drove back to
Las Vegas and explored there a bit. It was roughly what I expected - lots of
bright lights and tacky touristy things 🤣. The Fountains of Bellagio were
pretty impressive though!&lt;/p&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2018/06/zion-national-park-and-las-vegas/20180624_221610.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2018/06/zion-national-park-and-las-vegas/20180624_221610.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;
</content>
  </entry>
  
  <entry>
    <title>Travel posts</title>
    <link href="/2018/06/travel-posts/"/>
    <updated>2018-06-16T00:00:00+00:00</updated>
    <id>/2018/06/travel-posts/</id>
    <category term="software-tech" label="Software/Tech"></category>
    <content type="html">&lt;p&gt;Sometime in the next couple of days I’m going to publish a bunch of back dated
posts about travel I’ve done recently (or in some cases not so recently). A lot
of these posts are taken straight from emails I sent to family and friends at
the time I did the actual travel, I decided to post them here as &lt;a href=&quot;https://www.hanselman.com/blog/DoTheyDeserveTheGiftOfYourKeystrokes.aspx&quot;&gt;email is
where keystrokes go to
die&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This is a bit of a departure from what has been the norm on this blog so far,
and for those following via RSS I’ve introduced categories and separate feeds
for the &lt;a href=&quot;/feed/category/software-tech/&quot;&gt;Software/Tech&lt;/a&gt;
category and the &lt;a href=&quot;/feed/category/travel/&quot;&gt;Travel&lt;/a&gt;
category in addition to the &lt;a href=&quot;/feed/&quot;&gt;existing feed containing all posts&lt;/a&gt;.  If you’d rather not hear about travel posts, please update
your subscription :)&lt;/p&gt;

&lt;p&gt;Technically, the only interesting part of this is handling the images I wanted
to include in the posts. I’ve included a few images in the past, but never in a
large quantity.&lt;/p&gt;

&lt;p&gt;I use Google Photos/Drive for all my photos, and originally tried
hotlinking the photos from there. If this was supported it would have been the
best solution, as I wouldn’t have to duplicate the photos and it would be easy
to include them (though some of them are quite large). Unfortunately (though
unsurprisingly) Google Photos/Drive doesn’t support hotlinking, and any direct
links to images expire after a while.&lt;/p&gt;

&lt;p&gt;The next option was using the Google Drive ‘embed’ functionality, which
involves inserting some HTML into the post which will load an IFrame. This
worked, but:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;it looked a little clunky on desktop and didn’t scale well on mobile&lt;/li&gt;
  &lt;li&gt;a Google IFrame means Google tracking cookies&lt;/li&gt;
  &lt;li&gt;performance was poor - loading all the images on one of the travel posts
using this method resulted in a whole load of extra requests:&lt;/li&gt;
&lt;/ul&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2018/06/google-drive-iframe-performance.png&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2018/06/google-drive-iframe-performance.png&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;p&gt;I ended up committing them into the Git repository that backs this static site,
but that does mean the repo size is going to grow a lot more than it should. As
it’s just me working on this repo though, I can always use &lt;a href=&quot;https://git-scm.com/docs/git-filter-branch&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git
filter-branch&lt;/code&gt;&lt;/a&gt; as a last resort if
I do want to move the images elsewhere. To avoid bloating the repo too much and
to keep loading times low I did fairly aggressively reduce the file size with
ImageMagick:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;mogrify -sampling-factor 4:2:0 \
  -strip \
  -quality 85 \
  -interlace JPEG \
  -colorspace sRGB \
  -resize 50% \
  -auto-orient
  *
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The final change was adding lazy loading using &lt;a href=&quot;https://github.com/ApoorvSaxena/lozad.js&quot;&gt;Lozad.js&lt;/a&gt;. Thankfully I
include almost all the images on my site using a &lt;a href=&quot;https://github.com/mdjnewman/mdjnewman.github.io/blob/master/_includes/figure.html&quot;&gt;custom Jekyll
include&lt;/a&gt; so I just had to include the library and change one
file to get lazy loading across the board.&lt;/p&gt;

</content>
  </entry>
  
  <entry>
    <title>Brown County State Park &amp; Nashville, IN</title>
    <link href="/2018/05/brown-county-state-park-nashville-in/"/>
    <updated>2018-05-28T00:00:00+00:00</updated>
    <id>/2018/05/brown-county-state-park-nashville-in/</id>
    <category term="travel" label="Travel"></category>
    <content type="html">&lt;p&gt;Last week was my final week staffed in Cincinnati, so I finally got my act
together, booked an Airbnb and drove across to &lt;a href=&quot;https://en.wikipedia.org/wiki/Brown_County_State_Park&quot;&gt;Brown County State
Park&lt;/a&gt; in Indiana. I’ve
been meaning to go there for a while, as according to &lt;a href=&quot;https://www.mtbproject.com/directory/8015701/brown-county&quot;&gt;MTB
Project&lt;/a&gt; and
&lt;a href=&quot;https://www.singletracks.com/blog/mtb-trails/five2ride-best-bike-trails-near-cincinnati-oh/&quot;&gt;Singletracks&lt;/a&gt;
the state park and surrounding areas have some of the best trails in Indiana.&lt;/p&gt;

&lt;p&gt;I wasn’t disappointed - the state park is amazing. Miles of well maintained
trails (gravel, downhill flow, technical sections/rock gardens) coupled with
amazing views made the trip worthwhile.&lt;/p&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2018/05/in/20180525_154631.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2018/05/in/20180525_154631.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2018/05/in/20180525_160525.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2018/05/in/20180525_160525.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2018/05/in/20180526_125922.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2018/05/in/20180526_125922.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2018/05/in/20180526_141743.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2018/05/in/20180526_141743.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2018/05/in/20180526_142019.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2018/05/in/20180526_142019.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2018/05/in/20180526_150408.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2018/05/in/20180526_150408.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;
</content>
  </entry>
  
  <entry>
    <title>Washington DC</title>
    <link href="/2018/05/washington-dc/"/>
    <updated>2018-05-13T00:00:00+00:00</updated>
    <id>/2018/05/washington-dc/</id>
    <category term="travel" label="Travel"></category>
    <content type="html">&lt;p&gt;I’m at the airport about to head back to Cinci after a couple of days in the US
capital.&lt;/p&gt;

&lt;p&gt;It was a good trip, though I almost missed my flight thanks to leaving a bag at
security and only realising when boarding had already started. The 1 km run to
security and back while wearing boots and wondering if I was going to make it
got my heart rate up!&lt;/p&gt;

&lt;p&gt;The moment I left the airport in DC a motorcade stopped all the traffic which I
guess is a fairly regular occurrence here.&lt;/p&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2018/05/dc/motorcade.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2018/05/dc/motorcade.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;p&gt;On Friday night I walked about 8 km from my hotel past the Marine Corps
memorial, around Arlington national cemetery (you’ve probably seen this in
movies ­ rows and rows of white tombstones), across into DC, to the Lincoln
Memorial and Washington Monument, north to the White House, past the treasury
and to a local pub for a nightcap. It’s crazy how close all these attractions
are. While I was outside the White House a guy next to me said to his mate, not
too quietly, “I think I see Donald standing at the window in his underwear,
crying” at which point I burst out laughing.&lt;/p&gt;

&lt;p&gt;The big green area between the Lincoln Memorial and the Washington monument is
called the National Mall extends even further east to the US capitol building.
Its surrounded by museums, monuments, memorials and other federal buildings.&lt;/p&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2018/05/dc/marine-corps-memorial.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2018/05/dc/marine-corps-memorial.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2018/05/dc/lincoln-memorial.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2018/05/dc/lincoln-memorial.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2018/05/dc/washington-monument.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2018/05/dc/washington-monument.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;p&gt;On Saturday I caught the Metro and started at the Smithsonian National Air and
Space Museum which someone from work recommended, it was filled with really
cool stuff. There was also a fighter jet simulator there which would roll
upside down and everything, it was pretty great! It was a short run but I think
I’d have made myself sick if it was too much longer.&lt;/p&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2018/05/dc/smithsonian-air-and-space.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2018/05/dc/smithsonian-air-and-space.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;p&gt;The national art gallery was on the other side of national mall, so I went
there next. There was lots of … art. I appreciated a few things but I can
only handle so many portraits of stuffy old white dudes. The oldest painting I
saw was from 1247, and there were loads of pretty old sculptures. There was a
painting by da Vinci and more recent names I know like Andy Warhol.&lt;/p&gt;

&lt;p&gt;From there it was a short walk to the United States Capitol, which is the most
impressive building around. I was able to go inside the rotunda, but the full
tours were all booked out.&lt;/p&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2018/05/dc/capitol-selfie.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2018/05/dc/capitol-selfie.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2018/05/dc/capitol.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2018/05/dc/capitol.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2018/05/dc/capitol-rotunda.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2018/05/dc/capitol-rotunda.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;p&gt;The Library of Congress is reachable from the Capitol via a tunnel, so I went
there next - another super impressive building. Jefferson was apparently a big
reader and his collection of books was there, they weren’t all dated but some
were super old.&lt;/p&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2018/05/dc/library.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2018/05/dc/library.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2018/05/dc/library-columns.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2018/05/dc/library-columns.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;p&gt;Another Metro ride home and a run closed out Saturday. Managed 9km at just over
12 km/h (with a few stops for stretching and photos) despite the temperature
sitting at around 30°C. Theodore Roosevelt Island was really nice.&lt;/p&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2018/05/dc/ted-r-island.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2018/05/dc/ted-r-island.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;
</content>
  </entry>
  
  <entry>
    <title>New York City</title>
    <link href="/2018/05/nyc/"/>
    <updated>2018-05-09T00:00:00+00:00</updated>
    <id>/2018/05/nyc/</id>
    <category term="travel" label="Travel"></category>
    <content type="html">&lt;p&gt;I spent the last weekend in New York City, doing the tourist thing. I went with
very few plans and met up with another guy from work who has spent a year in
NYC.  Despite a several hour delay and change of airline &amp;amp; airport on the
flight there, it was a successful trip!&lt;/p&gt;

&lt;p&gt;Saturday played out as a busy day! In order:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Run in Central Park&lt;/li&gt;
&lt;/ul&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2018/05/nyc/central-park-lake.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2018/05/nyc/central-park-lake.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;
&lt;ul&gt;
  &lt;li&gt;Grand Central Station&lt;/li&gt;
&lt;/ul&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2018/05/nyc/grand-central.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2018/05/nyc/grand-central.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.thehighline.org/&quot;&gt;The High Line&lt;/a&gt; - a park that’s been built on
decommissioned overhead train tacks&lt;/li&gt;
  &lt;li&gt;Oculus - a $4 billion transit station&lt;/li&gt;
&lt;/ul&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2018/05/nyc/oculus.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2018/05/nyc/oculus.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;
&lt;ul&gt;
  &lt;li&gt;9/11 Memorial - pretty sobering to think there were two massive buildings
full of people where the monuments now stand&lt;/li&gt;
  &lt;li&gt;One World Observatory, 102 floors up&lt;/li&gt;
&lt;/ul&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2018/05/nyc/one-wtc.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2018/05/nyc/one-wtc.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2018/05/nyc/one-wtc-view.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2018/05/nyc/one-wtc-view.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;
&lt;ul&gt;
  &lt;li&gt;Stone Street - a street in the historic district with lots of old bars, it
was absolutely packed though because of Cinco de Mayo&lt;/li&gt;
&lt;/ul&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2018/05/nyc/stone-street.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2018/05/nyc/stone-street.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.deadrabbitnyc.com/about/&quot;&gt;The Dead Rabbit Grocery and Grog&lt;/a&gt;,
which won a few ‘worlds best bar’ awards in 2016&lt;/li&gt;
  &lt;li&gt;Wall St&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Trinity_Church_(Manhattan)&quot;&gt;Trinity Church&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.siferry.com/&quot;&gt;Staten island ferry&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2018/05/nyc/ferry-view.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2018/05/nyc/ferry-view.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;
&lt;ul&gt;
  &lt;li&gt;Times Square&lt;/li&gt;
  &lt;li&gt;Dinner at Ipanema&lt;/li&gt;
  &lt;li&gt;A Housewarming in Brooklyn, where we ended the day&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Sunday was a quieter day. We spent most of our time in Dumbo (Down Under the
Manhattan Bridge Overpass), an area in Brooklyn with pretty great views of the
city. We went to &lt;a href=&quot;http://www.grimaldis.com/&quot;&gt;Grimaldi’s pizza&lt;/a&gt;, which
is one of the old, amazing pizza places in NYC. A walk across the Brooklyn
Bridge closed out the weekend:&lt;/p&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2018/05/nyc/brooklyn-bridge-selfie.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2018/05/nyc/brooklyn-bridge-selfie.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;
</content>
  </entry>
  
  <entry>
    <title>Miami, Florida Keys &amp; Shark Valley in the Everglades</title>
    <link href="/2018/04/miami-keys-everglades/"/>
    <updated>2018-04-23T00:00:00+00:00</updated>
    <id>/2018/04/miami-keys-everglades/</id>
    <category term="travel" label="Travel"></category>
    <content type="html">&lt;p&gt;I spent last weekend in Miami! South Beach/South Pointe Pier was the first
stop, and the weather played along nicely.&lt;/p&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2018/04/fl/south-pointe-pier.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2018/04/fl/south-pointe-pier.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2018/04/fl/south-beach.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2018/04/fl/south-beach.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;p&gt;The nearby Art Deco Historic District had some classic Miami colours:&lt;/p&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2018/04/fl/art-deco-district.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2018/04/fl/art-deco-district.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;p&gt;I spent Friday evening wandering around Wynwood. The urban art there is
amazing, the below is just a tiny sample.&lt;/p&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2018/04/fl/wynwood-1.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2018/04/fl/wynwood-1.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2018/04/fl/wynwood-2.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2018/04/fl/wynwood-2.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2018/04/fl/wynwood-3.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2018/04/fl/wynwood-3.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2018/04/fl/wynwood-4.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2018/04/fl/wynwood-4.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2018/04/fl/wynwood-5.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2018/04/fl/wynwood-5.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2018/04/fl/wynwood-6.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2018/04/fl/wynwood-6.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2018/04/fl/wynwood-7.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2018/04/fl/wynwood-7.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2018/04/fl/wynwood-8.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2018/04/fl/wynwood-8.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;p&gt;On Saturday I drove the &lt;a href=&quot;https://en.wikipedia.org/wiki/Overseas_Highway&quot;&gt;Overseas
Highway&lt;/a&gt; from my hotel to Key West.&lt;/p&gt;

&lt;div class=&quot;embed-container&quot;&gt;
  &lt;iframe src=&quot;https://www.google.com/maps/embed/v1/directions?key=AIzaSyD6cA8LWv7uQJ1xjY-0JRY5EUZmYQ4c5tM&amp;amp;origin=Sonesta+Coconut+Grove,+Miami&amp;amp;destination=Southernmost+Point+of+the+Continental+US+Key+West&quot; allowfullscreen=&quot;&quot;&gt;
  &lt;/iframe&gt;
&lt;/div&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;The drive down was beautiful, though it’s a little bizarre being on some of the
really long bridges.&lt;/p&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2018/04/fl/overseas-highway-2.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2018/04/fl/overseas-highway-2.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2018/04/fl/overseas-highway.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2018/04/fl/overseas-highway.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;p&gt;I had to take the obligatory selfie at the Southernmost Point of the
Continental US in Key West.&lt;/p&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2018/04/fl/southernmost-point.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2018/04/fl/southernmost-point.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;p&gt;There was loads more to do in Key West, but I didn’t have loads of time given I
was doing the drive back to Miami the same day - I definitely have to visit
again!&lt;/p&gt;

&lt;p&gt;On Sunday I went to &lt;a href=&quot;https://en.wikipedia.org/wiki/Shark_Valley&quot;&gt;Shark Valley&lt;/a&gt;
in the Everglades where I hired a bike and rode a 24 km loop. There were so
many alligators!&lt;/p&gt;

&lt;video style=&quot;width: 100%; height: 100%;&quot; autoplay=&quot;&quot; loop=&quot;&quot; muted=&quot;&quot;&gt;
  &lt;source src=&quot;/public/images/2018/04/fl/alligator-trimmed.webm&quot; type=&quot;video/webm; codecs=vp9&quot; /&gt;
&lt;/video&gt;
&lt;!--
ffmpeg -ss 00:00:00 -i alligator.mp4 -t 00:00:08 -acodec copy -vcodec copy -async 1 -y alligator-trimmed.mp4
ffmpeg -i alligator-trimmed.mp4 -vcodec libvpx-vp9 -b:v 700K -filter:v scale=-1:480 -r 10 -threads 4 -an alligator-trimmed.webm
 --&gt;

&lt;p&gt;The tower at the half way point of the loop provided a good view, and was my
last stop for the day before heading to MIA and back to CVG.&lt;/p&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2018/04/fl/everglades-lookout.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2018/04/fl/everglades-lookout.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2018/04/fl/everglades-selfie.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2018/04/fl/everglades-selfie.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;
</content>
  </entry>
  
  <entry>
    <title>Dallas, Trinity River/Bishop Arts/Downtown</title>
    <link href="/2018/04/dallas/"/>
    <updated>2018-04-01T00:00:00+00:00</updated>
    <id>/2018/04/dallas/</id>
    <category term="travel" label="Travel"></category>
    <content type="html">&lt;p&gt;Yesterday I went for a walk through some of Dallas that I haven’t explored yet,
despite technically living here for about 9 months (I say technically, as a lot
of that time was spent travelling for work). I made a &lt;a href=&quot;https://goo.gl/xSA3hj&quot;&gt;rough
map&lt;/a&gt; of my walk using &lt;a href=&quot;https://onthegomap.com/&quot;&gt;On the Go
Map&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Following are a few notable points on the trip.&lt;/p&gt;

&lt;p&gt;Trinity River and the Margaret Hunt Hill Bridge:&lt;/p&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2018/04/20180331_173312.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2018/04/20180331_173312.jpg&quot; alt=&quot;Landscape shot of Trinity River&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2018/04/20180331_180027.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2018/04/20180331_180027.jpg&quot; alt=&quot;Helix-inspired arches of the Margaret Hunt Hill Bridge&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;p&gt;Lockhart Smokehouse - a reasonably famous BBQ place, where the ‘Texan
Vegetarian’ section comprises of chicken/turkey, instead of beef 🤣:&lt;/p&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2018/04/20180331_201454.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2018/04/20180331_201454.jpg&quot; alt=&quot;Lockhart smokehouse menu&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;p&gt;The delicious taster flight at &lt;a href=&quot;https://www.bishopcider.com/&quot;&gt;Bishop Cider Co&lt;/a&gt;:&lt;/p&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2018/04/20180331_192605.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2018/04/20180331_192605.jpg&quot; alt=&quot;Cider menu with 4 ciders&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;p&gt;A 30-ft eyeball in downtown Dallas, which is quite hard to miss:&lt;/p&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2018/04/20180331_220610.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2018/04/20180331_220610.jpg&quot; alt=&quot;Large plastic eyeball in a park&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;p&gt;And finally, this sign, which I feel captures so much of what it is like walking in a US
city other than New York:&lt;/p&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2018/04/20180331_172920.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2018/04/20180331_172920.jpg&quot; alt=&quot;Sign in the middle of a huge puddle saying &apos;pavement ends&apos; despite there being no discernable pavement&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;p&gt;I never did spot the pavement in that area, but at least I know not to expect one to appear now that it’s ‘ended’.&lt;/p&gt;

&lt;p&gt;The lack of people walking here continues to blow my mind. I walked an hour
from the Bishop Arts District to downtown, and didn’t walk past a single
person. A group of young guys went past in a car and one of them yelled “ain’t
y’all heard of Uber?”, further affirming my belief that everyone thought I was
crazy for walking. I guess it’s not that surprising given a couple of times the
pavement I was walking on came to a major road and just stopped, leaving me to
backtrack and find somewhere else to go.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>Vetted - tweaking importer performance</title>
    <link href="/2018/03/vetted-tweaking-importer-performance/"/>
    <updated>2018-03-03T00:00:00+00:00</updated>
    <id>/2018/03/vetted-tweaking-importer-performance/</id>
    <category term="software-tech" label="Software/Tech"></category>
    <content type="html">&lt;p&gt;Since the &lt;a href=&quot;/2018/01/vetted-importing-data/&quot;&gt;last post&lt;/a&gt;, I’ve started working on
an importer to load data from the existing Access database. Work to date is on
&lt;a href=&quot;https://github.com/mdjnewman/vetted/tree/f1253732f1c2e582fd6412a45aa75a133fa8bb78&quot;&gt;GitHub&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In the current domain model, there is a single aggregate root, the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Client&lt;/code&gt;.
The importer is written as a command line application which interacts directly
with the domain, assuming an empty database (I might get to incremental imports
in the future). At a high level, the importer currently:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Creates the clients&lt;/li&gt;
  &lt;li&gt;Adds any existing ‘notes’ about the client
    &lt;ul&gt;
      &lt;li&gt;Notes are freeform text about a client, unrelated to any particular patient or
transaction&lt;/li&gt;
      &lt;li&gt;The existing application is a little limited in what can be entered into
the main form, so notes have been used to make up the slack (e.g. in the
existing data, there are numerous clients which have an email address or fax
number in the notes field, as there is no first class input for these values)&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Adds home and mobile phone numbers&lt;/li&gt;
  &lt;li&gt;Adds the ‘most common travel distance’ as a note&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These steps are visible in the implementation of the importer:&lt;/p&gt;

&lt;div class=&quot;language-kotlin highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;vararg&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;py&quot;&gt;rows&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;accessDb&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;clientTableRows&lt;/span&gt;

    &lt;span class=&quot;kd&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;py&quot;&gt;newClientIds&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;UUID&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;createClients&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;rows&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;accessDb&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;postCodeFor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;accessDb&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stateFor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;commandGateway&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;nf&quot;&gt;allOf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;nf&quot;&gt;addClientNotes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rows&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;newClientIds&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;commandGateway&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
        &lt;span class=&quot;nf&quot;&gt;addPhoneNumbers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rows&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;newClientIds&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;commandGateway&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
        &lt;span class=&quot;nf&quot;&gt;addMostCommonDistance&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rows&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;newClientIds&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;commandGateway&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;First, clients are created, producing a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Map&lt;/code&gt; of the old client ID to the new
client ID. Once all clients have been created, all the other updates are
applied (potentially concurrently).&lt;/p&gt;

&lt;p&gt;Without giving away too much information about the existing data, the &lt;a href=&quot;https://en.wikipedia.org/wiki/Order_of_magnitude&quot;&gt;order of
magnitude&lt;/a&gt; of the existing number of clients is 3, and the total number
of events generated with the current importer implementation is at most 5x the
number of clients (one &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ClientMigratedEvent&lt;/code&gt;, up to two &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ClientNoteAddedEvent&lt;/code&gt;s
and up to two &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ClientPhoneNumberAddedEvent&lt;/code&gt;s).&lt;/p&gt;

&lt;p&gt;My first pass at the importer was taking around 80 seconds to import everything
into a PostgreSQL database. I know that &lt;a href=&quot;http://wiki.c2.com/?PrematureOptimization&quot;&gt;premature optimization is the root of
all evil&lt;/a&gt;, and that I don’t have anything resembling a
working product at the moment, but this seemed far too high. Also, it was
impacting my ability to iterate quickly with ‘production’ data, which is enough
of a reason to look for improvements.&lt;/p&gt;

&lt;p&gt;After looking at the generated schema and doing some sampling with
&lt;a href=&quot;https://visualvm.github.io/&quot;&gt;VisualVM&lt;/a&gt;, I decided there were three options to investigate:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Asynchronous processing of commands&lt;/li&gt;
  &lt;li&gt;Serialisation format changes&lt;/li&gt;
  &lt;li&gt;Generated schema changes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In order to compare a full run of the importer pre and post optimisations, I
want to be able to toggle the optimisations on/off from the command line. The
following script has the toggle properties in place, and in the sections below I
will use Spring config management to read these properties.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;PASSWORD=$(uuidgen)

docker stop vetted-postgres ; docker rm vetted-postgres

docker run \
    --publish 5432:5432/tcp \
    --name vetted-postgres \
    --env POSTGRES_PASSWORD=$PASSWORD \
    --detach \
    postgres

./gradlew build

java \
    -jar importer/build/libs/vetted-importer-0.0.1-SNAPSHOT.jar \
    --axon.use-async-command-bus=false \
    --axon.use-cbor-serializer=false \
    --spring.jpa.database-platform=org.hibernate.dialect.PostgreSQL95Dialect \
    --spring.datasource.password=$PASSWORD
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The script above will allow me to evaluate the impact of any changes I make in
a repeatable fashion.&lt;/p&gt;

&lt;h2 id=&quot;option-1---asynchronous-processing-of-commands&quot;&gt;Option 1 - Asynchronous processing of commands&lt;/h2&gt;

&lt;p&gt;I’m using the &lt;a href=&quot;http://www.axonframework.org/&quot;&gt;Axon framework&lt;/a&gt;, which handles a lot of the plumbing of
building an application based on DDD &amp;amp; CQRS principles. By default when using
the Spring auto-configuration, a &lt;a href=&quot;https://github.com/AxonFramework/AxonFramework/blob/fd88dfe/messaging/src/main/java/org/axonframework/commandhandling/SimpleCommandBus.java&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SimpleCommandBus&lt;/code&gt;&lt;/a&gt; is used
which processes commands on the calling thread.&lt;/p&gt;

&lt;p&gt;I added some configuration to use a &lt;a href=&quot;https://github.com/AxonFramework/AxonFramework/blob/fd88dfe/messaging/src/main/java/org/axonframework/commandhandling/AsynchronousCommandBus.java&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AsynchronousCommandBus&lt;/code&gt;&lt;/a&gt;
with a configurable number of threads:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;@Bean
@ConditionalOnProperty(
    value = [&quot;axon.use-async-command-bus&quot;],
    matchIfMissing = true
)
fun bus(
    transactionManager: TransactionManager,
    @Value(&quot;\${axon.command-bus.executor.pool-size}&quot;) poolSize: Int
): CommandBus {
    val bus = AsynchronousCommandBus(
        Executors.newFixedThreadPool(poolSize)
    )

    val tmi = TransactionManagingInterceptor(transactionManager)
    bus.registerHandlerInterceptor(tmi)

    return bus
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;I initially tried this configuration out with a pool size of 10. This reduced
the time for the import to around 30 seconds, which is an improvement from 80
seconds but short of an order of magnitude improvement which should be
possible. This led me to believe that there was either contention somewhere
else, or that some of the constant factors are just too high at the moment.&lt;/p&gt;

&lt;h2 id=&quot;option-2---serialisation-format-changes&quot;&gt;Option 2 - Serialisation format changes&lt;/h2&gt;

&lt;p&gt;By default, Axon will use &lt;a href=&quot;https://x-stream.github.io/&quot;&gt;XStream&lt;/a&gt; to serialise
events, which uses an XML representation. XML is quite verbose, and the &lt;a href=&quot;https://docs.axonframework.org/part4/performance-tuning.html#different-serializer-for-events&quot;&gt;Axon
documentation&lt;/a&gt; even suggests using a different
serializer.&lt;/p&gt;

&lt;p&gt;Overriding the serializer is thankfully quite easy:&lt;/p&gt;

&lt;div class=&quot;language-kotlin highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nd&quot;&gt;@Primary&lt;/span&gt;
&lt;span class=&quot;nd&quot;&gt;@Bean&lt;/span&gt;
&lt;span class=&quot;nd&quot;&gt;@ConditionalOnProperty&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;value&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;axon.use-cbor-serializer&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;matchIfMissing&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;true&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;serializer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Serializer&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;py&quot;&gt;objectMapper&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ObjectMapper&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;CBORFactory&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;objectMapper&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;findAndRegisterModules&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;objectMapper&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;setSerializationInclusion&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;NON_ABSENT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;JacksonSerializer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;objectMapper&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;I opted for using &lt;a href=&quot;https://github.com/FasterXML/jackson&quot;&gt;Jackson&lt;/a&gt; with a ‘Concise Binary Object
Representation’ (CBOR) &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;JsonFactory&lt;/code&gt;. This resulted in a ~70% reduction in size
for the serialized payload for most events. With XML:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;postgres=# select avg(length(loread(lo_open(payload::int, x&apos;40000&apos;::int), x&apos;40000&apos;::int))) from domain_event_entry;
     avg
--------------
 433.69003053
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;and with CBOR:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;     avg
--------------
 111.54379774
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This didn’t have a huge impact on the run time of the importer, but is still a
worthwhile optimisation.&lt;/p&gt;

&lt;h2 id=&quot;option-3---generated-schema-changes&quot;&gt;Option 3 - Generated schema changes&lt;/h2&gt;

&lt;p&gt;You may have noticed in the SQL statments above that the current schema is
using the PostgreSQL &lt;a href=&quot;https://www.postgresql.org/docs/10/static/largeobjects.html&quot;&gt;large objects&lt;/a&gt; functionality. From the
PostgreSQL docs:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;PostgreSQL has a large object facility, which provides stream-style access
to user data that is stored in a special large-object structure. Streaming
access is useful when working with data values that are too large to
manipulate conveniently as a whole.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If we inspect the schema that’s being generated:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;postgres=# \d domain_event_entry
     Table &quot;public.domain_event_entry&quot;
      Column      | Type | Nullable | Default
------------------+------+----------+---------
 meta_data        | oid  |          |
 payload          | oid  | not null |
 ...
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;oid&lt;/code&gt; type here is an &lt;strong&gt;o&lt;/strong&gt;bject &lt;strong&gt;id&lt;/strong&gt;entifier - a reference to a large
object which is stored externally from the table. The events we’re writing are
small enough that the overhead of reading them as separate streams is hurting
performance rather than helping.&lt;/p&gt;

&lt;p&gt;At least two people have had the same issue when using Axon with PostgreSQL, as
evidenced by the questions on &lt;a href=&quot;https://groups.google.com/forum/#!msg/axonframework/PfzLa3hBR0Y/nsie2H8kPP8J&quot;&gt;Google Groups&lt;/a&gt; and
&lt;a href=&quot;https://github.com/AxonFramework/AxonFramework/issues/445&quot;&gt;StackOverflow&lt;/a&gt;. The suggestion to customise the PostgreSQL
dialect used by Hibernate seems to work, and further reduced the runtime to
around 8 seconds.&lt;/p&gt;

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

&lt;p&gt;Based on my very rough benchmarking, the three changes above have reduced the
run time of the importer from around 80 seconds to 8 seconds. The code
is all at the link above, and the optimisations are on by default.&lt;/p&gt;

&lt;p&gt;There is surely more that can be done to improve performance, but that’s fast
enough for now!&lt;/p&gt;

</content>
  </entry>
  
  <entry>
    <title>Vetted - importing data into an event sourced system</title>
    <link href="/2018/01/vetted-importing-data/"/>
    <updated>2018-01-30T00:00:00+00:00</updated>
    <id>/2018/01/vetted-importing-data/</id>
    <category term="software-tech" label="Software/Tech"></category>
    <content type="html">&lt;p&gt;&lt;em&gt;See &lt;a href=&quot;/2017/11/vetted-a-new-hope/&quot;&gt;Vetted - a new project&lt;/a&gt; for some background.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;A task I’m going to have to tackle sooner or later is importing data from the
existing Access database. As I’m going to try my hand at event sourcing, this
raises an interesting question:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Given an existing application with data stored in an relational database &amp;amp; no
notion of events, how do you go about importing data into an event sourced
system?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2 id=&quot;options&quot;&gt;Options&lt;/h2&gt;

&lt;p&gt;At a high level, the initial options seem to be:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Try to reverse engineer/map the existing state to events&lt;/li&gt;
  &lt;li&gt;Have some sort of migration event event in your domain model (e.g.
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;FooMigrated&lt;/code&gt;) which acts as a snapshot&lt;/li&gt;
  &lt;li&gt;Run everything through your new API as commands, and allow the API
implementation to take care of creating the relevant events like normal&lt;/li&gt;
&lt;/ol&gt;

&lt;h3 id=&quot;recreating-domain-events&quot;&gt;‘Recreating’ domain events&lt;/h3&gt;

&lt;p&gt;Option one above would be nice, but seems impractical at best and is more likely
impossible. For every domain object (client, patient, payment, invoice,
vaccination etc) I’d need to try and reverse engineer the real-world happenings
that occurred to transition the object into its current state.&lt;/p&gt;

&lt;h3 id=&quot;a-migration-event-as-a-snapshot&quot;&gt;A ‘migration event’ as a snapshot&lt;/h3&gt;

&lt;p&gt;Originally when a colleague suggested this it conflicted with my understanding
of the term ‘snapshot’. To me a ‘snapshot’ has always been about collapsing an
event stream into a single event for performance reasons. When using this kind
of snapshot, the original stream of events is still available.&lt;/p&gt;

&lt;p&gt;The second kind of snapshot (which I didn’t see immediately) is a snapshot
which is used as base data. When using a snapshot as base data, the collapsed
state of the aggregate at the time the snapshot is all the information you have
about the history of the aggregate.&lt;/p&gt;

&lt;p&gt;It could also be argued that the migration is a meaningful domain event in its
own right, and should be captured explicitly. A &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CustomerMigratedEvent&lt;/code&gt; could
result in the creation of a new customer aggregate root in the same way that a
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CustomerRegisteredEvent&lt;/code&gt; does.&lt;/p&gt;

&lt;h3 id=&quot;run-all-existing-data-through-the-new-api&quot;&gt;Run all existing data through the new API&lt;/h3&gt;

&lt;p&gt;It should be possible to write a script that reads data from the existing
database, creates commands and posts those to the appropriate API. The relevant
events would ultimately be created off the back of processing the commands, so
all ‘legacy’ data should look exactly the same as anything created going
forward.&lt;/p&gt;

&lt;p&gt;The outcome is probably close to option one above, but with less manual work.&lt;/p&gt;

&lt;h2 id=&quot;next-steps&quot;&gt;Next steps&lt;/h2&gt;

&lt;p&gt;So far I’ve been spending a lot of time on the technical concepts &amp;amp; design of
an event sourced system, without doing much on the implementation side.&lt;/p&gt;

&lt;p&gt;It’s hard to build a useful conceptual domain model without considering
implementation issues, so I think it’s time I stopped debating concepts and
wrote some code.&lt;/p&gt;

&lt;p&gt;I’m planning to explore a little and gain an understanding of how building and
executing commands would differ in practice from the ‘import event’ option
above.&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;further-reading&quot;&gt;Further Reading&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://groups.google.com/forum/#!topic/dddcqrs/xUbKn8YLJfk&quot;&gt;Importing historic data into an Event Store&lt;/a&gt; on the DDD/CQRS Google Group&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://stackoverflow.com/questions/43640256/importing-data-and-event-sourcing&quot;&gt;Importing data and Event Sourcing&lt;/a&gt; on Stack Overflow&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://martinfowler.com/eaaDev/EventSourcing.html&quot;&gt;Event Sourcing&lt;/a&gt; on martinfowler.com&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;acknowledgements&quot;&gt;Acknowledgements&lt;/h2&gt;

&lt;p&gt;Thanks to Roman Safronov, Chris Rowe, Martin Fowler, Mariano Giuffrida, Jim
Barritt and Nouman Memon for taking the time to reply and/or chat about event
sourcing! Any good ideas are theirs, and errors are mine.&lt;/p&gt;

</content>
  </entry>
  
  <entry>
    <title>Vetted - choosing an appropriate license</title>
    <link href="/2017/11/vetted-licensing/"/>
    <updated>2017-11-05T00:00:00+00:00</updated>
    <id>/2017/11/vetted-licensing/</id>
    <category term="software-tech" label="Software/Tech"></category>
    <content type="html">&lt;p&gt;&lt;em&gt;See &lt;a href=&quot;/2017/11/vetted-a-new-hope/&quot;&gt;Vetted - a new project&lt;/a&gt; for some background.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I’m hoping to start pushing some code soon. Before I do, it’s a good
opportunity to do some reading into a topic that I am more ignorant of than I
should be: software licensing. The following is what I’ve learnt so far.&lt;/p&gt;

&lt;p&gt;Disclaimer: I am not a lawyer and this may be totally incorrect, and as such
should not be used as the basis for any decision ever.&lt;/p&gt;

&lt;p&gt;Once code is released as open source software, most common
OSS licenses (GPL, BSD, MIT, Apache etc) do not allow for the revocation of
rights granted under the license. This is a good thing. Imagine having to be
prepared for any open source library/framework you’re currently using become
proprietary software with no warning. Such uncertainty would severely limit the
utility of open source software.&lt;/p&gt;

&lt;p&gt;It &lt;em&gt;is&lt;/em&gt; possible for the current copyright owners to relicense their creations.
So, theoretically, any OSS software can be relicensed if all copyright owners
agree. The important part is that this relicensing does not revoke the rights
assigned under the previous license. So if I’ve released some software as open
source software, I can decide a year later to relicense it and create a
commercial version, with the following caveats:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;I still own the copyright for the entire project
    &lt;ul&gt;
      &lt;li&gt;I need to have been the sole contributor to the project, or to have
ensured that contributors have assigned copyright to me for their work&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;The existing rights assigned under the OSS license remain in place
    &lt;ul&gt;
      &lt;li&gt;If the license permits, anyone can fork the project at this point
and develop/use their own version&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Given what I’ve learned above, I’m planning to license the project under an OSS
license, but I won’t accept any contributions until I’ve got some kind of
Contributor License Agreement (CLA) in place.&lt;/p&gt;

&lt;p&gt;This is likely the first of many posts where it might seem I’m researching a
topic and deliberating a little excessively, given I have no working software
or even a particularly interesting idea. It’s fairly premature to assume that
there are going to be any contributors to this project other than myself. I
don’t believe veterinary practice management software is so exciting that I am
going to be swamped with contributions. However, as I &lt;a href=&quot;/2017/11/vetted-a-new-hope/&quot;&gt;mentioned
earlier&lt;/a&gt;, this whole project is mainly a learning
opportunity for me.&lt;/p&gt;

&lt;hr /&gt;

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

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://choosealicense.com&quot;&gt;choosealicense.com&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://haacked.com/archive/2006/01/24/TheDevelopersGuideToCopyrightLaw-Part1.aspx&quot;&gt;Phil Haack’s excellent three part series&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://opensource.com/article/17/9/open-source-licensing&quot;&gt;Open source licensing: What every technologist should know&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</content>
  </entry>
  
  <entry>
    <title>Vetted - a new project</title>
    <link href="/2017/11/vetted-a-new-hope/"/>
    <updated>2017-11-05T00:00:00+00:00</updated>
    <id>/2017/11/vetted-a-new-hope/</id>
    <category term="software-tech" label="Software/Tech"></category>
    <content type="html">&lt;p&gt;When I was in high school, I created a fairly basic application for managing a
small veterinary practice. It’s written in Microsoft Access and is used by my
parents to manage their mobile veterinary business.&lt;/p&gt;

&lt;p&gt;I’m toying with rebuilding it as a web application. For its current users, the
main benefits of this would be:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;client contact details could be made available on a mobile device;&lt;/li&gt;
  &lt;li&gt;there will be no more (or at least fewer) issues with concurrent
modification (merging two access database files that have been modified
independently on different computers because Dropbox didn’t sync is no fun);
and&lt;/li&gt;
  &lt;li&gt;it will be accessible anywhere with internet access, so that my dad could do
accounts when he is away from home and has some downtime.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For me, it would mainly be a learning opportunity.&lt;/p&gt;

&lt;p&gt;Naming things is not my strong suit, so I’m going with ‘Vetted’ for now.&lt;/p&gt;

&lt;p&gt;I’m going to try to do the following throughout the project:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Apply domain driven design rigorously&lt;/li&gt;
  &lt;li&gt;Apply functional programming principles&lt;/li&gt;
  &lt;li&gt;Document failures and successes&lt;/li&gt;
  &lt;li&gt;Document my &lt;a href=&quot;#design-heuristics&quot;&gt;design heuristics&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#develop-in-the-open&quot;&gt;Develop in the open&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Deploy continuously to &lt;del&gt;production&lt;/del&gt; &lt;em&gt;somewhere&lt;/em&gt;&lt;/li&gt;
  &lt;li&gt;Focus on adding the most valuable parts first (e.g. make phone numbers
available online) &amp;amp; delivering vertical slices&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I’m thinking that the basic architecture for now will be:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Single page application&lt;/li&gt;
  &lt;li&gt;Elm frontend&lt;/li&gt;
  &lt;li&gt;Kotlin backend&lt;/li&gt;
  &lt;li&gt;Maybe some kind of event sourced data store, as I’d like to see how badly I
can shoot my foot off&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;While I want to build something functional, I also want to learn about a few
techniques/patterns/tools that would be applicable on larger projects, so I might
be making some choices which seems strange. I’ll try to call these out as they
happen. I need to remember that &lt;a href=&quot;https://blog.bradfieldcs.com/you-are-not-google-84912cf44afb&quot;&gt;I am not Google&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I’m hoping to publish posts more regularly about this project, so keep an eye
out if you’re interested!&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;notes&quot;&gt;Notes&lt;/h2&gt;

&lt;h3 id=&quot;design-heuristics&quot;&gt;Design Heuristics&lt;/h3&gt;

&lt;p&gt;I attended the excellent &lt;a href=&quot;http://exploreddd.com/&quot;&gt;Explore DDD conference&lt;/a&gt; this
year and one of my favourite talks was &lt;a href=&quot;https://www.youtube.com/watch?v=fWCt5KWfTuo&quot;&gt;Cultivating Your Design
Heuristics&lt;/a&gt; by Rebecca Wirfs-Brock.&lt;/p&gt;

&lt;p&gt;As defined in the talk, a heuristic is:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;anything that provides a plausible aid (not a guaranteed aid) or direction in
defining a solution but is ultimately irrelevant to the final product&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Rebecca encourages everyone to consciously document and cultivate heuristics,
learn others heuristics &amp;amp; discuss them and ultimately adapt (or wholesale
replace) your own heuristics when appropriate.&lt;/p&gt;

&lt;p&gt;It’s a great talk, and I’m going to try to document the heuristics that I find
myself using while working on this project.&lt;/p&gt;

&lt;h3 id=&quot;develop-in-the-open&quot;&gt;Develop in the open&lt;/h3&gt;

&lt;p&gt;I’m going to be writing about what I’m building, and the code will be available
on GitHub. However, I haven’t yet determined how to license the project. My
basic requirement is that I retain copyright and can relicense the project if
that’s ever required.&lt;/p&gt;

&lt;p&gt;Look out for a post on this in the near future.&lt;/p&gt;

</content>
  </entry>
  
  <entry>
    <title>Debugging slow bash startup files</title>
    <link href="/2017/10/debugging-slow-bash-startup-files/"/>
    <updated>2017-10-31T00:00:00+00:00</updated>
    <id>/2017/10/debugging-slow-bash-startup-files/</id>
    <category term="software-tech" label="Software/Tech"></category>
    <content type="html">&lt;p&gt;Recently I found that opening a new &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bash&lt;/code&gt; session (e.g. when opening a new
terminal window) was getting a bit slow on my machine.  I take reasonable care
to make sure my dotfiles don’t get too crufty, and I keep them all in &lt;a href=&quot;https://github.com/mdjnewman/dotfiles&quot;&gt;version
control&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The following is a walk through of how I went about debugging the issue.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;So, how does one go about profiling what &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bash&lt;/code&gt; is doing when starting a login
shell/interactive shell?&lt;/p&gt;

&lt;p&gt;My initial thought was to use some kind of system call tracing to see what
files were being opened/executed. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;dtrace&lt;/code&gt; exists on OS X, so let’s try that:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;dtruss &lt;span class=&quot;nt&quot;&gt;-ef&lt;/span&gt; bash
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Sadly, the output isn’t overly useful due to &lt;a href=&quot;https://unix.stackexchange.com/a/276219&quot;&gt;System Integrity
Protection&lt;/a&gt;. I don’t want to boot
into recovery mode, so what are our options?&lt;/p&gt;

&lt;p&gt;I regularly add &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;set -o xtrace&lt;/code&gt; to my bash scripts … would the same thing
work for my &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.bashrc&lt;/code&gt;? I added the line, and executed &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bash&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;+ source /Users/mnewman/.bash_profile
++ export PATH=/Users/mnewman/bin:/Users/mnewman/perl5/bin:/Users/mnewman/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Users/mnewman/.rvm/bin
++ PATH=/Users/mnewman/bin:/Users/mnewman/perl5/bin:/Users/mnewman/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Users/mnewman/.rvm/bin
++ for file in ~/.{path,bash_prompt,exports,aliases,functions,extra}
++ &apos;[&apos; -r /Users/mnewman/.path &apos;]&apos;
++ for file in ~/.{path,bash_prompt,exports,aliases,functions,extra}
++ &apos;[&apos; -r /Users/mnewman/.bash_prompt &apos;]&apos;
...
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;It looks like that works (the above is showing the start of my &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.bash_profile&lt;/code&gt;,
which is sourced from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.bashrc&lt;/code&gt;). There is a lot of output there though, and we
still don’t have any timing information. A little searching for variants of
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bash add timestamp to each line&lt;/code&gt; led me to &lt;a href=&quot;https://stackoverflow.com/a/9813614/415801&quot;&gt;an SO
answer&lt;/a&gt; recommending &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ts&lt;/code&gt;. Looking at the manual page for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ts&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ man ts

NAME
       ts - timestamp input

SYNOPSIS
       ts [-r] [-i | -s] [format]

DESCRIPTION
       ts adds a timestamp to the beginning of each line of input.

       The optional format parameter controls how the timestamp is formatted, as used by strftime(3). The default format is &quot;%b %d %H:%M:%S&quot;. In addition to the regular strftime
       conversion specifications, &quot;%.S&quot; and &quot;%.s&quot; are like &quot;%S&quot; and &quot;%s&quot;, but provide subsecond resolution (ie, &quot;30.00001&quot; and &quot;1301682593.00001&quot;).

       If the -r switch is passed, it instead converts existing timestamps in the input to relative times, such as &quot;15m5s ago&quot;. Many common timestamp formats are supported. Note that
       the Time::Duration and Date::Parse perl modules are required for this mode to work. Currently, converting localized dates is not supported.

       If both -r and a format is passed, the existing timestamps are converted to the specified format.

       If the -i or -s switch is passed, ts timestamps incrementally instead. In case of -i, every timestamp will be the time elapsed since the last timestamp. In case of -s, the time
       elapsed since start of the program is used.  The default format changes to &quot;%H:%M:%S&quot;, and &quot;%.S&quot; and &quot;%.s&quot; can be used as well.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;So far so good, it looks like we could use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ts -i&lt;/code&gt; and get the duration of
every command! I’d like to try this out, but how can we redirect the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;xtrace&lt;/code&gt;
output to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ts&lt;/code&gt;?&lt;/p&gt;

&lt;p&gt;Some further Googling led me to &lt;a href=&quot;https://unix.stackexchange.com/a/155553&quot;&gt;this SO
answer&lt;/a&gt;, which suggests using the
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;BASH_XTRACEFD&lt;/code&gt; variable to tell bash where to write its &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;xtrace&lt;/code&gt; output. After
some trial and error, I added a few lines to my &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.bashrc&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# open file descriptor 5 such that anything written to /dev/fd/5&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# is piped through ts and then to /tmp/timestamps&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;exec &lt;/span&gt;5&amp;gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;(&lt;/span&gt;ts &lt;span class=&quot;nt&quot;&gt;-i&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;%.s&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; /tmp/timestamps&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# https://www.gnu.org/software/bash/manual/html_node/Bash-Variables.html&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;export &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;BASH_XTRACEFD&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;5&quot;&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Enable tracing&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-x&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Source my .bash_profile script, as usual&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-n&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$PS1&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;source&lt;/span&gt; ~/.bash_profile&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Upon restarting bash, this produces (a lot of) output in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/tmp/timestamps&lt;/code&gt;, and
each line contains an incremental timestamp, like so:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;0.000046 ++ which brew
0.003437 +++ brew --prefix
0.025518 ++ &apos;[&apos; -f /usr/local/share/bash-completion/bash_completion &apos;]&apos;
0.000741 +++ brew --prefix
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;These particular lines tell me that a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;brew --prefix&lt;/code&gt; command executed and took
20ms.&lt;/p&gt;

&lt;p&gt;With output like the above, I had enough info to track down a couple of slow loading
scripts (like sourcing &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;nvm.sh&lt;/code&gt;) and remove them from my &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.bashrc&lt;/code&gt;/&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.bash_profile&lt;/code&gt;.&lt;/p&gt;

</content>
  </entry>
  
  <entry>
    <title>Denver and the Rocky Mountains</title>
    <link href="/2017/09/denver-rocky-mountains/"/>
    <updated>2017-09-26T00:00:00+00:00</updated>
    <id>/2017/09/denver-rocky-mountains/</id>
    <category term="travel" label="Travel"></category>
    <content type="html">
&lt;figure&gt;
    &lt;a href=&quot;/public/images/2017/09/20170923_152855.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2017/09/20170923_152855.jpg&quot; alt=&quot;Aspen trees in the Rocky Mountains&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;p&gt;Last week I went to &lt;a href=&quot;http://exploreddd.com/&quot;&gt;Explore DDD&lt;/a&gt; (which I would highly
recommend) in Denver on Thursday and Friday, joined a tour to the Rocky
Mountains on Saturday, and explored Denver on Sunday.&lt;/p&gt;

&lt;p&gt;Content of the conference aside, even the view from the venue was pretty
amazing:&lt;/p&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2017/09/20170921_090819.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2017/09/20170921_090819.jpg&quot; alt=&quot;View of Denver buildings with Rocky Mountains in the background&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;p&gt;Sadly the weather was pretty poor on Saturday for the Roucky Mountains visit,
and there wasn’t lots to see out of the lookout 12,000 ft (~3600m) up:&lt;/p&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2017/09/20170923_132003.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2017/09/20170923_132003.jpg&quot; alt=&quot;Photo of Matt trying to see a view, but all there is outside is fog&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;p&gt;Denver is a cool city, figuratively and literally. It’s quite high, almost
exactly one mile above sea level. The Colorado capital building is in Denver;
the stairs out the front have a plaque to show which one is exactly one mile
above sea level, but measurements kept getting more and more accurate, so there
are actually three plaques!&lt;/p&gt;

&lt;p&gt;A few random facts from the visit:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;The trees with yellow leaves in the picture above are aspens, and they
actually grow in clumps all connected via a common root system&lt;/li&gt;
  &lt;li&gt;Denver convention center is the 13th largest building in the world&lt;/li&gt;
  &lt;li&gt;The Broncos (the Denver NFL team) have sold out every home game for the last
23 years&lt;/li&gt;
  &lt;li&gt;If attacked by a black bear, fight back&lt;/li&gt;
  &lt;li&gt;Up high, where the trees can only grow for a few months a year, a tree thats
2-3 inches thick might be 80 years old&lt;/li&gt;
  &lt;li&gt;A building that’s part of the &lt;a href=&quot;https://drive.google.com/file/d/1eIpaaVr7gU5Fg-QePmGeoYspBDsEuS_ObA/view&quot;&gt;Denver art gallery contains no right
angles&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;The &lt;a href=&quot;https://drive.google.com/file/d/1cQMoRWfIDpQ8Xmd7SO1UeU0s-fSeoRkBBA/view?usp=sharing&quot;&gt;eagle atop the Denver local government
building&lt;/a&gt;
was made by someone who hated the mayor who planned the construction of the
whole building.  Apparently you only see eagles with their wings in that
position when they’re a) about to take off, or b) defacating&lt;/li&gt;
  &lt;li&gt;In Denver, 1% of every public construction project must be set aside for a
public art installation nearby the building&lt;/li&gt;
  &lt;li&gt;The Denver mint makes coins for China&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://drive.google.com/file/d/1tvzH6a_vk6XEZz7HbwBbxFB_Z6Csnvc1qw/view?usp=sharing&quot;&gt;This art
piece&lt;/a&gt;
was meant to be for a primary school and was trying to make a statement about
the perspective of children (the horse atop the chair is actually a full size
horse). However, the school didn’t like it and it ended up at the library.
Another installation at the convention center pokes a bit of fun at this piece.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://drive.google.com/file/d/1q3jT5uW1ZZZwpYye8JbX1sOoaMjkzc4jDA/view?usp=sharing&quot;&gt;‘Iseewhatyoumean’ is the name of a huge blue
bear&lt;/a&gt;
who’s always trying too see what’s happening in the Denver convention center,
and is consistently voted the favorite public are installation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Despite the weather it was a fun weekend, I’m looking forward to going to
&lt;a href=&quot;http://exploreddd.com/&quot;&gt;Explore DDD&lt;/a&gt; again in 2018.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>Migrating a GitHub Pages blog with a custom domain to HTTPS</title>
    <link href="/2017/07/migrating-a-github-pages-blog-with-a-custom-domain-to-https/"/>
    <updated>2017-07-06T00:00:00+00:00</updated>
    <id>/2017/07/migrating-a-github-pages-blog-with-a-custom-domain-to-https/</id>
    <category term="software-tech" label="Software/Tech"></category>
    <content type="html">&lt;p&gt;At the time of writing, this blog is hosted on &lt;a href=&quot;https://pages.github.com/&quot;&gt;GitHub Pages&lt;/a&gt;,
which has been working well since I set it up a &lt;a href=&quot;https://github.com/mdjnewman/mdjnewman.github.io/commit/9e1e0836999aec7393d0314f9066040b94ef8c43&quot;&gt;few years back&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The only thing that has bugged me for a while now is that the whole site was
served over HTTP, rather than HTTPS.&lt;/p&gt;

&lt;p&gt;I wanted to move to move this blog to HTTPS, but with some constraints:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Continue using GitHub pages (it’s free and easy, I don’t want to manage a
server)&lt;/li&gt;
  &lt;li&gt;No certificate renewal (smart me plans for stupid me, who would surely forget
to renew a cert)&lt;/li&gt;
  &lt;li&gt;Continue using my domain (mdjnewman.me)&lt;/li&gt;
  &lt;li&gt;No cost&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;GitHub pages doesn’t support HTTPS for custom domain names, as it uses a
certificate with a wildcard SAN of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;*.github.io&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.cloudflare.com/&quot;&gt;CloudFlare&lt;/a&gt; offers HTTPS on a free plan, which
Troy Hunt has &lt;a href=&quot;https://www.troyhunt.com/how-to-get-your-ssl-for-free-on-shared/&quot;&gt;written
about&lt;/a&gt;
before.&lt;/p&gt;

&lt;p&gt;It looks like this will meet my constraints above - I get to keep using GitHub
Pages, I don’t have to manage a cert (CloudFlare takes care of this), and I can
keep using my custom domain.&lt;/p&gt;

&lt;p&gt;The steps I followed to do this were relatively simple:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Exported a zone file from current nameservers&lt;/li&gt;
  &lt;li&gt;Completed the CloudFlare onboarding, during which I imported the above zone file&lt;/li&gt;
  &lt;li&gt;Updated the authoritative DNS servers for my domain to the
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;*.ns.cloudflare.com&lt;/code&gt; name servers:
 &lt;img src=&quot;/public/images/2017/07/migrating-to-https-nameservers.png&quot; alt=&quot;Update name servers&quot; /&gt;&lt;/li&gt;
  &lt;li&gt;Tested the site out,
&lt;a href=&quot;https://github.com/mdjnewman/mdjnewman.github.io/commit/4b2a2237e1c00d9e280566f6d288f5870e250927&quot;&gt;fixed&lt;/a&gt;
a CSS link that was loaded over HTTP&lt;/li&gt;
  &lt;li&gt;Forced HTTPS in CloudFlare:
 &lt;img src=&quot;/public/images/2017/07/migrating-to-https-enforce-https.png&quot; alt=&quot;Enforcing HTTPS with CloudFlare&quot; /&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;… and that was it. I finished this in part of an afternoon.&lt;/p&gt;

&lt;h2 id=&quot;shortcomings&quot;&gt;Shortcomings&lt;/h2&gt;

&lt;p&gt;There is one major shortcoming with this setup: &lt;strong&gt;there is no certificate
validation between CloudFlare and GitHub&lt;/strong&gt; (CloudFlare supports fetching from
an origin without validating certificates, which is the option I’ve chosen -
‘strict’ HTTPS can be enabled for most use cases).&lt;/p&gt;

&lt;p&gt;As we mentioned before, the GitHub cert is valid for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;*.github.io&lt;/code&gt;, and we’re
using my custom domain, which is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mdjnewman.me&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If we switched off the custom domain on GitHub, and did some smarts in
CloudFront to rewrite requests so that the request to GitHub was using
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mdjnewman.github.io&lt;/code&gt;, then we’d get HTTPS all the way to GitHub servers.&lt;/p&gt;

&lt;p&gt;CloudFlare does support
&lt;a href=&quot;https://support.cloudflare.com/hc/en-us/articles/206652947-Using-Page-Rules-to-Re-Write-Host-Headers&quot;&gt;rewriting HTTP Host headers&lt;/a&gt;
, but it’s an enterprise feature.&lt;/p&gt;

&lt;p&gt;I could switch to using &lt;a href=&quot;https://aws.amazon.com/cloudfront/&quot;&gt;CloudFront&lt;/a&gt; with
an &lt;a href=&quot;https://aws.amazon.com/certificate-manager/&quot;&gt;AWS Certificate Manager&lt;/a&gt; cert,
which would meet all the above constraints except for ‘no cost’ (admittedly, my tiny
blog doesn’t get much traffic, so the cost would be minimal).&lt;/p&gt;

&lt;p&gt;Given that most of the shenanigans with injecting content into web sites
happens at the last leg of a connection (I’m looking at you, dodgy internet
cafe), I’m happy that the new setup for this blog mitigates that problem and am
willing to accept the cost/security trade-off. While it’s possible for someone
to perform a man in the middle attack and impersonate GitHub, given my site has
no sensitive information I’m not too worried about this threat model (Troy Hunt
also &lt;a href=&quot;https://www.troyhunt.com/cloudflare-ssl-and-unhealthy-security-absolutism/&quot;&gt;wrote
about&lt;/a&gt;
this trade-off).&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>When should I force push after rebasing?</title>
    <link href="/2017/07/when-should-i-force-push-after-rebasing/"/>
    <updated>2017-07-05T00:00:00+00:00</updated>
    <id>/2017/07/when-should-i-force-push-after-rebasing/</id>
    <category term="software-tech" label="Software/Tech"></category>
    <content type="html">&lt;p&gt;tl;dr: assuming it’s your own branch, &lt;strong&gt;immediately&lt;/strong&gt;.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;On the last few projects I have been a part of, I have been the defacto Git
problem solver.&lt;/p&gt;

&lt;figure&gt;
    &lt;a href=&quot;https://imgs.xkcd.com/comics/git.png&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;https://imgs.xkcd.com/comics/git.png&quot; alt=&quot;XKCD Git Comic&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    (obligatory &lt;a href=&quot;https://xkcd.com/1597/&quot;&gt;xkcd&lt;/a&gt;)
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;p&gt;On more than one occasion, I was presented with something like the following:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ git l master
* 232e985 (origin/master, origin/HEAD, master) Feature 4
* 94989d0 Feature 3
* 296d0b3 Feature 2
* 4b856cd Feature 1

$ git l feature-5
* 5c31f6d (HEAD -&amp;gt; feature-5) Feature 4
* 420f83b Feature 3
* 724236a (origin/feature-5) Feature 5
* 296d0b3 Feature 2
* 4b856cd Feature 1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;In the above, the commits adding features 3 and 4 on each branch are logically
the same, but on the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;feature-5&lt;/code&gt; branch they’ve somehow ended up after the
commit adding feature 5.&lt;/p&gt;

&lt;p&gt;The team was using feature branches, and the author of feature 5 above was
trying to rebase their changes onto master, but somehow ended up inserting
their commit between commits on master. At this stage, you’re in a pretty bad
place, as you’ve diverged from master.&lt;/p&gt;

&lt;p&gt;How did this happen? I’m guessing it was the following series of events:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Developer branches from master to create feature-5&lt;/li&gt;
  &lt;li&gt;Features 3 &amp;amp; 4 are pushed to master&lt;/li&gt;
  &lt;li&gt;Feature 5 is committed to the feature-5 branch&lt;/li&gt;
  &lt;li&gt;Developer runs &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git pull --rebase origin master&lt;/code&gt; or similar&lt;/li&gt;
  &lt;li&gt;… some time passes …&lt;/li&gt;
  &lt;li&gt;Developer runs &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git pull --rebase&lt;/code&gt; without really thinking about it&lt;/li&gt;
&lt;/ul&gt;

&lt;!--
&lt;script src=&quot;https://cdnjs.cloudflare.com/ajax/libs/gitgraph.js/1.11.3/gitgraph.js&quot;&gt;&lt;/script&gt;
&lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;https://cdnjs.cloudflare.com/ajax/libs/gitgraph.js/1.11.3/gitgraph.css&quot; /&gt;

&lt;script&gt;
var gitGraphTemplateConfig = {
          colors: [&quot;#979797&quot;, &quot;#008fb5&quot;, &quot;#f1c109&quot;],
          branch: {
            lineWidth: 10,
            spacingX: 50,
            labelRotation: 0
          },
          commit: {
            spacingY: -80,
            dot: {
              size: 14
            },
            message: {
              displayAuthor: false,
              displayBranch: false,
              font: &quot;normal 14pt Arial&quot;
            }
          }
        };

var gitGraphTemplate = new GitGraph.Template( gitGraphTemplateConfig );
&lt;/script&gt;
--&gt;
&lt;p&gt;After the first few steps above, we have something like the following:&lt;/p&gt;

&lt;!--
&lt;div style=&quot;overflow-x: scroll&quot;&gt;
&lt;canvas id=&quot;gitgraph-1&quot; height=&quot;800&quot;&gt;&lt;/canvas&gt;
&lt;/div&gt;
&lt;script&gt;
var gitgraph = new GitGraph( { template: gitGraphTemplate, elementId: &quot;gitgraph-1&quot; })
var master = gitgraph.branch(&quot;master&quot;)
gitgraph.commit( { message: &quot;Feature 1&quot;, sha1: &quot;4b856cd&quot; })
gitgraph.commit( { message: &quot;Feature 2&quot;, sha1: &quot;296d0b3&quot; })
gitgraph.branch(&quot;feature-5&quot; )
gitgraph.commit( { message: &quot;Feature 5 (feature-5, origin/feature-5)&quot;, sha1: &quot;724236a&quot; })
master.checkout()
gitgraph.commit( { message: &quot;Feature 3&quot;, sha1: &quot;94989d0&quot; })
gitgraph.commit( { message: &quot;Feature 4 (master, origin/master)&quot;, sha1: &quot;232e985&quot; })
&lt;/script&gt;
--&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2017/07/git-1.png&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2017/07/git-1.png&quot; alt=&quot;Commits after creating feature branch&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;p&gt;So far, so good. We want to rebase our changes onto master, so that we can test
and push our code. After &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git pull --rebase origin master&lt;/code&gt;:&lt;/p&gt;

&lt;!--
&lt;div style=&quot;overflow-x: scroll&quot;&gt;
&lt;canvas id=&quot;gitgraph-2&quot;&gt;&lt;/canvas&gt;
&lt;/div&gt;
&lt;script&gt;
var gitgraph = new GitGraph( { template: gitGraphTemplate, elementId: &quot;gitgraph-2&quot; })
var master = gitgraph.branch(&quot;master&quot;)
gitgraph.commit( { message: &quot;Feature 1&quot;, sha1: &quot;4b856cd&quot; })
gitgraph.commit( { message: &quot;Feature 2&quot;, sha1: &quot;296d0b3&quot; })
gitgraph.branch(&quot;origin/feature-5&quot; )
gitgraph.commit( { message: &quot;Feature 5 (origin/feature-5)&quot;, sha1: &quot;724236a&quot; })
master.checkout()
gitgraph.commit( { message: &quot;Feature 3&quot;, sha1: &quot;94989d0&quot; })
gitgraph.commit( { message: &quot;Feature 4 (master, origin/master)&quot;, sha1: &quot;232e985&quot; })
gitgraph.commit( { message: &quot;Feature 5 (feature-5)&quot;, sha1: &quot;44e1c44&quot; })
&lt;/script&gt;
--&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2017/07/git-3.png&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2017/07/git-3.png&quot; alt=&quot;Commits after rebasing onto master&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;p&gt;Still looking good. At this stage, we could &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git push --force origin feature-5&lt;/code&gt;
and all would be well in the world.&lt;/p&gt;

&lt;p&gt;But what happens if we go for a tea and forget what we were doing (or we use an
overzealous git GUI tool), and we try to rebase onto &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;origin/feature-5&lt;/code&gt;?&lt;/p&gt;

&lt;!--
&lt;div style=&quot;overflow-x: scroll&quot;&gt;
&lt;canvas id=&quot;gitgraph-3&quot;&gt;&lt;/canvas&gt;
&lt;/div&gt;
&lt;script&gt;
var gitgraph = new GitGraph( { template: gitGraphTemplate, elementId: &quot;gitgraph-3&quot; })
var master = gitgraph.branch(&quot;master&quot;)
gitgraph.commit( { message: &quot;Feature 1&quot;, sha1: &quot;4b856cd&quot; })
gitgraph.commit( { message: &quot;Feature 2&quot;, sha1: &quot;296d0b3&quot; })
gitgraph.branch(&quot;feature-5&quot; )
gitgraph.commit( { message: &quot;Feature 5 (origin/feature-5)&quot;, sha1: &quot;724236a&quot; })
gitgraph.commit( { message: &quot;Feature 3&quot;, sha1: &quot;420f83b&quot; })
gitgraph.commit( { message: &quot;Feature 4 (feature-5)&quot;, sha1: &quot;5c31f6d&quot; })
master.checkout()
gitgraph.commit( { message: &quot;Feature 3&quot;, sha1: &quot;94989d0&quot; })
gitgraph.commit( { message: &quot;Feature 4 (master, origin/master)&quot;, sha1: &quot;232e985&quot; })
&lt;/script&gt;
--&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2017/07/git-2.png&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2017/07/git-2.png&quot; alt=&quot;Commits after rebasing from our remote branch - shows duplicate commits&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;p&gt;What we see above is the result of Git rebasing commits &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;94989d0&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;232e985&lt;/code&gt;
and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;44e1c44&lt;/code&gt; on top of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;origin/feature-5&lt;/code&gt;. As the commit ID is computed by
hashing of the contents of a commit and its parent, the same logical commits
from master now exist on our branch with different IDs.&lt;/p&gt;

&lt;p&gt;This could have been avoided if we followed this rule of thumb:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;strong&gt;If you’re working on your own branch, always push immediately after rebasing.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Some people on the team were seeing a message like the following:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Your branch and &apos;origin/feature-5&apos; have diverged,
and have 3 and 1 different commits each, respectively.
  (use &quot;git pull&quot; to merge the remote branch into yours)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;and assuming that they should &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git pull --rebase&lt;/code&gt;, which in this case is exactly what you &lt;em&gt;don’t&lt;/em&gt; want.&lt;/p&gt;

&lt;p&gt;If you’re looking for further reading &lt;a href=&quot;https://git-scm.com/book/en/v2/Getting-Started-What-is-Git%3F&quot;&gt;Getting Started - Git Basics&lt;/a&gt; covers the fundamentals and &lt;a href=&quot;http://learngitbranching.js.org/&quot;&gt;LearnGitBranching&lt;/a&gt; is a great interactive tool.&lt;/p&gt;

&lt;p&gt;Diagrams were created using &lt;a href=&quot;http://gitgraphjs.com/&quot;&gt;Gitgraph.js&lt;/a&gt;, and &lt;a href=&quot;/public/2017-07-05-when-should-i-force-push-after-rebasing-script.sh&quot;&gt;this script&lt;/a&gt; creates an example repository.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>Monad transformers</title>
    <link href="/2016/07/monad-transformers/"/>
    <updated>2016-07-31T00:00:00+00:00</updated>
    <id>/2016/07/monad-transformers/</id>
    <category term="software-tech" label="Software/Tech"></category>
    <content type="html">&lt;p&gt;I’ve been spending some time working through &lt;a href=&quot;http://haskellbook.com/&quot;&gt;Haskell Programming From First
Principles&lt;/a&gt; recently which is a very comprehensive
introduction to functional programming and Haskell.&lt;/p&gt;

&lt;p&gt;One of the exercises to implement a simplified command line version of
&lt;a href=&quot;https://en.wikipedia.org/wiki/Morra_(game)&quot;&gt;Morra&lt;/a&gt;, which involves keeping
track of scores and reading user input.&lt;/p&gt;

&lt;p&gt;My initial method to play a round looked something like this:&lt;/p&gt;

&lt;div class=&quot;language-haskell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;playRound&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Config&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Scores&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;IO&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Bool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Scores&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;playRound&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;config&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;scores&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kr&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;putStr&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;P1: &quot;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;p1HandMaybe&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;getHumanHand&lt;/span&gt;
  &lt;span class=&quot;kr&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p1HandMaybe&lt;/span&gt; &lt;span class=&quot;kr&quot;&gt;of&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;Nothing&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;scores&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;               &lt;span class=&quot;c1&quot;&gt;-- error case 1&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;Just&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kr&quot;&gt;do&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;putStr&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;P2: &quot;&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;p2HandMaybe&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;getHumanHand&lt;/span&gt;
      &lt;span class=&quot;kr&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p2HandMaybe&lt;/span&gt; &lt;span class=&quot;kr&quot;&gt;of&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;Nothing&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;scores&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;           &lt;span class=&quot;c1&quot;&gt;-- error case 2&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;Just&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kr&quot;&gt;do&lt;/span&gt;
          &lt;span class=&quot;kr&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;evenWins&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mod&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;`&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
          &lt;span class=&quot;n&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;updateScores&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;config&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;evenWins&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;scores&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;playRound&lt;/code&gt; takes the configuration for the game and the current score, and
returns a side effecting computation that will return a tuple with the new
scores and a boolean indicating if the game is finished.&lt;/p&gt;

&lt;p&gt;The method &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;getHumanHand&lt;/code&gt; used above returns a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;IO (Maybe Int)&lt;/code&gt;, which can be
interpreted as a side effecting action that might return an integer (in this
case, the side effect is reading from the console and we can’t trust the user
to enter an integer, hence the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Maybe&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;The problem then is that we’re then manually unpacking these &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Maybe Int&lt;/code&gt;
values, which leads to the ugly nesting and case statements. However, we can
see on the lines marked ‘error case’ above that the handling for both cases is
the same - we assume that if the user has entered something other than an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Int&lt;/code&gt;
that they want to end the game.&lt;/p&gt;

&lt;p&gt;I recently learned about Monad transformers, which allow you to compose monads.
In this case, we want to compose the Maybe monad with the IO monad, so we will
use &lt;a href=&quot;https://www.stackage.org/haddock/lts-6.2/transformers-0.4.2.0/Control-Monad-Trans-Maybe.html#g:1&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MaybeT&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Rewriting &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;getHumanHand&lt;/code&gt; to return a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MaybeT IO Int&lt;/code&gt; and rewriting &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;playRound&lt;/code&gt;
results in the following:&lt;/p&gt;

&lt;div class=&quot;language-haskell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;playRound&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Config&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Scores&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;IO&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Bool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Scores&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;playRound&apos;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;config&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;scores&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kr&quot;&gt;do&lt;/span&gt;

  &lt;span class=&quot;n&quot;&gt;newScores&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;runMaybeT&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;kr&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;liftIO&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;putStr&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;P1: &quot;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;p1Hand&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;getHumanHand&apos;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;liftIO&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;putStr&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;P2: &quot;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;p2Hand&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;getHumanHand&apos;&lt;/span&gt;
    &lt;span class=&quot;kr&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;evenWins&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p1Hand&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p2Hand&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mod&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;`&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;updateScores&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;config&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;evenWins&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;scores&lt;/span&gt;

  &lt;span class=&quot;n&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;kr&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;newScores&lt;/span&gt; &lt;span class=&quot;kr&quot;&gt;of&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;Nothing&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;scores&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;Just&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The nice thing about this implementation is that we’ve avoided the need for
pattern matching, as the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;do&lt;/code&gt; block above where we’re dealing with the
potentially failing computations will immediately short circuit and return a
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Nothing&lt;/code&gt; if either user fails to provide a legitimate value.&lt;/p&gt;

&lt;p&gt;This is the first time I’ve actually used a Monad transformer, and it was good
to see how it cleans up the implementation of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;playRound&lt;/code&gt;.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>Europe</title>
    <link href="/2016/07/europe/"/>
    <updated>2016-07-21T00:00:00+00:00</updated>
    <id>/2016/07/europe/</id>
    <category term="travel" label="Travel"></category>
    <content type="html">&lt;p&gt;The post below is a concatenation of multiple emails I wrote during the trip,
apologies if it seems a litte disjointed.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;I’m writing the first part of this as I sit on the train on the way to
Salzburg, there’s about an hour left of a trip that takes a little under two
hours.&lt;/p&gt;

&lt;p&gt;I had three very busy days in Munich, managing to see&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Deutsches Museum&lt;/li&gt;
  &lt;li&gt;Marienplatz&lt;/li&gt;
  &lt;li&gt;BMW welt&lt;/li&gt;
  &lt;li&gt;BMW museum&lt;/li&gt;
  &lt;li&gt;Olympic park&lt;/li&gt;
  &lt;li&gt;Tollwood SommerFestival&lt;/li&gt;
  &lt;li&gt;Residenz (external and garden)&lt;/li&gt;
  &lt;li&gt;Englischer Garten&lt;/li&gt;
  &lt;li&gt;Schloss Nymphenburg, Gardens &amp;amp; Outbuildings&lt;/li&gt;
  &lt;li&gt;Dachau Concentration Camp Memorial&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The museum was awesome, I kept thinking how much I would have loved a museum
like that when I was little. It was primarily a technical museum - the sections
were mining, marine navigation, oceanography, foundries, machine tools, metals,
power machinery, marine navigation, electric power, new technologies, physics,
energy technologies, pharmaceutics, historic aviation, ceramics and glass
production, paper, musical instruments, astronomy, measures and weights,
computers, mathematics, microelectronics (I geeked out a bit in these last
three), chronometery and geodesy. It is a really big place, you could easily
spend upwards of an hour in each of those sections. I spent about 6 hours in
the museum and easily could have spent twice that, though maybe over two days;
there is only so much museum-ing I can handle.&lt;/p&gt;

&lt;p&gt;First up on Thursday morning I went to the area of the city where the BMW
headquarters and factory are located.&lt;/p&gt;

&lt;p&gt;There is also building called BMW Welt (‘welt’ -&amp;gt; ‘world’) which was like a
showroom on steroids. They had some Rolls Royces there too because BMW, Mini
Coopers and Rolls Royces are all either owned by one company or they have some
partnership going on. I planned to do a tour of the BMW factory but it was sold
out (until August!) so I settled for the museum.&lt;/p&gt;

&lt;p&gt;The BMW museum had all sorts of stuff from the life of the company over the
last 100 years and talked about how much it’s changed, from manufacturing
military parts to bikes, cars, airplane engines and even pots and pans at the
end of the war. They used POW labour at one point during the war which I didn’t
expect given a company like BMW, but this was during the war when they had a
lot less control over their operations.&lt;/p&gt;

&lt;p&gt;Once I was done at the museum I made my way into Olympiapark where the 1972
Olympics were held. This whole area has been turned into a public space and the
stadium and halls are still used for events. While I was there an event that’s
on this weekend was being setup, and there was wake boarding and some
slopestlye mountain biking going on. They were still completing the mountain
biking track so no one was doing full runs but there were pretty massive jumps
in there. I got a video of one guy casually doing backflips for the crowd!&lt;/p&gt;

&lt;p&gt;I also spotted an event called the &lt;a href=&quot;http://www.tollwood.de/&quot;&gt;Tollwood
Sommerfestival&lt;/a&gt; from a lookout so I went and had a
peek there. It had a cool vibe and would have been good fun later in the
evening, but it was a long way from where I planned to finish the day.&lt;/p&gt;

&lt;p&gt;From the Olympic Park I made my way back to Munich Residenz where the Bavarian
monarchs used to live but didn’t have time to go inside. It’s a museum now but
I just checked out the externals and went through the courtyard on my way to
the Englischer Garten.&lt;/p&gt;

&lt;p&gt;The English Gardens are massive, I only walked through half of them in then end
despite plans to go from one end to the other. There is and really cool spot at
the start of the gardens where the water flows in (not sure if it’s flowing
through or recycled through the canal system in the park - maybe both), there
were people surfing there! They’ve set something up that makes an artificial
wave across the canal.&lt;/p&gt;

&lt;p&gt;In the middle of the gardens is this relic of a bit of a China craze that went
through Munich a while back. There is this pagoda type thing, and all around is
the most German food/drinks setup ever. So many 1L mugs of beer! I had my
dinner of sausages and sourkraut there along with a wheat beer before making my
way home.&lt;/p&gt;

&lt;p&gt;First up on Friday I went to Nymphenburg Schloss which is a huge palace some
Bavarian rules used to live in. Construction started in 1664 and there were
still buildings being added and pretty big modifications being made to the
grounds until 1825. Water is a very big feature throughout the grounds and is
provided by a 2km long channel that brings water from a nearby river. There was
a really run down looking building called the Magdalenenklause in the gardens,
but it was actually built to look that way as an escape from the prim and
proper life at court.&lt;/p&gt;

&lt;p&gt;After I’d wandered all around the gardens and reached appropriate levels of
sunburn, I made my way to Dachau, where there was a concentration camp. This
wasn’t a camp where mass executions were carried out in gas chambers, though
there was a chamber built there. The people running Dachau instead really
believed in ‘&lt;a href=&quot;https://en.wikipedia.org/wiki/Extermination_through_labour&quot;&gt;extermination through
labour&lt;/a&gt;’, whereby
they overworked people until they pretty much died of exhaustion. The gates to
the camp said “work shall set you free”, though freedom in this case normally
meant death. There were 32 huts each originally built to house 250 people, but
apparently they each held upwards of 1000 people towards the end of the war.
Over 40,000 people died/were executed there in the twelve years it was
operating. Sobering place.&lt;/p&gt;

&lt;p&gt;After Dachau it was time to head to Salzburg which was very easy to figure out.
The public transport in Munich is amazing, I had no trouble getting around
despite not knowing the city and not understanding what anyone was saying or
what anything said.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;This is yet another instalment that’s being written while on the train, this
time from Salzburg to Vienna. I have internet on this train, and it’s probably
faster than what 99% of Australian ISPs provide (thanks Tony). It made me laugh
when I connected to WiFi and saw this immediately:&lt;/p&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2016/07/0B3HUADVbsoZAZ2ExdmprNlhDcEdSZHJLZlVxeTA1U0hXZ3hv.png&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2016/07/0B3HUADVbsoZAZ2ExdmprNlhDcEdSZHJLZlVxeTA1U0hXZ3hv.png&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;p&gt;… ‘this is of course free’. In Aus this would cost an arm and a leg and take
four hours to set up.&lt;/p&gt;

&lt;p&gt;During my two days in Salzburg I visited:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Festung Hohensalzburg - a fortress&lt;/li&gt;
  &lt;li&gt;The Domquartier - a museum combining the church and residence of the
‘Prince-Archbishop’&lt;/li&gt;
  &lt;li&gt;Kapuzinerberg - a mountain in the middle of town, not as heavily fortified as
Festung Hohensalzburg&lt;/li&gt;
  &lt;li&gt;Schloss Mirabell - a palace built around 1606&lt;/li&gt;
  &lt;li&gt;Augustiner Brauhaus&lt;/li&gt;
  &lt;li&gt;A few other places around Salzburg, though only the exteriors:
    &lt;ul&gt;
      &lt;li&gt;Mozarts geburtshaus and wohnhaus (where he was born and lived,
respectively)&lt;/li&gt;
      &lt;li&gt;Christian Doppler’s geburtshaus&lt;/li&gt;
      &lt;li&gt;About 1000 churches&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Festung Hohensalzburg was probably the hightlight for me. There is evidence
that there have been people on Festungsberg since year 0180, and construction
started on Festung Hohensalzburg in 1077. It’s no wonder people have been using
it as a stronghold for so long, it is an amazing place to put up a strong
defence (it’s actually never been taken by force, but was surrendered once
during the Napoleonic War of the Second Coalition in 1800 when the ruler at the
time bailed to Vienna). I think the only people to actually attack it were some
peasants in 1525 who were promptly repelled. The fortress was commissioned by
the ‘Prince-Archbishops’ of Salzburg.  These guys were the supreme rulers, as
they’re non-secular princes as well as archbishops of the church. One of the
really interesting things there is the ‘Salzburger Bull’, which is a very loud
mechanical organ that was used to signal various things to the town (photo
&lt;a href=&quot;https://drive.google.com/open?id=1UH2EfaI7Gr0-EiI0hL3CbjP0iCPg7oDD2g&quot;&gt;here&lt;/a&gt;).
The fortress was used as a military outpost until 1861.&lt;/p&gt;

&lt;p&gt;Next up was the Domquartier, a museum that combines a palace where the
Prince-Archbishops used to live and do the princely thing and the cathedral
where they used to be pray and carry out their duties as archbishops. The
residence building was initially built in 1604 and the cathedral in 1614. The
two buildings have been joined on the second level since one of the
Prince-Archbishops decided they didn’t like getting their feet wet when walking
between the two. The museum is setup so that you follow the path that a visitor
would have followed when seeing the Prince-Archbishop, which mainly involved
going through several extravagant rooms. The first room is huge and not as
fancy, but the further along you get the smaller and more expensive-feeling the
rooms get, this is apparently because the more important you were the further
into the palace you could get. The rooms all have portraits of Alexander the
Great painted on the ceilings, which were all indirectly drawing comparisons
between Alexander and the Prince-Archbishops you were about to see. Sadly I
don’t have any photos of the interior of the palace as they weren’t allowed.&lt;/p&gt;

&lt;p&gt;It was a bit of a rainy afternoon so I started making my way back to the hotel
and decided to check out Augustiner Brauhaus on the way. It’s massive - 5,000
square meters internally and with a beer garden that can sit 1,400 people. The
beer is rolled out in massive barrels from which people fill up their steins.&lt;/p&gt;

&lt;p&gt;On Wednesday I went to Mozarts geburtshaus and wohnhaus but decided I’d had
enough of museums and instead went for a walk up the Kapuzinerberg. The
Kapuzinerberg is a mountain in the middle of town, not as heavily fortified as
Festung Hohensalzburg. There is one castle up there (Franziskischlössl) and a
massive wall that goes all the way back towards the river to another
stronghold. This second stronghold could be used to defend the eastern side of
what was at the time the only bridge across the river (Hettwer-Bastion). I
walked the wall back from the Franziskischlössl to the Hettwer-Bastion, going
past some signs that looked vaguely like they were warning me about something.
Building this wall now would be a pretty impressive feat, let alone building it
in three years from 1629-1632. I think it would take the Brisbane City Council
about 100 years and several billion of machinery. The Franziskischlössl and the
wall were built such that there are no angles were attackers could hide without
being under fire. The main drawbridge into Franziskischlössl is protected on
three sides, and there were watchtowers built within shouting distance of each
other all the way back to Hettwer-Bastion.&lt;/p&gt;

&lt;p&gt;From the end of the wall I made my way to Schloss Mirabell - a palace built
around 1606, also for the Prince-Archbishops. The palace building itself is
still used by the local council and events and concerts are held there, but the
gardens are open for all to see. One of the features of the gardens are &lt;a href=&quot;https://drive.google.com/open?id=18JpeapUiwSkbBjcPeD2LvcFWfyBR8CcUOw&quot;&gt;14
marble
dwarfs&lt;/a&gt;
which were put there in 1710 as part of an outdoor theatre. Several scenes from
The Sound of Music were shot in the gardens.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;Ahoy! (which is apparently a common greeting used by people in Bratislava as
well as by pirates)&lt;/p&gt;

&lt;p&gt;In keeping with the train theme, I’m starting this update on the train back to
Vienna.&lt;/p&gt;

&lt;p&gt;Since arriving in Vienna on Sunday night, I have checked into our Airbnb, done
some exploring of Vienna, and spent the day in Bratislava, the capital of
Slovakia. Bratislava just on the Slovakia side of the Austria-Solvakia border
and only an hour in the train from Vienna.&lt;/p&gt;

&lt;p&gt;We went for a walk along part of Donauinsel on Monday morning. Donauinsel is a
roughly 20km long island in Vienna on the Danube River. From there we walked
back towards our apartment, hoping to walk through a local university but
somehow walking past a horse racing track and a huge construction site. After a
lunch at home with groceries from the local supermarket and Kirstens arrival we
headed off to explore some of Vienna.&lt;/p&gt;

&lt;p&gt;From the bridge to Donauinsel, we’d seen a very large church nearby so we had a
look at that first. The church was ‘&lt;a href=&quot;https://en.wikipedia.org/wiki/St._Francis_of_Assisi_Church,_Vienna&quot;&gt;Heiliger Franz von
Assisi&lt;/a&gt;’,
or the St.  Francis of Assisi Church. It was built much more recently than most
of the churches around here, construction only started in 1898! The interior
was quite plain compared to how it looked from the outside:&lt;/p&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2016/07/0B3HUADVbsoZAb1hMdnlla2o0Rlk.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2016/07/0B3HUADVbsoZAb1hMdnlla2o0Rlk.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;p&gt;After checking out the local church, we caught the U-bahn (Untergrundbahn, or
undergroud railway in English) to Schönbrunn Palace. The first part of the
mansion there was built in 1548 and was normally occupied by members of the
Habsburg Monarchy, including Franz Joseph, the longest-reigning emperor of
Austria. It’s been a museum since the fall of the Austro-Hungarian Empire in 1918.
It’s a pretty striking place:&lt;/p&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2016/07/0B3HUADVbsoZAdGFLMS1PS3llR00.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2016/07/0B3HUADVbsoZAdGFLMS1PS3llR00.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;p&gt;The final stop on Monday was Karlskirche (or St. Charles’s Church) which was
built between 1716 &amp;amp; 1737. The columns outside this church are pretty unusual:&lt;/p&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2016/07/1Tz-lBxKVuxoloYTOtmuBTKclOkUJMKRA0g.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2016/07/1Tz-lBxKVuxoloYTOtmuBTKclOkUJMKRA0g.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;p&gt;I will send another update about Bratislava, but it’s Wednesday morning now so
I’m off to explore some of Vienna :)&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;I’m not writing on a train this time, but having a relaxed day in Vienna as my
feet feel like they’re about to fall off. I will probably head out and go to a
museum or something this afternoon.&lt;/p&gt;

&lt;p&gt;As I said in my last email that we went to Bratislava on Tuesday which was a
really good trip. Most of our time there was spent on a free walking tour of
the city (‘free’ but tips expected - our guide was really good though). I made
a &lt;a href=&quot;https://drive.google.com/open?id=1Oaj5Ssby72EnKIxQMV19fctnelY&quot;&gt;map of the
path&lt;/a&gt; we took.&lt;/p&gt;

&lt;p&gt;There are a lot of statues in Bratislava, including one of Hans Christian
Andersen (author of “The Emperor’s New Clothes”, “The Little Mermaid”, “The
Nightingale”, “The Snow Queen”, “The Ugly Duckling”, “Thumbelina” …) which we
would have walked straight past if our guide had not pointed it out. The back
of the statue has lots of things from his stories. Another one is the ‘man at
work’:&lt;/p&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2016/07/1ew2GmutCxzkSuBGqWxZO6cRjD3rid47w.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2016/07/1ew2GmutCxzkSuBGqWxZO6cRjD3rid47w.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    Courtesy of &lt;a href=&quot;https://commons.wikimedia.org/wiki/File:Man_at_work_(%C4%8Cumil)_statue_in_Bratislava.jpg&quot;&gt;Frettie on Wikimedia Commons&lt;/a&gt;
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;p&gt;This statue doesn’t really have a name, but a sign warning saying ‘Man at work’
was put up after people kept tripping over him. According to the locals his
name is Cumil and he is the quintessential Bratislavian man at work, as he just
chills out all day and perves on the tourists. The executioner below has been
present for quite some time in one form or another:&lt;/p&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2016/07/1F2uD5H-N8h87JCYZagiIXhlldzWEv5hfFA.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2016/07/1F2uD5H-N8h87JCYZagiIXhlldzWEv5hfFA.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;p&gt;This is at the entrance to the lane where the executioner used to live (his
house is now a massage parlour!). The lane where the executioner lived was next
to Michael’s Gate, part of the fortifications for the city build in the mid
14th century. A second gate was added along with a 90° corner in the 17th
century, so that enemies had to slow down even if they breached both gates.&lt;/p&gt;

&lt;p&gt;From Michael’s Gate we walked on to the Slovak National Uprising Square. This
square, as well as another in the middle of the city, were important sites in
the &lt;a href=&quot;https://en.wikipedia.org/wiki/Velvet_Revolution&quot;&gt;Velvet Revolution&lt;/a&gt; which
in 1989 ended the communist rule in then Czechoslovakia (the split into the
Czech Republic and Slovakia happened in 1993).&lt;/p&gt;

&lt;p&gt;After the SNP Square we visited The Church of St. Elizabeth/The Blue Church/The
Smurf Church which was built in 1908 and is very, very blue:&lt;/p&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2016/07/1BNSQDyUESeBDXfLnUnHTlCeaLaQVPi4pAw.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2016/07/1BNSQDyUESeBDXfLnUnHTlCeaLaQVPi4pAw.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2016/07/1ixnQAloxdYevoBl5RCzyJeyKZ8EAM2nSAA.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2016/07/1ixnQAloxdYevoBl5RCzyJeyKZ8EAM2nSAA.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;p&gt;After a final short walk we were sitting at the entrance to a building when our
guide was telling us more about the Soviet invasion of Czechoslovakia in 1968.
She handed around a physical copy of a &lt;a href=&quot;https://theworldinbetween.com/2012/08/19/ladislav-bielik-and-the-iconic-photograph-of-1968-czechoslovakia/&quot;&gt;rather controversial
photograph&lt;/a&gt;.
I haven’t included it here, as the image isn’t in the public domain, but after
looking at it we realised we were sitting on the stairs of the building in the
background!&lt;/p&gt;

&lt;p&gt;The tour guide also told us some interesting stories about traditions in
Slovakia. For men, easter apparently involves pouring water on the women in
your life and lightly hitting them with willow sticks. Christmas means it’s
time to catch a carp and keep it in the bathtub for a few days before eating it
for a Christmas meal.&lt;/p&gt;

&lt;p&gt;I did some exploring of Vienna yesterday, but I will send another email about
that!&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;I’ve finally got around to writing up what I got up to in Vienna, while I’m on
the train of course! We’re currently on the long ride from Vienna to Mainz. The
good thing is the train is currently going at 170 km/h. I’ll split this into a
few emails, the first one is about Wednesday when I explored the inner area of
Vienna.&lt;/p&gt;

&lt;p&gt;I started out at the
&lt;a href=&quot;https://en.wikipedia.org/wiki/Belvedere,_Vienna&quot;&gt;Belvedere&lt;/a&gt;, a complex
consisting of two palaces, a botanical garden and even a small zoo. The large
palace now houses a museum (or an art gallery, I can’t remember - there are so
many galleries and museums in Vienna). The palace was built was built as a
summer residence for Prince Eugene of Savoy sometime in the early 1700’s. Savoy
was a big fan of animals and had a small zoo setup there, though that’s all
gone now.&lt;/p&gt;

&lt;p&gt;On my way to the centre of old Vienna I walked past &lt;a href=&quot;https://en.wikipedia.org/wiki/Soviet_War_Memorial_(Vienna)&quot;&gt;Heldendenkmal der Roten
Armee&lt;/a&gt; (the Heroes’
Monument of the Red Army), a Soviet War Memorial built in 1945 (that is at
times a little unpopular with the locals, as the Soviets caused quite a bit of
damage when they took the city in a battle from 2 to 13 April 1945 and in the
weeks following the battle).&lt;/p&gt;

&lt;p&gt;From there I walked north to the
&lt;a href=&quot;https://en.wikipedia.org/wiki/Vienna_Ring_Road&quot;&gt;Ringstrasse&lt;/a&gt; (Ring Road) which
forms a loop around most of the old buildings and museums. There was lots to
see, but I didn’t actually go into many places as they all had a roughly €10
entrance fee and there wasn’t time to do them justice on the Wednesday. I
walked past a bunch of places inside the Ringstrasse, including&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;The ‘&lt;a href=&quot;https://en.wikipedia.org/wiki/Haus_der_Musik&quot;&gt;Haus der Musik&lt;/a&gt;’ was my
first stop inside the Ringstrasse, it is kind of like a museum with ways for
people to explore sound and how sounds are generated. Entry was a bit expensive
and I wasn’t sure if I wanted to go in, but there was a choir performing in the
lobby. When I heard the person organising the choir speak after one of their
songs, I thought they had a bit of an Australian accent. Sure enough, it was a
choir from Adelaide called Young Adelaide Voices.&lt;/li&gt;
  &lt;li&gt;A bunch of embassies&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Vienna_State_Opera&quot;&gt;Wiener Staatsoper&lt;/a&gt; (Vienna
State Opera), an opera house that opened in 1869&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Albertina&quot;&gt;Albertina&lt;/a&gt;, a museum/gallery built
in 1805 with approximately 65,000 drawings and approximately 1 million old
master prints&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Hofburg_Palace&quot;&gt;Hofburg Palace&lt;/a&gt;, a massive
complex including Österreichische Nationalbibliothek (Austrian National
Library), Michaelerplatz (an archaeological site), Joseph Square, Heldenplatz,
Kaiserappartements (see the image below)&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Austrian_Parliament_Building&quot;&gt;Austrian Parliament
Building&lt;/a&gt;,
completed in 1883 &amp;amp; still used today&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Rathaus,_Vienna&quot;&gt;Rathaus&lt;/a&gt; (town hall) also
opened in 1883. There were a bunch of massive screens setup for people to
watch the Euro Cup, we came here on Thursday night to watch the Germany/France
game&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Burgtheater&quot;&gt;Burgtheater&lt;/a&gt;, a theatre built in
1888&lt;/li&gt;
&lt;/ul&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2016/07/1itgnadiF3M1GPMVpxGbJjQkmM0um9q2P.png&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2016/07/1itgnadiF3M1GPMVpxGbJjQkmM0um9q2P.png&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    Google Maps view of a few of the places I visited
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;p&gt;The final stop for the day was
&lt;a href=&quot;https://en.wikipedia.org/wiki/St._Stephen%27s_Cathedral,_Vienna&quot;&gt;Stephansdom&lt;/a&gt;
(St Stephens Cathedral), one of the larger churches in Vienna (the bell there
is the largest in the country and weighs just over 20 metric tonnes). The
original church on the site was consecrated in 1147 and the cathedral in its
current form was finished in 1359 (some parts are still from the old church).&lt;/p&gt;

&lt;p&gt;The one place I did pay to go into on Wednesday was the katakomben (crypts) at
the cathedral. The crypts have been there since the 13th century, and everyone
who died in the town used to be buried down there. There are remains from
11,000 people (400 people per room) buried under the church over 30 years until
1783 until the smell grew too strong to run masses and they also ran out of
space. When they ran out of space they had prisoners empty out full rooms,
clean the bones and stack them neatly in ‘bone houses’ so they used less space.
We weren’t allowed to take pictures down there, but there were rooms stacked
floor to ceiling with all sorts of bones, though skulls &amp;amp; femurs were the most
recognisable. Duke Rudolph IV is in the crypt, who died in 1365 (his coffin was
replaced in the 18th century as the old one was falling apart).&lt;/p&gt;

&lt;p&gt;The final interesting fact from the crypt is that when a member of the Habsburg
family (who used to run the show here, the same family I’ve mentioned earlier)
died, there used to be disagreement about where their remains should be placed,
as there were three locations that were of particular significance to the
family.  What ended up happening is that each location got a piece - their
heart was sealed in a chalice type thing and sent to one location, their other
organs where sealed in another larger container and placed in the crypt at St
Stephens, and their bodies were put into a coffin and stored at the palace (I
think, I might be wrong on the location). Some of the containers that the
organs are in are larger than then others, the guide told us this is because
some of them sprung a leak! The leaky container just gets resealed in a larger
one whenever it happens. Apparently it happened a few years back and they had
to close the crypts for a week because of the smell.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;On Thursday afternoon I visited &lt;a href=&quot;https://en.wikipedia.org/wiki/Imperial_Treasury,_Vienna&quot;&gt;Kaiserliche
Schatzkammer&lt;/a&gt; (the
Imperial Treasury).&lt;/p&gt;

&lt;p&gt;The treasury was split into two sections, secular and ecclesiastical. There
were a bunch of interesting things in there. In no particular order:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://drive.google.com/file/d/14sjrFL9sC1kTyM_7uDHpkT7_ou5bdL3K1w/view?usp=sharing&quot;&gt;a ‘unicorn
horn’&lt;/a&gt;
from the 1500’s, which was actually the tusk from a narwhal&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://drive.google.com/file/d/1ppN-sZDOUMoYhg2jtYfxGIPvl8CR72YlMQ/view?usp=sharing&quot;&gt;a part of the ‘True
Cross’&lt;/a&gt;,
though I swear if you added up every piece of the cross you’d have a forest&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://drive.google.com/file/d/1MUFBc9C8-ViQyJKEZjBFOYqGqsnH6ejBGw/view?usp=sharing&quot;&gt;the point from a ‘holy lance’ in
750&lt;/a&gt; -
‘a guarantee of divine assistance of victory in battle’ (after all, what’s
more holy than winning wars?)&lt;/li&gt;
  &lt;li&gt;artefacts from the ‘Order of the Golden Fleece’, a secular order of chivalry
from 1430. I don’t know what is particularly chivalrous about a sheep skin,
and the chain their members wore has &lt;a href=&quot;https://drive.google.com/file/d/1wvnBHyGsWkeNAq1qaLShzaaphxIz0fi3kw/view?usp=sharing&quot;&gt;a golden but droopy looking
sheep&lt;/a&gt;
on it.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://drive.google.com/file/d/1XzBOkiCe3p9W78aUh8zs14LeUg6VLyx2UA/view?usp=sharing&quot;&gt;the basin the royalty were baptised
in&lt;/a&gt; -
solid gold!&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://drive.google.com/file/d/1Dk7R0gbjEmlAs-GtTomkJIH4qi2ZO6U8Kw/view?usp=sharing&quot;&gt;a 2.68 carat emerald
vessel&lt;/a&gt;
which an emperor tried to use as security for a loan in the 17th century, but
was too priceless to be valued&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://drive.google.com/file/d/1tRTEdZerzUemNPvU6jTYbrB5uuD4Svyimw/view?usp=sharing&quot;&gt;a swordbelt for the imperial
sword&lt;/a&gt;,
from the 12th or 13th century&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://drive.google.com/file/d/1qQOBVje06qhh4PNlrD5C_B-hkkRn8I2plQ/view?usp=sharing&quot;&gt;John the Baptist’s
tooth&lt;/a&gt;
(apparently)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I also walked past this store on my way home:&lt;/p&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2016/07/1PPKJDW-YBVvv4gdQ2IfGsjbPmVkfb0D8ug.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2016/07/1PPKJDW-YBVvv4gdQ2IfGsjbPmVkfb0D8ug.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;p&gt;I guess marijuana is legal in Austria!&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;On Friday I went to &lt;a href=&quot;https://en.wikipedia.org/wiki/Seegrotte&quot;&gt;Seegrotte
Hinterbrühl&lt;/a&gt;. “Hinterbrühl” was an
underground gypsum mine until 1912 when a blasting operation in went awry and
20 million litres of water flooded the mine. It was opened as a tourist
attraction in 1930 and has been open to tourists since then, with the exception
of World War II.  During WWII the mine was used as a factory for &lt;a href=&quot;https://en.wikipedia.org/wiki/Heinkel_He_162&quot;&gt;Heinkel He
162&lt;/a&gt; jet fighters during, there
were 2,000 people working down there as the underground site couldn’t be
bombed.&lt;/p&gt;

&lt;p&gt;Currently 50,000 L of water have to be pumped out every day to keep the water
level constant. The water is super clean and apparently drinkable, though very
mineral heavy. It was also surprisingly cold down there at only 9 °C. The guide
was doing his thing in German, but I heard someone else translating for their
friend and asked if I could listen in.&lt;/p&gt;

&lt;p&gt;Burg Lichtenstein was also nearby. It was originally built during the 12th
century, destroyed by the Ottomans in 1529 and 1683, and remained in ruins
until 1884, when it was rebuilt. I only realised while doing some reading to
write this email that the family who established Liechtenstein the country (or
principality?) took their family name from the castle, and the country is named
after the family. The castle wasn’t open for tours, so I just had a walk around
there and the surrounding forest. There was a amphitheater built near the
castle around 1800 which is now all overgrown, it was surreal walking
through it.&lt;/p&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2016/07/16duZlchZCt8x0SffeUvqDcKewYOnv8Dl0A.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2016/07/16duZlchZCt8x0SffeUvqDcKewYOnv8Dl0A.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;p&gt;You can see almost the whole structure in the background of the image below.&lt;/p&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2016/07/18naK_i7QP6Ogndxd9E9zGvqzyk4AcS_GWw.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2016/07/18naK_i7QP6Ogndxd9E9zGvqzyk4AcS_GWw.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;hr /&gt;

&lt;p&gt;I got chatting to the two people I was eavesdropping on at the caves and they
recommended going to
&lt;a href=&quot;https://en.wikipedia.org/wiki/Schneeberg_(Alps)&quot;&gt;Schneeberg&lt;/a&gt; mountain south of
Vienna, so I decided to do that on Saturday.&lt;/p&gt;

&lt;p&gt;Getting there was a bit of a debacle - I was on the train which was meant to be
going all the way to my destination and we’d been stopped at a train station
for a while, which was odd. Soon enough a ticket inspector wandered through the
train and said something to me in German which I didn’t understand. After I
made it clear I didn’t speak German, he just said the destination station I was
going to, and I nodded. He then pointed at a train on the other side of the
station and said one of the only German words I know: “schnell, schnell!”.
“Schnell” is roughly “quick”, which was enough instruction for me. I galloped
and hopped on the other train just before it left.&lt;/p&gt;

&lt;p&gt;Eventually I made it to &lt;a href=&quot;https://en.wikipedia.org/wiki/Puchberg_am_Schneeberg&quot;&gt;Puchberg am
Schneeberg&lt;/a&gt;, which is at
the foot of the mountain. I’d been planning on maybe hiking up the mountain but
I didn’t have enough time so I caught the ‘Schneebergbahn’ train up to the top.
The track up is a cog railway that was built from 1895-1897.&lt;/p&gt;

&lt;p&gt;There was still a decent walk up to from where the train station is to the
peak, and I didn’t have loads of time, so I powered from Berghaus
Hochschneeberg (1800m) to Klosterwappenhohle (2076m) and Kaiserstein (2061m)
and then back:&lt;/p&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2016/07/0B3HUADVbsoZAU05yTngyTjRFQjNTTElDNmxJVk1UdjNEcmY4.png&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2016/07/0B3HUADVbsoZAU05yTngyTjRFQjNTTElDNmxJVk1UdjNEcmY4.png&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;p&gt;(the map above is from
&lt;a href=&quot;https://www.openstreetmap.org/way/29041905#map=15/47.7645/15.8147&quot;&gt;OpenStreetMap&lt;/a&gt;,
which is an open source alternative to Google Maps and often has more detailed
walking/hiking/biking tracks).&lt;/p&gt;

&lt;p&gt;I was a little underprepared for how windy and cold it would be up there (there
is still some snow that hasn’t melted yet). Here is me with my hands firmy in
the pockets of my inadequate jacket:&lt;/p&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2016/07/1uoLZw2r4mlSxbnqX_lSfmRXGokiAgUXGkQ.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2016/07/1uoLZw2r4mlSxbnqX_lSfmRXGokiAgUXGkQ.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;p&gt;The cold was worth it though, the views were amazing:&lt;/p&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2016/07/1drELJ5Ns0BHYC1BayfKTb8KGquKn1nsFcQ.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2016/07/1drELJ5Ns0BHYC1BayfKTb8KGquKn1nsFcQ.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2016/07/1vKp5RruWDDRjQFufizoj2Mk4zd1RMz3d5A.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2016/07/1vKp5RruWDDRjQFufizoj2Mk4zd1RMz3d5A.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2016/07/1yavnc5LQUfes6cw-Gmi96ltWA7WQw5QJ5A.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2016/07/1yavnc5LQUfes6cw-Gmi96ltWA7WQw5QJ5A.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2016/07/1MTf55i_-kGfXBJHb_rumbQ5ZS30ml3Em-A.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2016/07/1MTf55i_-kGfXBJHb_rumbQ5ZS30ml3Em-A.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;
</content>
  </entry>
  
  <entry>
    <title>BFPG talk - Functional Programming in Scala Chapters 7 &amp; 8</title>
    <link href="/2016/06/talk_fp_in_scala_7_8/"/>
    <updated>2016-06-19T00:00:00+00:00</updated>
    <id>/2016/06/talk_fp_in_scala_7_8/</id>
    <category term="software-tech" label="Software/Tech"></category>
    <content type="html">&lt;p&gt;In May, I presented a talk based on Chapters 7 &amp;amp; 8 of &lt;a href=&quot;https://www.manning.com/books/functional-programming-in-scala&quot;&gt;Functional Programming
in Scala&lt;/a&gt; at the
&lt;a href=&quot;http://www.meetup.com/Brisbane-Functional-Programming-Group/&quot;&gt;Brisbane Functional Programming
Group&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The talk explores the design and implementation of two functional libraries, one for
parallelism and one for property based testing.&lt;/p&gt;

&lt;p&gt;The video of the talk (also embedded below) is now available online at
&lt;a href=&quot;http://talks.bfpg.org/talks/2016-05-10.talk_fp_in_scala_7_8.html&quot;&gt;the BFGP talks site&lt;/a&gt;,
along with a link to the slides.&lt;/p&gt;

&lt;p&gt;See &lt;a href=&quot;http://talks.bfpg.org/past.html&quot;&gt;http://talks.bfpg.org/past.html&lt;/a&gt; for
other past BFPG presentations.&lt;/p&gt;

&lt;div class=&quot;embed-container&quot;&gt;&lt;iframe src=&quot;https://www.youtube.com/embed/ZSKeOZMoWUg&quot; frameborder=&quot;0&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;&lt;/div&gt;
</content>
  </entry>
  
  <entry>
    <title>-Xlint:unchecked and -Werror for Java projects with Gradle</title>
    <link href="/2016/05/werror-java-gradle/"/>
    <updated>2016-05-04T00:00:00+00:00</updated>
    <id>/2016/05/werror-java-gradle/</id>
    <category term="software-tech" label="Software/Tech"></category>
    <content type="html">&lt;p&gt;I was recently working in a codebase where there were chunks of Java code that
used generic interfaces from the Apache Commons Collections project as well as
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;java.util&lt;/code&gt; Collections in a type unsafe way, even though the
interfaces/classes that were being used supported generics.&lt;/p&gt;

&lt;p&gt;Our gradle build was emitting the following warning:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;:compileJavaNote: Some input files use unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This warning should be an error in my books. It’s possible to get this
behaviour by adding the following to your &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;build.gradle&lt;/code&gt; file:&lt;/p&gt;

&lt;div class=&quot;language-groovy highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;tasks&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;withType&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;JavaCompile&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;options&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;compilerArgs&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;-Xlint:unchecked&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;-Werror&quot;&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This way, when our code is built everyone is aware when they’re using unsafe
operations, and can either fix the issue or supress the warning with
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;@SupressWarnings(&quot;unchecked&quot;)&lt;/code&gt; if it’s intentional.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>Johannesburg &amp; the ThoughtWorks Pan Africa Away Day 2016</title>
    <link href="/2016/02/johannesburg/"/>
    <updated>2016-02-29T00:00:00+00:00</updated>
    <id>/2016/02/johannesburg/</id>
    <category term="travel" label="Travel"></category>
    <content type="html">&lt;p&gt;I’m back in Australia after a quick trip to South Africa to attend the
ThoughtWorks Pan Africa Away Day 2016.&lt;/p&gt;

&lt;p&gt;I left on Tuesday morning, and was early to the airport in Brisbane so I got on
an earlier flight to Sydney before flying to Johannesburg. The flight from
SYD-JNB was good, it was the first time I’ve flown with Qantas internationally
and I was pretty impressed. I was following the sun so by the time it got dark
here I’d been in daylight for about 20 hrs which was a very long day!&lt;/p&gt;

&lt;p&gt;ThoughtWorks SA had organised a pickup from the airport and the hotel, so a
driver picked me up from the airport. On the way to the hotel he told me about
how different areas had different races living in them during apartheid. Some
nicer looking houses have very serious security, but apparently home invasions
are becoming less of a problem. There were still some questionable characters
in parts though so I’m sure home invasions still happen, it’s interesting how
much the crime rate varies depending on who you talk to.&lt;/p&gt;

&lt;p&gt;I spent Wednesday in the ThoughtWorks office. It’s a nice office and much
bigger than Brisbane despite having a similar number of people working out of
it. I met some of the locals and another traveller here for the away day from
Brazil. All up there were 32 international visitors, some there doing talks,
some attending like I was and a lot from ThouthWorks leadership/management. The
guests were from Brazil, China, Ecuador, Germany, India, Kenya, Singapore,
Turkey, UK and the US.&lt;/p&gt;

&lt;p&gt;On Thursday we did a tour of Soweto, an area in Johannesburg. First we walked
through some of Motsoaledi, an ‘informal settlement’ (a.k.a.
shantytown/favela). There are around 8,000 people living there - you should be
able to pick it out on &lt;a href=&quot;https://www.google.com.au/maps/place/Motsoaledi+Bus+Stop/@-26.2650095,27.9321694,1881m/data=!3m1!1e3!4m2!3m1!1s0x1e9509d6b3d04e51:0xa5e5beaf93ddffe7&quot;&gt;Google Maps&lt;/a&gt;. One thing I found pretty
crazy in all these areas is how much Coca Cola sponsors things - most people
there don’t have running water, but there are Coke signs everywhere!&lt;/p&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2016/02/welcome-to-motsoaledi.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2016/02/welcome-to-motsoaledi.jpg&quot; alt=&quot;Coca Cola sign in Motsoaledi&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;p&gt;From there we went to Vilakazi Street, which is the only street in the world to
have two Nobel Peace Prize winners living there - Nelson Mandela and Desmond
Tutu. Mandela’s house is a typical government built house from that era, a very
basic four bedroom place. It’s now a (small) museum:&lt;/p&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2016/02/mandela-house-museum.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2016/02/mandela-house-museum.jpg&quot; alt=&quot;Panoramic shot of Mandela&apos;s old house, showing that it&apos;s now a museum&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;p&gt;After reading some of what he and his family put up with, it’s pretty amazing
he was as forgiving as he was when was released from jail!&lt;/p&gt;

&lt;p&gt;We also went to the &lt;a href=&quot;https://en.wikipedia.org/wiki/Hector_Pieterson_Museum&quot;&gt;Hector Pieterson Museum&lt;/a&gt; which is all about the
anti-Afrikaans Soweto Uprising - in 1976 some politician decided that all
schools (where students were already struggling with English) would now run
lessons in Afrikaans. A whole load of students refused to go to school, and
lead a march and the police reacted pretty brutally - 13-year-old Hector
Pieterson was one of the first to be shot dead.&lt;/p&gt;

&lt;p&gt;On Friday we left to &lt;a href=&quot;http://khayaconference.co.za/&quot;&gt;Khaya iBhubesi&lt;/a&gt;, the venue for the Away
Day. Despite the name translating to ‘home of the lion’ there wasn’t a lot of
wildlife around, though there were some lions there in an enclosure.&lt;/p&gt;

&lt;p&gt;Friday and Saturday were mostly talks from ThoughtWorks Global and Africa
leadership. There were events on Friday and Saturday night too, so I didn’t get
a whole load of sleep (though I think that made jetlag easier to handle when I
got back; I slept the whole flight back and then the whole night on Monday
too!).&lt;/p&gt;

&lt;p&gt;On Sunday we drove back to Johannesburg and then I went with two people from
the Ecuador office to the Apartheid Museum. It’s crazy how arbitrary the laws
were in that time!&lt;/p&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2016/02/apartheid-museum-methods-to-determine-race.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2016/02/apartheid-museum-methods-to-determine-race.jpg&quot; alt=&quot;Sign showing that aspects like which sports someone played where used to detmine their &apos;race&apos;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2016/02/chameleons.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2016/02/chameleons.jpg&quot; alt=&quot;Sign explaining how in 1985 at least 1000 people &apos;changed race&apos;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;p&gt;After the museum I was off to the airport.&lt;/p&gt;

&lt;p&gt;It was a really good trip even if it was a bit quick. It would have been good
if I had more notice and could plan to visit other countries in Africa, but I
guess that will have to wait until next time!&lt;/p&gt;

</content>
  </entry>
  
  <entry>
    <title>Pedantic console for JavaScript tests</title>
    <link href="/2016/01/pedantic-console/"/>
    <updated>2016-01-30T00:00:00+00:00</updated>
    <id>/2016/01/pedantic-console/</id>
    <category term="software-tech" label="Software/Tech"></category>
    <content type="html">&lt;p&gt;When running JavaScript tests that fire up a browser, it can be useful to
ensure that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;console.warn&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;console.error&lt;/code&gt; aren’t being called, and to have
your automated build fail if this starts happening.&lt;/p&gt;

&lt;p&gt;If you’re using a framework like Jasmine, you can place the following file in
your helpers directory to ensure that an exception will be thrown whenever a
call is made to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;console.warn&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;console.error&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;error&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;

  &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;originalConsole&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;myError&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;originalConsole&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;apply&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;arguments&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;console.error called, failing test&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;myError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;})();&lt;/span&gt;


&lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;warn&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;

  &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;originalConsole&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;warn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;myError&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;originalConsole&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;apply&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;arguments&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;console.warn called, failing test&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;myError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;})();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;I recently used this to locate all the places that &lt;a href=&quot;https://github.com/moment/moment/issues/1407&quot;&gt;a deprecated Moment.js
feature&lt;/a&gt; was being used in a
codebase.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>Haskell stack, Yesod and Docker</title>
    <link href="/2016/01/haskell-stack-yesod-docker/"/>
    <updated>2016-01-01T00:00:00+00:00</updated>
    <id>/2016/01/haskell-stack-yesod-docker/</id>
    <category term="software-tech" label="Software/Tech"></category>
    <content type="html">&lt;h2 id=&quot;the-why&quot;&gt;The why&lt;/h2&gt;

&lt;p&gt;Over the break I’ve been working on a web app to replace a fairly old MS Access
Database that I built for my Dad to use in 2009 (he has a &lt;a href=&quot;https://www.facebook.com/Ross-Newman-Mobile-Vet-1461582037471594/&quot;&gt;mobile vet
business&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;This seemed like a good chance to try out
&lt;a href=&quot;http://www.yesodweb.com/&quot;&gt;Yesod&lt;/a&gt;, a web framework for Haskell. The Yesod
philosophy is to leverage the Haskell type system wherever possible. For
example, in the Hamlet templating language everything from generating URLs to
including static files and generating forms is checked at compile time.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://haskellstack.org&quot;&gt;stack&lt;/a&gt; is a cross platform build tool for developing
Haskell programs which (when combined with
&lt;a href=&quot;https://www.stackage.org/&quot;&gt;Stackage&lt;/a&gt; makes Haskell development much more
enjoyable.&lt;/p&gt;

&lt;p&gt;I’d recommend stack for any new Haskell project, and hopefully this post can
point someone else in the right direction for a stack/Yesod/Docker project.&lt;/p&gt;

&lt;p&gt;I built a very basic site with Yesod and stack locally on OS X, based off the
yesod-postgres template (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;stack new mysite yesod-postgres&lt;/code&gt;). The yesod dev
server makes this all very easy, just running &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;stack exec -- yesod devel&lt;/code&gt; will
keep Yesod running and recompiling the app whenever any changes are made.&lt;/p&gt;

&lt;p&gt;Soon it was time to make the app available somewhere in order to start
getting some feedback. At this stage, the most basic requirement for the
hosting was that it be low cost. Digital Ocean came to mind (use &lt;a href=&quot;https://www.digitalocean.com/?refcode=c55b676d3a2e&quot;&gt;this
link&lt;/a&gt; for $10 credit), and
I’m now using their one-click Docker droplet at USD $5 per month. This host can
run both the Yesod frontend and the PostgreSQL database.&lt;/p&gt;

&lt;p&gt;Binaries built locally on OS X won’t run on a Linux-based Digital Ocean droplet,
and it was a bit early to spend $$ on something like Snap or Travis, so I needed
a VM or container to run the build in.&lt;/p&gt;

&lt;h2 id=&quot;the-how&quot;&gt;The how&lt;/h2&gt;

&lt;h3 id=&quot;set-up&quot;&gt;Set up&lt;/h3&gt;

&lt;p&gt;stack has support for Docker to run the build and package the application, but
it isn’t currently supported when using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;boot2docker&lt;/code&gt; (see
&lt;a href=&quot;https://github.com/commercialhaskell/stack/issues/194&quot;&gt;these&lt;/a&gt;
&lt;a href=&quot;https://github.com/commercialhaskell/stack/issues/488&quot;&gt;issues&lt;/a&gt;), so I used a
simple Vagrantfile to start up a beefy VM:&lt;/p&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;no&quot;&gt;Vagrant&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;configure&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;

  &lt;span class=&quot;n&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;vm&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;box&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;puppetlabs/centos-6.6-64-nocm&quot;&lt;/span&gt;

  &lt;span class=&quot;n&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;vm&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;provider&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;virtualbox&quot;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vb&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;vb&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;memory&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;4096&quot;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;vb&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;cpus&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;vb&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;customize&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;modifyvm&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;--ioapic&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;on&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

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

&lt;p&gt;Centos 6.6 might seem like an odd choice for a development environment, but the
Vagrant box was already on my laptop, so using it saved me the download time
(bandwidth is a precious commodity in semi-rural Australia).&lt;/p&gt;

&lt;p&gt;I didn’t bother setting up provisioning properly, but here are the commands
that are needed to get stack working:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# Add FP Complete repo &amp;amp; install stack&lt;/span&gt;
curl &lt;span class=&quot;nt&quot;&gt;-sSL&lt;/span&gt; https://s3.amazonaws.com/download.fpcomplete.com/centos/6/fpco.repo | &lt;span class=&quot;nb&quot;&gt;sudo tee&lt;/span&gt; /etc/yum.repos.d/fpco.repo
&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;yum &lt;span class=&quot;nt&quot;&gt;-y&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;install &lt;/span&gt;stack

&lt;span class=&quot;c&quot;&gt;# Add EPEL repo and install Docker&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;rpm &lt;span class=&quot;nt&quot;&gt;-iUvh&lt;/span&gt; http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm
&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;yum &lt;span class=&quot;nt&quot;&gt;-y&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;install &lt;/span&gt;docker-io

&lt;span class=&quot;c&quot;&gt;# stack requires the Docker client to be able to connect&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# to the daemon without root, so add vagrant user to dockerroot group&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;gpasswd &lt;span class=&quot;nt&quot;&gt;-a&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;USER&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt; dockerroot

&lt;span class=&quot;c&quot;&gt;# At this point, you&apos;ll need to log out and back in for&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# the group change to take effect&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Setup iptables to allow Docker links to work&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;iptables &lt;span class=&quot;nt&quot;&gt;-t&lt;/span&gt; filter &lt;span class=&quot;nt&quot;&gt;-A&lt;/span&gt; DOCKER &lt;span class=&quot;nt&quot;&gt;-d&lt;/span&gt; 172.17.0.0/16 &lt;span class=&quot;nt&quot;&gt;-i&lt;/span&gt; docker0 &lt;span class=&quot;nt&quot;&gt;-j&lt;/span&gt; ACCEPT
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Adding the vagrant user to dockerroot comes with all the usual security issues,
but I’m not too worried about that here. There are some other suggestions in
the &lt;a href=&quot;http://docs.haskellstack.org/en/stable/docker_integration.html#docker&quot;&gt;stack documentation&lt;/a&gt;
for how to handle this.&lt;/p&gt;

&lt;h3 id=&quot;running-the-build&quot;&gt;Running the build&lt;/h3&gt;

&lt;p&gt;So, stack and Docker are now both installed. Enabling stack’s Docker
integration on the VM is as simple as modifying the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;~/.stack/config&lt;/code&gt; file:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[vagrant@localhost ~]$ cat ~/.stack/config.yaml
docker:
  enable: true
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This gives the advantage of using Docker to run the builds on the VM, while not impacting
the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;yesod devel&lt;/code&gt; workflow on OS X.&lt;/p&gt;

&lt;p&gt;By default stack will use the fpco/stack-build repository to obtain an image to
run the build in. This suits me, as there is also fpco/stack-run for running the
binaries once they’re compiled. The build image includes everything that’s necessary
for building the whole of Stackage, whereas stack-run is more trimmed down.&lt;/p&gt;

&lt;p&gt;Running &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;stack build&lt;/code&gt; kicked off the build in the Docker container, which
completed successfully as all required dependencies (e.g. libpq and pg_config)
were already in the image. Thanks to &lt;a href=&quot;https://www.fpcomplete.com/&quot;&gt;FP Complete&lt;/a&gt;
for setting up these Docker containers for everyone to use!&lt;/p&gt;

&lt;h3 id=&quot;packaging-docker-image&quot;&gt;Packaging Docker image&lt;/h3&gt;

&lt;p&gt;stack’s support for creating container images is a relatively recent addition,
and currently isn’t covered well in the documentation. There is a reference to the
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;image&lt;/code&gt; configuration section &lt;a href=&quot;http://docs.haskellstack.org/en/stable/yaml_configuration.html#image&quot;&gt;here&lt;/a&gt;,
which was enough for my needs. After added the relevant bits, my &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;stack.yml&lt;/code&gt;
looks something like:&lt;/p&gt;

&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;na&quot;&gt;resolver&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;lts-3.20&lt;/span&gt;

&lt;span class=&quot;na&quot;&gt;packages&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;.&apos;&lt;/span&gt;

&lt;span class=&quot;na&quot;&gt;extra-deps&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;pi&quot;&gt;[]&lt;/span&gt;

&lt;span class=&quot;na&quot;&gt;flags&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;mysite&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;library-only&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;false&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;dev&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;false&lt;/span&gt;

&lt;span class=&quot;na&quot;&gt;extra-package-dbs&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;pi&quot;&gt;[]&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# This isn&apos;t required as it&apos;s set in the user config on the VM&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# docker:&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;#     enable: true&lt;/span&gt;

&lt;span class=&quot;na&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;container&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;mdjnewman/mysite&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;base&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;fpco/stack-run&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;/app/config&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;static&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;/app/static&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;With that in place, running &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;stack image container&lt;/code&gt; produced a Docker container
ready to be pushed to Docker Hub:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[vagrant@localhost vagrant]$ stack image container
Sending build context to Docker daemon 34.25 MB
Sending build context to Docker daemon
Step 0 : FROM fpco/stack-run
 ---&amp;gt; db9b2a858ef5
Step 1 : ADD ./ /
 ---&amp;gt; e682c572d7ed
Removing intermediate container 1ce35ed1ccea
Successfully built e682c572d7ed
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Running a regular &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;docker push&lt;/code&gt; published the image to the registry.&lt;/p&gt;

&lt;h3 id=&quot;deploying-to-digital-ocean&quot;&gt;Deploying to Digital Ocean&lt;/h3&gt;

&lt;p&gt;After all these steps, the final package was in Docker Hub and it was just a
matter of running the following commands on the droplet, and the site was live:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;docker run &lt;span class=&quot;nt&quot;&gt;--name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;postgres &lt;span class=&quot;nt&quot;&gt;-e&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;POSTGRES_PASSWORD&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;$(&lt;/span&gt;uuidgen&lt;span class=&quot;si&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-e&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;POSTGRES_USER&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;postgres &lt;span class=&quot;nt&quot;&gt;-d&lt;/span&gt; postgres:9.3

&lt;span class=&quot;c&quot;&gt;# Yes, I know UUIDs don&apos;t make the best passwords :)&lt;/span&gt;

docker run              &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;-d&lt;/span&gt;                  &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;-w&lt;/span&gt; /app             &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;--link&lt;/span&gt; postgres:postgres         &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;-p&lt;/span&gt; 3000:3000        &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    mdjnewman/mysite    &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    /bin/bash &lt;span class=&quot;nt&quot;&gt;-c&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;PGHOST=$POSTGRES_PORT_5432_TCP_ADDR PGPASS=$POSTGRES_ENV_POSTGRES_PASSWORD /usr/local/bin/mysite&apos;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The last command is running the Yesod server, with environment variables set to
the values provided by Docker (see
&lt;a href=&quot;https://github.com/yesodweb/yesod/wiki/Configuration#overriding-configuration-values-with-environment-variables&quot;&gt;here&lt;/a&gt; for info about setting configuration variables in Yesod).&lt;/p&gt;

&lt;h2 id=&quot;the-results&quot;&gt;The results&lt;/h2&gt;

&lt;p&gt;I’m very happy with the Yesod workflow, and stack’s Docker integration makes
deploying a lot easier as I don’t have to worry about what packages are in my
build and test environments. Seems like a good compromise between manually
copying files around and having a full CD pipeline.&lt;/p&gt;

&lt;p&gt;Using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;stack build&lt;/code&gt; with a LTS resolver and an isolated container is also the
holy grail of repeatable builds!&lt;/p&gt;

&lt;p&gt;There is still a lot that would need to be done (improving security, backups,
logging etc) before this was closer to a production environment, but it’s good
enough as a development region.&lt;/p&gt;

&lt;p&gt;This whole process (including writing this post) from having something that I
wanted to deploy to being able to view the live site took less than a day,
and I was learning a lot along the way. Deciding where was the best place to
host the site and waiting for Docker to pull the fpco/stack-build image took up
most of the time!&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>Simon Peyton Jones on maintenance with strong types</title>
    <link href="/2014/06/simon-peyton-jones-on-maintenance-with-strong-types/"/>
    <updated>2014-06-26T00:00:00+00:00</updated>
    <id>/2014/06/simon-peyton-jones-on-maintenance-with-strong-types/</id>
    <category term="software-tech" label="Software/Tech"></category>
    <content type="html">&lt;blockquote&gt;
  &lt;p&gt;People don’t like fixing type errors, but they are a lot easier to fix than runtime errors… The single biggest thing going for static typing is not so much that it helps you write your program in the first place, but it helps you maintain your program.&lt;/p&gt;

  &lt;p&gt;GHC itself is an example – it’s now 150,000 lines of Haskell &amp;amp; twenty years old and I regularly refactor it in pretty large scale ways. I just wouldn’t dare do that if I didn’t have static typing to keep me sane. It’s this enormous code base, chunks of which I’ve forgotten about, and yet I can confidently make systemic changes to it because I know the type checker is going to catch all the places that change needs to go.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Simon Peyton Jones, speaking on &lt;a href=&quot;http://www.functionalgeekery.com/episode-11-simon-peyton-jones/&quot; title=&quot;Functional Geekery Episode 11 – Simon Peyton Jones&quot;&gt;Functional Geekery Episode 11&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The part about GHC is anecdotal evidence, to be sure, but it makes the point nicely.&lt;/p&gt;

</content>
  </entry>
  
  <entry>
    <title>Why Functional Programming Matters</title>
    <link href="/2014/06/why-functional-programming-matters/"/>
    <updated>2014-06-13T00:00:00+00:00</updated>
    <id>/2014/06/why-functional-programming-matters/</id>
    <category term="software-tech" label="Software/Tech"></category>
    <content type="html">&lt;p&gt;The following is the conclusion from a paper entitled ‘Why Functional Programming Matters’:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;In this paper, we’ve argued that modularity is the key to successful programming. Languages that aim to improve productivity must support modular programming well. But new scope rules and mechanisms for separate compilation are not enough — modularity means more than modules. Our ability to decompose a problem into parts depends directly on our ability to glue solutions together. To support modular programming, a language must provide good glue. Functional programming languages provide two new kinds of glue — higher-order functions and lazy evaluation. Using these glues one can modularize programs in new and useful ways, and we’ve shown several examples of this. Smaller and more general modules can be reused more widely, easing subsequent programming. This explains why functional programs are so much smaller and easier to write than conventional ones. It also provides a target for functional programmers to aim at. If any part of a program is messy or complicated, the programmer should attempt to modularize it and to generalize the parts. He or she should expect to use higher-order functions and lazy evaluation as the tools for doing this.&lt;/p&gt;

  &lt;p&gt;Of course, we are not the first to point out the power and elegance of higher-order functions and lazy evaluation. For example, Turner shows how both can be used to great advantage in a program for generating chemical structures. Abelson and Sussman stress that streams (lazy lists) are a powerful tool for structuring programs. Henderson has used streams to structure functional operating systems. But perhaps we place more stress on functional programs’ modularity than previous authors.&lt;/p&gt;

  &lt;p&gt;This paper is also relevant to the present controversy over lazy evaluation. Some believe that functional languages should be lazy; others believe they should not. Some compromise and provide only lazy lists, with a special syntax for constructing them (as, for example, in Scheme). This paper provides further evidence that lazy evaluation is too important to be relegated to second-class citizenship. It is perhaps the most powerful glue functional programmers possess. One should not obstruct access to such a vital tool.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href=&quot;http://comjnl.oxfordjournals.org/content/32/2/98.short&quot; title=&quot;Why Functional Programming Matters&quot;&gt;J. Hughes, “Why Functional Programming Matters,” Comput. J., vol. 32, pp. 98–107, 1989.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This paper was written twenty years ago – the more things change, the more they stay the same. I’d urge any programmer (whether currently interested in FP or otherwise) to read this paper if you haven’t already.&lt;/p&gt;

</content>
  </entry>
  
  <entry>
    <title>ThoughtWorks LevelUp EXP Brisbane – Take 2</title>
    <link href="/2014/05/thoughtworks-levelup-exp-brisbane-take-2/"/>
    <updated>2014-05-05T00:00:00+00:00</updated>
    <id>/2014/05/thoughtworks-levelup-exp-brisbane-take-2/</id>
    <category term="software-tech" label="Software/Tech"></category>
    <content type="html">
&lt;figure&gt;
    &lt;a href=&quot;/public/images/2014/05/ThoughtWorks-LevelUp-EXP-Brisbane-May-2014.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2014/05/ThoughtWorks-LevelUp-EXP-Brisbane-May-2014.jpg&quot; alt=&quot;&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    LevelUp EXP Brisbane Attendees (thanks Alexandra Tran for the photo!)
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;p&gt;ThoughtWorks ran another great express &lt;a href=&quot;https://www.thoughtworks.com/en-au/about-us/events/level-up&quot; title=&quot;LevelUp&quot;&gt;LevelUp&lt;/a&gt; event on Saturday at their Brisbane office. LevelUp events aim to help students bridge the gap between university and their first full-time job. LevelUp EXP is a mini-conference with a number of talks and hands on sessions, as well as lots of opportunities to mingle with the ThoughtWorks employees and other attendees. One theme that recurred through almost every talk of the day was focussing on the user at every stage of the development process – if you’re not building something that your users can use, then you’re wasting time. This does mean &lt;strong&gt;users&lt;/strong&gt;, not customers. You can be building a product for a client, but it’s ultimately the user’s experience that will determine success.&lt;/p&gt;

&lt;h2 id=&quot;real-project-example-dominos-html5-in-brisbane&quot;&gt;Real Project Example: Domino’s HTML5 in Brisbane&lt;/h2&gt;

&lt;p&gt;First up was Mark Ryall (&lt;a href=&quot;https://twitter.com/markryall&quot; title=&quot;Mark Ryall (markryall) on Twitter&quot;&gt;@markryall&lt;/a&gt;) discussing the recent consolidation of three separate websites into a single HTML5 site for the Dominos pizza franchise in Australia, New Zealand and the Netherlands. The new site was to replace separate Flash, mobile and accessibility-focussed sites, and was a greenfield project. From a software process perspective, the project kicked off with a two-week inception where BAs, developers, designers and testers worked together for two weeks to get initial requirements worked out. Mark pointed out that this is an effective alternative to the business struggling to work out requirements on their own for six months before getting anyone else involved. It reminded me of the quote that’s often attributed to Henry Ford:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;If I’d asked people what they wanted, they would have said a faster horse.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The point is that the business doesn’t always know what they want, and even if they do, they may not be able to articulate that in such a way that both parties have the same vision. The rest of the project ran in two-week iterations, with showcases at the end of every iteration. Mark mentioned that the biggest challenges (from a technical perspective) in this project were internationalisation (I18N) and localisation. As Mark explained it, internationalisation ensures everything is available in the correct languages for the correct region, whereas localisation focusses on differences such as different address formats (another example of what this site in particular has to handle is that Domino’s in NL doesn’t provide catering, like it does in AU). There was a heavy emphasis on test automation in this project, and &lt;a href=&quot;http://docs.seleniumhq.org/projects/webdriver/&quot; title=&quot;Selenium WebDriver&quot;&gt;Selenium WebDriver&lt;/a&gt; was used for automated browser testing. WebDriver allows single tests to be written to target more than one browser, and are more robust than trying to guess what the browser is doing and interspersing your tests with loads of sleep() calls. In order to make tests more readable for everyone on the project (BAs/the business included), &lt;a href=&quot;http://www.specflow.org/&quot; title=&quot;Specflow - Cucumber for .NET&quot;&gt;Specflow&lt;/a&gt; was used. Specflow is a .NET alternative to Cucumber, and uses a similar declarative style to define specifications &amp;amp; expected behaviour. Tests are then generated from these easy to read specifications, targeting whichever testing framework you’re using (NUnit in this case). Given this site was replacing an existing site with a focus on accessibility, Domino’s required this site to be just as accessible for people using screen readers and keyboard only navigation. Accessibility is something that is easy to overlook, but every developer should make the effort to do these things correctly (using alternative text, &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA&quot; title=&quot;ARIA - Accessibility | MDN&quot;&gt;ARIA tags&lt;/a&gt;, skip links for navigation etc). If you want to know more about how important accessibility is, Scott Hanselman recently did an &lt;a href=&quot;http://www.hanselminutes.com/413/im-a-blind-software-technician-ask-me-anything-with-katherine-moss&quot; title=&quot;I&apos;m a Blind Software Technician - Ask Me Anything! with Katherine Moss&quot;&gt;interesting interview with Katherine Moss&lt;/a&gt;, a blind software technician.&lt;/p&gt;

&lt;h2 id=&quot;the-lego-game&quot;&gt;The Lego Game&lt;/h2&gt;

&lt;p&gt;The Lego Game is a game designed to give you a taste of the Agile software development process.  Our task was building a Lego ‘animal’ with a client in mini sprints lasting a few minutes each. We worked through everything from estimation to a retrospective in less than ten minutes, and completed three iterations with a client who wasn’t afraid to change their mind. An interesting resource that was mentioned by the ThoughtWorks employees running the Lego game was the Retrospective Prime Directive by Norman Keith:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Regardless of what we discover, we understand and truly believe that everyone did the best job they could, given what they knew at the time, their skills and abilities, the resources available, and the situation at hand.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I thought this was a good guideline for running retrospectives, as it ensures that you focus on what went well and what can be improved, and not on trying to assign blame. There are &lt;a href=&quot;https://www.google.com.au/search?q=agile+lego+game&quot; title=&quot;agile lego game - Google&quot;&gt;plenty of pages&lt;/a&gt; describing the agile Lego game on the net if you want to read more.&lt;/p&gt;

&lt;h2 id=&quot;agile-101-with-a-business-analyst&quot;&gt;Agile 101 with a Business Analyst&lt;/h2&gt;

&lt;p&gt;Agile 101 with a BA by &lt;a href=&quot;https://henrylawson.net/&quot; title=&quot;Henry Lawson: Home&quot;&gt;Henry Lawson&lt;/a&gt; was the first of the twenty-minute lightning talks for the day. In twenty minutes, Henry managed to cover a brief history of Agile, the Agile manifesto and different Agile methodologies. There was more about Agile on the cards but the twenty-minute timeline had to be adhered to! The following paragraphs sum up the main points of the talk.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Agile manifesto&lt;/strong&gt;: the &lt;a href=&quot;http://agilemanifesto.org/&quot; title=&quot;Manifesto for Agile Software Development&quot;&gt;Agile manifesto&lt;/a&gt; is what gave the movement towards iterative, lightweight processes a name. Written in 2001 by several prominent figures in the software industry, the core of the Agile manifesto is the following four points:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Individuals and interactions over processes and tools&lt;/li&gt;
  &lt;li&gt;Working software over comprehensive documentation&lt;/li&gt;
  &lt;li&gt;Customer collaboration over contract negotiation&lt;/li&gt;
  &lt;li&gt;Responding to change over following a plan&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;The differences between traditional Waterfall methodologies and Agile&lt;/strong&gt;: The waterfall model is a sequential design process, where each stage is completed and locked-down before the next is started.&lt;/p&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2014/05/waterfall-model.png&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2014/05/waterfall-model.png&quot; alt=&quot;Waterfall model of system development&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    Waterfall model of system development – avoid it! (you want the cycle above to take two weeks, not twelve months) (&lt;a href=&quot;http://en.wikipedia.org/wiki/File:Waterfall_model.svg&quot; title=&quot;File:Waterfall model.svg&quot;&gt;source&lt;/a&gt;)
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;p&gt;While waterfall might work for other engineering projects (like building a bridge), it’s not really suitable for software development (too many software projects have elements of a &lt;a href=&quot;https://en.wikipedia.org/wiki/Wicked_problem&quot; title=&quot;Wicked problem - Wikipedia&quot;&gt;wicked problem&lt;/a&gt;). I won’t go into the benefits of Agile or Agile processes in too much detail here, as there is plenty more information available.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Different agile methodologies&lt;/strong&gt;: Examples of agile methodologies include Scrum, Kanban, Lean, XP and Crystal Clear. The main difference between these methodologies is the practices, such as daily Scrum meetings or pair programming in XP. The general processes are similar, and there is no reason you can’t mix and match.&lt;/p&gt;

&lt;h2 id=&quot;functional-programming&quot;&gt;Functional Programming&lt;/h2&gt;

&lt;p&gt;Hugo Firth (&lt;a href=&quot;https://twitter.com/hugo_firth&quot; title=&quot;Hugo (hugo_firth) on Twitter&quot;&gt;@hugo_firth&lt;/a&gt;) was giving the next lightning talk, this time with a quick intro to functional programming concepts. There are a number of programming paradigms, such as procedural and object-oriented (OO). Procedural code (e.g. C/BASIC code) doesn’t provide many ways to create abstractions and manage state. OO, such as you’ve probably encountered in Java/C#/C++ allows abstractions to hide global state. Functional programming on the other hand is all about removing state where possible, and programming with pure functions. Hugo went through some common functions you’ll meet in functional programming, such as map &amp;amp; filter by providing some simple examples in Clojure. If you want to see a less rushed presentation by Hugo, his recent talk at the Brisbane Functional Programming Group is available on Vimeo.&lt;/p&gt;

&lt;div class=&quot;embed-container&quot;&gt;&lt;iframe src=&quot;https://player.vimeo.com/video/80576311&quot; frameborder=&quot;0&quot; webkitallowfullscreen=&quot;&quot; mozallowfullscreen=&quot;&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href=&quot;http://www.meetup.com/Brisbane-Functional-Programming-Group/&quot; title=&quot;Brisbane Functional Programming Group (BFPG) (Brisbane)&quot;&gt;BFPG&lt;/a&gt; is a great community if you’re looking to learn more about functional programming – I’ve always found everyone there to be extremely willing to help.&lt;/p&gt;

&lt;h2 id=&quot;working-in-different-environments-from-heaven-to-hell&quot;&gt;Working in different environments… from Heaven to Hell&lt;/h2&gt;

&lt;p&gt;The last lightning talk in the first session was by Claudia Ferreira (&lt;a href=&quot;https://twitter.com/claudia_onfire&quot; title=&quot;claudia ferreira (claudia_onfire) on Twitter&quot;&gt;@claudia_onfire&lt;/a&gt;), providing some practical advice for dealing with difficult work environments. You shouldn’t assume that the end of uni is the end of the hard work. Starting a new job, meeting new people and adapting to company culture is just as hard. Also, you don’t want to fall into the trap of thinking that you know everything and that you can stop learning. There is an almost endless variety of work environments, some good and some not so great. Claudia showed the following clip from The Matrix and told us about a time she was in this exact position.&lt;/p&gt;

&lt;div class=&quot;embed-container&quot;&gt;&lt;iframe src=&quot;https://www.youtube.com/embed/c_Ot1OEfk9I&quot; frameborder=&quot;0&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;&lt;/div&gt;

&lt;p&gt;Claudia’s boss basically said you’re here to work, not think, and there are hundreds of people who can fill this spot if you aren’t happy with that. Hopefully you won’t find yourself in a situation this extreme, but chances are you’ll have a boss you’re not overly excited about working with at some point in your career. If you find yourself in this situation, don’t just bottle it up and say nothing. Your team is there to help, you should be able to trust them and speak to them about issues. It’s important to have a good relationship with your team, as they’re the people that you spend the majority of your day with. So don’t stress if you’re confronted with a difficult situation, just take a deep breath, speak up if you really don’t agree and be the bigger person.&lt;/p&gt;

&lt;h2 id=&quot;the-way-of-the-consultant&quot;&gt;The Way of the Consultant&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;http://vizualize.me/panda#.U2bXgfmSzOM&quot; title=&quot;vizualize.me - Sarbashrestha Panda&quot;&gt;Sarbashrestha Panda&lt;/a&gt; has been a consultant for 5-6 years, working as an analyst and project manager on many projects. There are many types of consulting, from technical to business strategy. Technical consulting still has a strong focus on the business needs, no matter what area you’re in you are helping solve a problem the business is having. As Panda explained it, the role of the consultant is to always ask the difficult questions and have the difficult conversations. You want to make a problem visible, make people think and help to implement solutions. As a consultant, your knowledge should drive change.&lt;/p&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2014/05/rhino-painting.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2014/05/rhino-painting.jpg&quot; alt=&quot;Rhinoceros painting&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    Most problems are people problems - recognise that everyone has a different perspective (&lt;a href=&quot;http://alligator-sunglasses.com/post/8929519267/poor-rhinoceros&quot; title=&quot;Poor rhinoceros&quot;&gt;source&lt;/a&gt;)
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;p&gt;If you’re working as a consultant, embrace the opportunity to work on many different projects – you can’t develop a broad skill set without experience. You can be a consultant in any language with any technology, and after a few years should develop the skills to become a consultant for a specific domain. Don’t let yourself get cornered into a specific technology – technologies change far too fast.&lt;/p&gt;

&lt;h2 id=&quot;ui-dev-what-and-why&quot;&gt;UI Dev. What and Why?&lt;/h2&gt;

&lt;p&gt;Eru Penkman gave the next talk, which was originally entitled ‘UI Dev. What and Why?’, but seemed to have transformed into a talk about programmer culture and day-to-day life. Eru pointed out a bunch of things that a lot of programmers/developers have in common. Most of the people in the room had read XKCD at some point, everyone had used Stack Overflow, lots of people read similar blogs etc. Having all these elements in common helps when working in a team, which as Eru pointed out is pretty much what development is about. It’s very rare to have a project where you don’t interact with a number of people throughout the day. There are plenty of resources for developers, as everyone uses Stack Overflow it means that SO can answer almost any question, and lots of problems you might want to solve have already been solved by one open source project or another. However, don’t just consume these resources – make accounts on SO/GitHub and start contributing!&lt;/p&gt;

&lt;h2 id=&quot;what-they-didnt-tell-you-about-testing&quot;&gt;What they didn’t tell you about Testing!&lt;/h2&gt;

&lt;blockquote&gt;
  &lt;p&gt;Do not assume anything. Ever.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The final lightning talk for the day was by Leonor Salazar &amp;amp; Brian Mason, covering testing and quality. The first point that Leo &amp;amp; Brian drilled home is that quality is subjective. Everyone has different ideas of quality, and you can’t do much meaningful testing without knowing what quality means for your project. Quality as defined by the users of the product is the most important. Everyone on a project should be thinking about quality, it’s not something that one person can ‘add in’ at the end. There is also a simple and compelling economic argument for having quality on everyone’s mind: it’s up to 1000x times more expensive to fix a bug in production than it is in analysis. Don’t let that cripple you or force you into a big-design-up-front type approach, but keep quality at the front of your mind.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Development is solving problems, testing is asking questions.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You need to ask yourself four questions:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Are we doing the right things?&lt;/li&gt;
  &lt;li&gt;Are we doing the things right?&lt;/li&gt;
  &lt;li&gt;Are we getting them done well?&lt;/li&gt;
  &lt;li&gt;Are we getting the benefits?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There is no point obsessing over whether you’re doing things right if you’re not doing the right things! Testers also have the opportunity to improve process, and take the product in new directions.&lt;/p&gt;

&lt;h2 id=&quot;user-testing-what-you-build--hands-on-session&quot;&gt;User Testing what you Build – Hands On Session&lt;/h2&gt;

&lt;p&gt;Carrying on with the theme of user first was Pete Chemsripong, with a hands on session where each team had to develop a ‘product’ that was then tested by a user. For example, a media remote control for a user with boxing gloves on or a lift control panel for someone carrying 15 bags of groceries. To design a good user experience, you need to ask why you’re building anything in the first place. You need to understand why people would use this product. Ultimately the answer to a question like ‘What makes Google better than Bing?’ is always that it offers a better user experience and satisfies the users needs. It doesn’t matter what you build or how you build it if people don’t enjoy using it. User testing also doesn’t have to be expensive. You can even grab a dev from another team who hasn’t touched your project. Chances are they’re going to find a lot of the same issues as a ‘real’ user of the software, allowing you to pick the low hanging fruit for minimal cost. Pete showed a video from a recent ThoughtWorks experiment, where an &lt;a href=&quot;http://www.thoughtworks.com/clients/woolworths&quot; title=&quot;Woolworths | ThoughtWorks&quot;&gt;in-store innovation lab at a Woolworths&lt;/a&gt; store produced loads of great feedback in a very short time. The other ThoughtWorkers present mentioned &lt;a href=&quot;http://www.joelonsoftware.com/articles/UsabilityTestingwithMorae.html&quot; title=&quot;Usability Testing with Morae by Joel Spolsky&quot;&gt;Usability Testing with Morae&lt;/a&gt; as a good read for more information about inexpensive usability testing.&lt;/p&gt;

&lt;h2 id=&quot;tdd--from-woe-to-go-in-10-minutes--hands-on-session&quot;&gt;TDD – from woe to go in 10 minutes – Hands On Session&lt;/h2&gt;

&lt;blockquote&gt;
  &lt;p&gt;As professional developers, the burden of proving a system works lies with us.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Steve Morris held the floor for the final session of the day, and did a great job showing everyone how simple test driven development can be. TDD provides the following benefits:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Shows the code does what you say it does&lt;/li&gt;
  &lt;li&gt;Improves quality by making code more testable&lt;/li&gt;
  &lt;li&gt;Allows you to figure out what to test only once – no more writing a monolithic class/function and then spending time working through what needs to be tested over and over&lt;/li&gt;
  &lt;li&gt;At any time, you can see what is broken and whether your code is shippable (as there is never code that isn’t covered by tests)&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
  &lt;p&gt;TDD is coding with intent – don’t code by accident.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The ‘test’ in TDD could just as easily be replaced by ‘expectation’, ‘behaviour’, ‘specification’ or ‘intent’. It’s as much about helping to define expected behaviour and a minimal specification as it is about testing actual code. It doesn’t matter if you’re a developer or not, TDD provides the same benefits to BAs, managers and QA testers. I couldn’t write this post without including the TDD mantra, lest Steve think we all learnt nothing at all from the talk. The TDD mantra is as follows&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Red – write a minimal failing test&lt;/li&gt;
  &lt;li&gt;Green – write the minimum amount of code to make the test pass&lt;/li&gt;
  &lt;li&gt;Refactor – incrementally refactor the code (both code under test &lt;strong&gt;and&lt;/strong&gt; the tests themselves – test code is first class code!)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Writing tests before code forces you to think about naming, architecture, APIs and design without considering implementation details. This helps with design and forces us to progress with intent, to avoid building unnecessary features. The refactor step encourages design improvements in incremental steps, rather than writing a bunch of code and then struggling through a ‘big bang’ refactor later in the project. Failing tests are not a failure of any kind, rather, they are statements of intent. The minimal failing test doesn’t even have to compile. A test that doesn’t compile signifies an intent to write the code to make it compile. In this way tests are documentation of future intent as well as progress to date. The hands on component of this talk included getting testing environments for C# and Node.js set up and writing our first code using TDD. Set-up for C# is as simple as installation of a testing framework like NUnit, which in a newer version of Visual Studio is as easy as running&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Install-Package Nunit
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;in the package manager console. The set up for Node.js was just as simple, with npm installed simply run&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;npm install karma
npm install phantomjs
npm install jasmine
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;from your favourite shell. In the talk, it was possible to get this environment set up and have our first test running in under ten minutes for each environment. There really isn’t any excuse for not giving TDD a try! Steve also pointed out that TDD (like most concepts in software development) &lt;a href=&quot;http://arialdomartini.wordpress.com/2012/07/20/you-wont-believe-how-old-tdd-is/&quot; title=&quot;You won’t believe how old TDD is&quot;&gt;isn’t as new as you might think&lt;/a&gt;.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;The second LevelUp EXP event in Brisbane was eye-opening, and I think the attendees learnt a lot to complement what is taught at university. If you attended/presented and I’ve omitted anything, please let me know and I’ll fix it up. My post about the first Brisbane LevelUp event is &lt;a href=&quot;/2013/10/levelup-exp-brisbane/&quot; title=&quot;ThoughtWorks LevelUp EXP Brisbane&quot;&gt;here&lt;/a&gt;, and more about ThoughtWorks LevelUp can be found on Twitter (&lt;a href=&quot;https://twitter.com/TW_LevelUp&quot;&gt;@TW_LevelUp&lt;/a&gt;) and &lt;a href=&quot;https://www.facebook.com/ThoughtworksLevelUp&quot;&gt;Facebook&lt;/a&gt;.&lt;/p&gt;

</content>
  </entry>
  
  <entry>
    <title>Working on Haskell code in vim</title>
    <link href="/2014/04/working-on-haskell-code-in-vim/"/>
    <updated>2014-04-17T00:00:00+00:00</updated>
    <id>/2014/04/working-on-haskell-code-in-vim/</id>
    <category term="software-tech" label="Software/Tech"></category>
    <content type="html">&lt;p&gt;I decided to get a fresh vim install properly set up for some Haskell development, and went down the road of using &lt;a href=&quot;https://github.com/bitc/hdevtools&quot; title=&quot;hdevtools on GitHub&quot;&gt;hdevtools&lt;/a&gt;, &lt;a href=&quot;https://github.com/bitc/vim-hdevtools&quot; title=&quot;vim-hdevtools on GitHub&quot;&gt;vim-hdevtools&lt;/a&gt; and &lt;a href=&quot;https://github.com/scrooloose/syntastic&quot; title=&quot;syntastic on GitHub&quot;&gt;Syntastic&lt;/a&gt;. Below are notes on some issues I encountered setting up vim-hdevtools.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;The instructions on the GitHub page for hdevtools &amp;amp; vim-hdevtools linked above are simple enough, but I ran into a couple of issues. I’m using the sandbox feature added in Cabal 1.18, and by default hdevtools doesn’t know to look for a .cabal-sandbox folder. So, when I tried to use any of the hdevtools commands, I received an error message similar to the following:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Error loading targets
(file):
Could not find module `(module)&apos;
Use -v to see a list of the files searched for.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This is an issue that a few people have run into, and I found a link to &lt;a href=&quot;http://lpaste.net/94999&quot; title=&quot;vim config for hdevtools and cabal sandboxes&quot;&gt;this solution&lt;/a&gt; in the archives of the &lt;a href=&quot;http://www.haskell.org/haskellwiki/IRC_channel&quot; title=&quot;View source for IRC channel - HaskellWiki&quot;&gt;#Haskell&lt;/a&gt; IRC channel.
Adding it to my .vimrc seems to have fixed this error, and I can now use all the hdevtool commands in vim. I’m still having issues with 
*.cabal files that specify default-extensions (vim-hdevtools doesn’t seem to pick these up).&lt;/p&gt;

&lt;p&gt;Also, if you get an error message similar to the following:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;E492: Not an editor command: ...
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;make sure that hdevtools is on your path and that you have plugin files for specific file types enabled by adding&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;filetype plugin on
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;to your .vimrc.&lt;/p&gt;

</content>
  </entry>
  
  <entry>
    <title>Installing self signed certificates on Android (Jelly Bean)</title>
    <link href="/2013/11/jelly-bean-self-signed-certificates/"/>
    <updated>2013-11-06T00:00:00+00:00</updated>
    <id>/2013/11/jelly-bean-self-signed-certificates/</id>
    <category term="software-tech" label="Software/Tech"></category>
    <content type="html">&lt;p&gt;I was pretty happy when I found out Android now supports installing self signed certificates, but had some trouble getting the certificate I use for administering this blog installed.&lt;/p&gt;

&lt;p&gt;So, a quick note for anyone who is attempting to install a self signed SSL certificate on Jelly Bean Android devices: &lt;strong&gt;you can only install a root CA certificate&lt;/strong&gt; (i.e. a certificate with “Subject Type=CA”).&lt;/p&gt;

&lt;p&gt;Trying to install a certificate for a single site (i.e. a certificate with “Subject Type=End Entity”) isn’t possible as far as I can tell. I don’t have any references for this, it’s just based from my experience, so let me know if you’ve experienced otherwise.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>Two-factor authentication and ‘trusted’ devices</title>
    <link href="/2013/10/two-factor-authentication-and-trusted-devices/"/>
    <updated>2013-10-30T00:00:00+00:00</updated>
    <id>/2013/10/two-factor-authentication-and-trusted-devices/</id>
    <category term="software-tech" label="Software/Tech"></category>
    <content type="html">&lt;p&gt;&lt;a href=&quot;https://web.archive.org/web/20191028203113/https://pando.com/2013/10/26/i-challenged-hackers-to-investigate-me-and-what-they-found-out-is-chilling/&quot; title=&quot;I challenged hackers to investigate me and what they found out is chilling - PandoDaily&quot;&gt;“I challenged hackers to investigate me and what they found out is chilling”&lt;/a&gt; is an interesting article – it’s the story of a couple who challenged a hacking team to pen-test their digital lives. To give some context to the following quote, their laptop has been compromised and user ID and password for their on-line banking account at Chase has been stolen by the ethical hacking team:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Chase.com uses a two-step verification system, which momentarily stymied SpiderLabs’ hackers. Every time she or I logs on from an IP address that Chase doesn’t recognize, it offers to send us an activation code via text to our mobile phones. But a search of Charlotte’s hard drive revealed Chase cookies, which the team copied and used to convince Chase that she was logging in from home.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You could argue that if your PC has been this thoroughly compromised then you have bigger problems, but it still points out how limited some two-factor authentication systems can be if you allow devices to be remembered/trusted.&lt;/p&gt;

</content>
  </entry>
  
  <entry>
    <title>ThoughtWorks LevelUp EXP Brisbane</title>
    <link href="/2013/10/levelup-exp-brisbane/"/>
    <updated>2013-10-29T00:00:00+00:00</updated>
    <id>/2013/10/levelup-exp-brisbane/</id>
    <category term="software-tech" label="Software/Tech"></category>
    <content type="html">&lt;p&gt;On Saturday I was lucky enough to attend &lt;a href=&quot;http://levelup.thoughtworks.com/brisbane/&quot; title=&quot;ThoughtWorks LevelUp EXP Brisbane&quot;&gt;ThoughtWorks LevelUp EXP&lt;/a&gt; at the ThoughtWorks Brisbane office.&lt;/p&gt;

&lt;p&gt;As well as plenty of opportunities to chat with the ThoughtWorkers (and Chad!) who kindly gave up their Saturday, there were six presentations throughout the day:&lt;/p&gt;

&lt;h2 id=&quot;opening-keynote-design-thinking&quot;&gt;Opening Keynote: Design Thinking&lt;/h2&gt;

&lt;p&gt;Ben Melbourne (&lt;a href=&quot;https://twitter.com/benmelb&quot; title=&quot;Ben Melbourne (benmelb) on Twitter&quot;&gt;@benmelb&lt;/a&gt;) set out to teach us about design thinking, and how it’s important for any project. The main points that I took away from his talk were:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Visual design is only a small part of design.&lt;/li&gt;
  &lt;li&gt;UX research is not strictly academic or scientific – iterate quickly and rely on feedback to get the best results in the shortest time.&lt;/li&gt;
  &lt;li&gt;Embrace constraints to get the most out of a situation. Design is harder when you have a green field to work in – if you have constraints, don’t fight against them, use them for inspiration.&lt;/li&gt;
  &lt;li&gt;Everyone is a designer – if you’ve ever been on a project without a designer, it was you.&lt;/li&gt;
  &lt;li&gt;Always ask if the current approach is the best use of business capability.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;functional-programming-for-fun-and-profit&quot;&gt;Functional Programming for Fun and Profit&lt;/h2&gt;

&lt;p&gt;Next up was James Ottoway (&lt;a href=&quot;https://twitter.com/jms_&quot; title=&quot;James Ottaway (jms_) on Twitter&quot;&gt;@jms_&lt;/a&gt;) with a good intro to functional programming. He started out by explaining declarative languages and reactive programming, as well as DSLs and closures and how they can be used to cut complexity.&lt;/p&gt;

&lt;p&gt;Declarative languages focus on expressing the logic of a computation, not how to carry out that computation. Regular expressions, Chef/Puppet configuration files, and SQL were all used as examples of declarative languages. In James’s words:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;We’re expressing what, not how. And that’s a good thing.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Expressing what you want to do (and not how it must be done) frees up the compiler/interpreter to make decisions about implementation at runtime, and eases the burden on you as a programmer.&lt;/p&gt;

&lt;p&gt;When talking about reactive programming, James used Excel (everyone’s favourite spreadsheet application) as an example of a reactive program. This is a really simple analogy which I think helped everyone grasp the idea of reactive programming quickly. He also pointed out that the windows GitHub client is built using reactive programming (using &lt;a href=&quot;http://www.reactiveui.net/&quot; title=&quot;ReactiveUI&quot;&gt;ReactiveUI&lt;/a&gt; from what I can see).&lt;/p&gt;

&lt;p&gt;As someone who’s trying to learn Haskell at the moment, this section about of this talk about closures was interesting to me. Closures aren’t something that I was seeing in Haskell, perhaps because I’m still battling with unfamiliar syntax (turns out they’re pretty much everywhere). A closure is just a function together with a referencing environment, and they’re pretty essential for functional programming.&lt;/p&gt;

&lt;h2 id=&quot;business-analysis&quot;&gt;Business Analysis&lt;/h2&gt;

&lt;p&gt;After lunch we heard about the life of a BA from Cathie Hagen (&lt;a href=&quot;https://twitter.com/catherist&quot; title=&quot;Cathie Hagen (catherist) on Twitter&quot;&gt;@catherist&lt;/a&gt;) and Jiangmei Kang. BAs are an integral part of every stage of a project, and use their place as a bridge between the client and the developers to ensure that value is delivered to the client. The following is a photo I took of the board used to explain the many aspects of work as a BA, I think it says more than I can:&lt;/p&gt;

&lt;figure&gt;
    &lt;a href=&quot;/public/images/2013/10/TW-LevelUp-Business-Analysis.jpg&quot;&gt;
        &lt;img class=&quot;lozad&quot; data-src=&quot;/public/images/2013/10/TW-LevelUp-Business-Analysis.jpg&quot; alt=&quot;TW LevelUp - Business Analysis&quot; /&gt;
    &lt;/a&gt;
    
    &lt;figcaption&gt;
    (Sorry about the poor quality – the projector turned on for the next talk just as I was taking this picture)
    &lt;/figcaption&gt;
    
&lt;/figure&gt;

&lt;h2 id=&quot;user-testing&quot;&gt;User Testing&lt;/h2&gt;

&lt;blockquote&gt;
  &lt;p&gt;Why build something that people don’t want to use? It’s 2013, doing that is a waste of humanities potential.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Pete Chemsripong gave a great talk about the importance of user testing. Speed is important for user testing and ideally
should be a daily thing. Every feature that you’re working on in a project should be validated by a user (this agrees
with what Ben said in the design talk).&lt;br /&gt;&lt;/p&gt;

&lt;h2 id=&quot;helping-you-get-your-first-job&quot;&gt;Helping you get your first job&lt;/h2&gt;

&lt;p&gt;The last presentation before the keynote was by Jean D’amore (&lt;a href=&quot;https://twitter.com/jeandamore&quot; title=&quot;Jean D&apos;amore (jeandamore) on Twitter&quot;&gt;@jeandamore&lt;/a&gt;) with an entertaining talk on how to land your first job in IT. The talk introduced job hunting as a game where you can’t control everything, but what you can control can make all the difference. He split the journey into seven steps, each accompanied by a great movie reference &amp;amp; quote. Hopefully the slides will be made available as I didn’t get everything down, but what follows is my summary:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Yourself (The Last Samurai)
    &lt;ul&gt;
      &lt;li&gt;Improve the environment by working on yourself.&lt;/li&gt;
      &lt;li&gt;Do: know your boundaries, be versatile, stretch yourself, maintain balance, listen, commit to projects, be willing to sacrifice, learn/do new things&lt;/li&gt;
      &lt;li&gt;Don’t: underestimate yourself, thing you’re alone, deny the challenge, limit the horizon&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;The Search (An Unexpected Journey)
    &lt;ul&gt;
      &lt;li&gt;The search will change you&lt;/li&gt;
      &lt;li&gt;Do: know what you seek, choose a domain, know the employer, ask about graduate programs/training, keep your LinkedIn (and internet presence in general) up to date, favour simple job ads (i.e. not ads that list every skill under then sun – you often need to be a specialist before you can generalise)&lt;/li&gt;
      &lt;li&gt;Don’t: dismiss too quickly, use recruitment agencies, work on projects you don’t agree with (everything you do has an impact and will impact you), waste too much time searching on-line (do spend more time talking to people)&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Your CV (The Colour of Money)
    &lt;ul&gt;
      &lt;li&gt;Do: PDF it!, make it unique, know what’s on it, web design it (use web design principles – e.g. readability, don’t cram everything in), make it one page, get friends to read it, start with skills over education&lt;/li&gt;
      &lt;li&gt;Don’t: lie/exaggerate, rush it, use ‘bullshit bingo’ words (except in a few cases where it’s in the ad – in this case, always explain and give examples)&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Applying (Close Encounters of the Third Kind)
    &lt;ul&gt;
      &lt;li&gt;You need to understand and be understood&lt;/li&gt;
      &lt;li&gt;Do: strike with precision, add a cover letter, apply to people (not computers), customise your CV, wait, follow-up, be organised&lt;/li&gt;
      &lt;li&gt;Don’t: bulk apply (do apply to at most 5 organisations at once – it becomes too hard to keep track of what you’re doing otherwise)&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Interviews (Gattaca)
    &lt;ul&gt;
      &lt;li&gt;Little things are often the most important. For example, be good to everyone at the company.&lt;/li&gt;
      &lt;li&gt;Do: look clean and tidy, research the company &amp;amp; their interview process, arrive early, know who you are and why you’re there, know what you’ll be asked, listen, ask relevant questions, be humble and curious, know your stuff (especially your résumé)&lt;/li&gt;
      &lt;li&gt;Don’t: be afraid to ask for clarification, lower your guard until you’re clear of the building (i.e. do treat every moment you’re in/near their offices as part of the interview), ask how you did at the interview, ask about time/money when you’re after your first job, leave your phone on, have alcohol (even if offered), go if you’re sick (you need to be 100%, and the interviewers will understand)&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Hearing Yes/No (The Hurricane)
    &lt;ul&gt;
      &lt;li&gt;Don’t be afraid of failing and keep bouncing back&lt;/li&gt;
      &lt;li&gt;Do: take your chance to explore/re-evaluate, take risks, trust your instinct, understand that this is one step is a career&lt;/li&gt;
      &lt;li&gt;Don’t: burn bridges, take it personally, rush to accept, say you’re waiting on another offer&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;First Day (City Hall)
    &lt;ul&gt;
      &lt;li&gt;Make a difference and work where you’re satisfied. Focus on employers that give you the upper parts of &lt;a href=&quot;http://en.wikipedia.org/wiki/Maslow&apos;s_hierarchy_of_needs&quot; title=&quot;Maslow&apos;s hierarchy of needs&quot;&gt;Maslow’s hierarchy of needs&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;Do: learn names, go to social events, pair, do what you’re told, be helpful, learn the ropes step by step, leave if you don’t like it after a month of so&lt;/li&gt;
      &lt;li&gt;Don’t: panic, try to change things quickly, cold shoulder anyone&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&quot;closing-keynote-who-are-you-where-are-you-going-and-how-will-you-get-there&quot;&gt;Closing Keynote: Who are you, where are you going, and how will you get there?&lt;/h2&gt;

&lt;p&gt;The closing keynote by Chad Renando (&lt;a href=&quot;https://twitter.com/ChadRenando&quot; title=&quot;Chad Renando (ChadRenando) on Twitter&quot;&gt;@ChadRenando&lt;/a&gt;) followed on nicely from the presentation from Jean, and was really a step back, focussing on making the most of who you are, being clear about where you are going, and being intentional about how you can get there.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Every man invents a story for himself – which he often, and with great cost to himself – takes to be his life.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Chad used this quote from Max Frisch as a way of explaining that you create your own story, but you should never think that it can’t be changed or even completely rewritten.&lt;/p&gt;

&lt;p&gt;You need to understand yourself to understand how you will work with others – are you more practical or creative? Do you approach things in an analytical way or listen to your beliefs? Are you structured or flexible? Learn what your &lt;a href=&quot;https://en.wikipedia.org/wiki/Values_in_Action_Inventory_of_Strengths&quot; title=&quot;Values in Action Inventory of Strengths - Wikipedia&quot;&gt;signature strengths&lt;/a&gt; are and use those to create a mission statement, as your strengths are the things that make you feel alive. At the same time, look out for the strengths that you rank poorly in.&lt;/p&gt;

&lt;p&gt;Create goals (what is your 9-day plan? your 120-day plan?) that align with your strengths, but don’t think that these goals are set in stone. Use goals as a way to direct yourself, not as measures of success. This allows you to iterate on your goals and improve them as you learn more about yourself.&lt;/p&gt;

&lt;p&gt;Chad finished the main part of his talk with his axioms from life in a digital studio:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Ask questions&lt;/li&gt;
  &lt;li&gt;Focus on resolving process conflict, not relationship conflict&lt;/li&gt;
  &lt;li&gt;There are things that are understandable, but not acceptable – don’t get the two confused&lt;/li&gt;
  &lt;li&gt;Everyone is generally doing the best they can&lt;/li&gt;
  &lt;li&gt;There is no fault, only cause&lt;/li&gt;
  &lt;li&gt;Every conversation we have is with ourselves, and sometimes they involve others&lt;/li&gt;
  &lt;li&gt;If you want to lead others, lead yourself&lt;/li&gt;
&lt;/ul&gt;

&lt;hr /&gt;

&lt;p&gt;The day covered a range of topics and gave me a lot to think about. One point that appeared a couple of times throughout the day (and which Chad reiterated at the end of his keynote) is how important it is to get involved with your community. It allows you to grow your network, get references and learn. I can’t agree more, I have learnt so much and met lots of interesting people by attending the &lt;a href=&quot;http://yowconference.com.au&quot; title=&quot;YOW! | Australian Developer Conference&quot;&gt;YOW! conference&lt;/a&gt;, &lt;a href=&quot;http://yowaustralia.com.au/general/yownights.html&quot; title=&quot;YOW! Nights&quot;&gt;YOW! nights&lt;/a&gt;, and the &lt;a href=&quot;http://www.meetup.com/Brisbane-Functional-Programming-Group/&quot; title=&quot;BFPG&quot;&gt;BFPG&lt;/a&gt; &amp;amp; &lt;a href=&quot;http://www.meetup.com/Brisbane-GPU-Users/&quot; title=&quot;Brisbane GPU Users (Brisbane ) - Meetup&quot;&gt;Brisbane GPU Users&lt;/a&gt; meetups (there are tons of similar user groups in Brisbane – I guarantee you won’t regret attending one of their meetups!). Another way to get involved in the broader community while sharpening your skills is volunteering – there are plenty of non-profits that could use help with IT. Or, if you have an idea/are working on a start-up, &lt;a href=&quot;http://www.rivercitylabs.net/&quot; title=&quot;River City Labs&quot;&gt;River City Labs&lt;/a&gt; is building an amazing community of like-minded people.&lt;/p&gt;

&lt;p&gt;Thanks again to ThoughtWorks for running this mini-conference – you’ve done a great job of inspiring this IT undergrad! More about ThoughtWorks LevelUp can be found on Twitter (&lt;a href=&quot;https://twitter.com/TW_LevelUp&quot; title=&quot;LevelUp on Twitter&quot;&gt;@TW_LevelUp&lt;/a&gt;) and &lt;a href=&quot;https://www.facebook.com/ThoughtworksLevelUp&quot; title=&quot;ThoughtWorks Level Up&quot;&gt;Facebook&lt;/a&gt;.&lt;/p&gt;

</content>
  </entry>
  
  <entry>
    <title>Kevlin Henney on code comments</title>
    <link href="/2013/10/kevlin-henney-a-common-fallacy/"/>
    <updated>2013-10-16T00:00:00+00:00</updated>
    <id>/2013/10/kevlin-henney-a-common-fallacy/</id>
    <category term="software-tech" label="Software/Tech"></category>
    <content type="html">&lt;blockquote&gt;
  &lt;p&gt;A common fallacy is to assume authors of incomprehensible code will somehow be able to express themselves lucidly and clearly in comments.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href=&quot;http://kevlin.tel/&quot; title=&quot;kevlin.tel&quot;&gt;Kevlin Henney&lt;/a&gt; (original tweet &lt;a href=&quot;https://twitter.com/KevlinHenney/status/381021802941906944&quot; title=&quot;Kevlin Henney - A common fallacy is to assume ...&quot;&gt;here&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;There are some interesting responses, pointing out that comments are great for references and in-line diagrams, and sometimes necessary for code that has been restructured to improve performance (although creating difficult to read code solely for performance reasons is a separate issue).&lt;/p&gt;

</content>
  </entry>
  
  <entry>
    <title>John Carmack on type systems</title>
    <link href="/2013/10/john-carmack-on-type-systems/"/>
    <updated>2013-10-04T00:00:00+00:00</updated>
    <id>/2013/10/john-carmack-on-type-systems/</id>
    <category term="software-tech" label="Software/Tech"></category>
    <content type="html">&lt;blockquote&gt;
  &lt;p&gt;It’s just amazing how many mistakes [are made] and how bad programmers can be. Everything that is syntactically legal, that the compiler will accept, will eventually wind up in your code base. And that is why I think static typing is so valuable.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/John_Carmack&quot; title=&quot;John D. Carmack&quot;&gt;John Carmack&lt;/a&gt; (full talk &lt;a href=&quot;http://youtu.be/1PhArSujR_A?t=15m47s&quot; title=&quot;John Carmack&apos;s keynote at Quakecon 2013 (Part 4)&quot;&gt;here&lt;/a&gt; – note this link jumps to this quote – part one of the keynote is &lt;a href=&quot;http://youtu.be/eNWAcEu1jpU?t=15m12s&quot; title=&quot;John Carmack&apos;s keynote at Quakecon 2013 (Part 1)&quot;&gt;here&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;Pretty much sums up how I feel about the static v. dynamic debate for anything other than very short-lived prototypes.&lt;/p&gt;

</content>
  </entry>
  
  <entry>
    <title>Don’t fear the Monad</title>
    <link href="/2013/10/dont-fear-the-monad/"/>
    <updated>2013-10-03T00:00:00+00:00</updated>
    <id>/2013/10/dont-fear-the-monad/</id>
    <category term="software-tech" label="Software/Tech"></category>
    <content type="html">&lt;p&gt;I recently watched Brian Beckman’s &lt;a href=&quot;http://channel9.msdn.com/shows/Going+Deep/Brian-Beckman-Dont-fear-the-Monads/&quot;&gt;Don’t fear the monad&lt;/a&gt; talk (YouTube version &lt;a href=&quot;http://www.youtube.com/watch?v=ZhuHCtR3xq8&quot;&gt;here&lt;/a&gt;) and thought it was a really good explanation of functions, monoids &amp;amp; monads and why they’re a useful way to master complexity.&lt;/p&gt;

&lt;p&gt;I recommend it to anyone who’s starting to look at functional programming. Here are some of the key points I took away from the talk:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Functions are data
    &lt;ul&gt;
      &lt;li&gt;A function takes an argument(/s) and returns a value, and always returns the same result for the same inputs&lt;/li&gt;
      &lt;li&gt;Think of a function as a table lookup – the table is the data&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Functional programming is a style that can be used in almost any language
    &lt;ul&gt;
      &lt;li&gt;But some languages make it easier than others&lt;/li&gt;
      &lt;li&gt;First class functions (or at least lamdbas) are a must have&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Complexity is killing software developers – we need to control it
    &lt;ul&gt;
      &lt;li&gt;The best way to control complexity is to put functions into groups where things are disciplined, and where they can be composed in arbitrary ways&lt;/li&gt;
      &lt;li&gt;Build complexity out of simplicity by composing things&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;A monad adds some data to a value, and the implementation of the bind operator defines how that data interacts&lt;/li&gt;
  &lt;li&gt;If you want to add a feature, you shouldn’t even have to know what you’re going to interact with
    &lt;ul&gt;
      &lt;li&gt;Using monads means the interaction is already built into the structure&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;You don’t need to know what a monad does
    &lt;ul&gt;
      &lt;li&gt;So long as it follows the rules, it can have arbitrary side effects&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Another interesting part was Brian’s reasoning about why functional programming is a ‘hard sell’:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Immediately upon the foundation of computing, the world split into two camps – the bottom up camp and the top down camp.&lt;/p&gt;

  &lt;p&gt;The bottom up camp is typified by Turing machines – “let’s start with the hardware and add abstraction as we need it to get close to the mathematics, but never at the expense of performance”. That gave rise to FORTRAN, C, C++, Pascal, Java, C# … all of those languages are in that tradition.&lt;/p&gt;

  &lt;p&gt;The top down crowd says “let’s start with the mathematics and subtract abstractions to get down to the machine, sometimes at the expense of performance”. That tradition starts with lambda calculus … and only subtracts abstraction when it is convenient to do so. That’s the tradition that gave rise to ALGOL, Lisp, Smalltalk, ML, Haskell and all these languages that have reputations of being slow.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;As most programmers are familiar with the bottom up way of doing things and the two approaches come from very different origins, it can be hard to convince a bottom up programmer of the benefits of the ‘top down’ approach. It can be even harder to pick up functional programming once you’ve resigned to giving it a try.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;[The top-down crowd] are saying “don’t go to the hardware so early, you’ll lock yourself into irreversible design choices”. [The bottom-up crowd] are saying “don’t give me all this math, I can’t handle garbage collection, or function calls or whatever it is that’s getting in the way of my performance, I need every ounce of performance the hardware can give me. And I’m willing to write software into the wee hours of the morning to get it”.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The last sentence here is what stands out to me – as software gets more complex, it seems that bottom up programming is going to require more and more time working in the wee hours of the morning to get the desired performance and functionality.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>Maybe Haskell …</title>
    <link href="/2013/09/maybe-haskell/"/>
    <updated>2013-09-14T00:00:00+00:00</updated>
    <id>/2013/09/maybe-haskell/</id>
    <category term="software-tech" label="Software/Tech"></category>
    <content type="html">&lt;p&gt;After reading &lt;a href=&quot;http://learnyouahaskell.com/&quot; title=&quot;Learn You a Haskell&quot;&gt;Learn You a Haskell&lt;/a&gt; on and off over the past fortnight and watching a couple of Erik Meijer’s &lt;a href=&quot;http://channel9.msdn.com/Series/C9-Lectures-Erik-Meijer-Functional-Programming-Fundamentals&quot; title=&quot;Erik Meijer - Functional Programming Fundamentals&quot;&gt;Functional Programming Fundamentals&lt;/a&gt;,
I finally got around to installing the Haskell platform and firing up GHCi.&lt;/p&gt;

&lt;p&gt;After a couple of hours of implementing the simple functions scattered throughout LYAH, I was up to &lt;a href=&quot;http://learnyouahaskell.com/recursion#quick-sort&quot; title=&quot;Learn You a Haskell - Recursion&quot;&gt;implementing quick sort&lt;/a&gt;.
Given the number of times I’ve seen this example, I’m not going to reproduce it here, but it’s pretty amazing &lt;sup&gt;&lt;a href=&quot;#f1&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;

&lt;p&gt;One of the main things I noticed was that after two hours of writing code in a language I’d never used, I’d produced
&lt;strong&gt;zero run time errors&lt;/strong&gt;. There were plenty of compile errors, but that’s to be expected – especially given I was
using an editor that was inserting tabs in a language with significant white space (which, by the way, makes for fun
times when unfamiliar with Haskell compiler errors). I know what kind of error I would prefer to deal with.&lt;/p&gt;

&lt;p&gt;So far I’m liking Haskell, and I think it’s a huge shame that there is only one functional programming course at
my university (&lt;a href=&quot;http://www.uq.edu.au/study/course.html?course_code=COMP1024&quot; title=&quot;Conceptual Foundations of Computer Programming (COMP1024)&quot;&gt;COMP1024&lt;/a&gt;), which isn’t available to most dual degree students.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Edit&lt;/strong&gt;: COMP1024 hasn’t been offered since 2010.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;&lt;a name=&quot;f1&quot;&gt;&lt;/a&gt;1. I know this isn’t ‘true’, in-place, high performance quick sort, but in how many other languages can you write a readable, generic sorting algorithm in 6 lines of code?&lt;/p&gt;

</content>
  </entry>
  
  <entry>
    <title>VirtualBox + Dell laptop VT-x issues</title>
    <link href="/2013/08/virtualbox-dell-laptop-vt-x-issues/"/>
    <updated>2013-08-15T00:00:00+00:00</updated>
    <id>/2013/08/virtualbox-dell-laptop-vt-x-issues/</id>
    <category term="software-tech" label="Software/Tech"></category>
    <content type="html">&lt;p&gt;I recently had to use a VM for a uni project, and needed to have access on my laptop &amp;amp; desktop. I haven’t used a VM on my laptop in a
while, but didn’t expect to see the following error message from VirtualBox (4.2.16):&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;VT-x features locked or unavailable in MSR.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I’ve used x64 hosts before with no problems, but I guess my BIOS settings were reverted for some reason (using a Dell laptop
with Intel PM45 chipset).&lt;/p&gt;

&lt;p&gt;So thinking to myself that this should be an easy fix, I rebooted, enabled VT-x and restarted, but I received the same error
message. No amount of changing BIOS/VirtualBox settings, rebooting or otherwise reconfiguring would make this message go away.&lt;/p&gt;

&lt;p&gt;I eventually read that it’s sometimes &lt;strong&gt;necessary to power down and physically disconnect the machine from power to properly
enable VT-x&lt;/strong&gt;. This solved my problem – I decided to make a note of it here to hopefully help someone else in the same situation.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>Ubuntu 12.10 – Transmission fails to connect to HTTPS trackers</title>
    <link href="/2013/01/ubuntu-12-10-transmission-fails-to-connect-to-https-trackers/"/>
    <updated>2013-01-10T00:00:00+00:00</updated>
    <id>/2013/01/ubuntu-12-10-transmission-fails-to-connect-to-https-trackers/</id>
    <category term="software-tech" label="Software/Tech"></category>
    <content type="html">&lt;p&gt;&lt;a href=&quot;http://www.transmissionbt.com/&quot; title=&quot;Transmission&quot;&gt;Transmission&lt;/a&gt;, the BitTorrent client installed by default in Ubuntu seems to have an issue with connecting to trackers using HTTPS at the moment.&lt;/p&gt;

&lt;p&gt;After Transmission failed to connect to a tracker using HTTPS, I went searching and found this &lt;a href=&quot;https://bugs.launchpad.net/ubuntu/+source/gnutls26/+bug/937537&quot; title=&quot;libgnutls26 2.12.14 breaks SSL tracker support in Transmission&quot;&gt;bug report&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The steps there are pretty simple and worked well for me:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Close Transmission&lt;/li&gt;
  &lt;li&gt;Download the .deb for updated libgnutls26 from &lt;a href=&quot;http://packages.debian.org/wheezy/libgnutls26&quot;&gt;here&lt;/a&gt; (bottom of page – choose your architecture then mirror)&lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Install using&lt;/p&gt;

    &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt; dpkg -i (package name).deb
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;Restart Transmission&lt;/li&gt;
&lt;/ol&gt;

&lt;hr /&gt;

&lt;p&gt;UPDATE: It looks like this is now fixed, so running&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;sudo apt-get update
sudo apt-get upgrade
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;should get it working again for you.&lt;/p&gt;

</content>
  </entry>
  

</feed>
