2020-11-04T15:41:58Zhttps://blog.ldjb.ukLeon Byforda software developer from LondonIf you know GCSE Maths, you know functional programming!2018-07-30T00:00:00Z2018-07-30T00:00:00Zhttps://blog.ldjb.uk/functional-programming<p>It took me an unbelievably long time to grasp functional programming. In the lectures I took, it was described in terms of lambda calculus with lots of weird mathematical symbols that didn’t make sense to me.</p>
<p>However, little did I know that I had already learnt functional programming back in GCSE Maths, without even knowing it!</p>
<!-- more -->
<p>On the BBC Bitesize website, there is <a href="https://www.bbc.com/education/guides/z36vcj6/revision/6">information on using algebraic formulae with function notation</a> <sup id="fnref:0" role="doc-noteref"><a href="#fn:0" class="footnote">1</a></sup>.</p>
<p>As you can see, you can define a formula like:</p>
<blockquote>
<p>f(x) = x + 1</p>
</blockquote>
<p>This lets you substitute x with any number. For example, x=3:</p>
<blockquote>
<p>f(3) = 3 + 1 = 4</p>
</blockquote>
<p>Actually, this works exactly the same way when doing functional programming. For example, I can create a function in Python with the same functionality, which we invoke like so:</p>
<div class="language-py console highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="o">></span> <span class="n">f</span><span class="p">(</span><span class="mi">3</span><span class="p">)</span>
<span class="mi">4</span>
<span class="o">></span> <span class="n">f</span><span class="p">(</span><span class="mi">5</span><span class="p">)</span>
<span class="mi">6</span>
<span class="o">></span> <span class="n">f</span><span class="p">(</span><span class="o">-</span><span class="mi">2</span><span class="p">)</span>
<span class="o">-</span><span class="mi">1</span>
</code></pre></div></div>
<p>Defining this function is different from how we do it in maths, but it’s relatively intuitive:</p>
<div class="language-py highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">f</span><span class="p">(</span><span class="n">x</span><span class="p">):</span>
<span class="k">return</span> <span class="n">x</span> <span class="o">+</span> <span class="mi">1</span>
</code></pre></div></div>
<p>Isn’t this like just any other Python function? Why, yes it is. But the key thing is that the functions in functional programming have no side-effects. We take the parameters, transform them in some way, then return the result, without modifying any external variable. As such, whenever we call the function with the same arguments, we should expect to always receive the same result.</p>
<p>So, how do we do this in Lisp/Scheme/Racket? It’s actually quite similar. But note that these languages use prefix notation – not infix – so there is a different syntax for calling functions.</p>
<p>Instead of <code class="language-plaintext highlighter-rouge">f(x)</code>, we write <code class="language-plaintext highlighter-rouge">(f x)</code>. Really, all we’ve done is brought the <code class="language-plaintext highlighter-rouge">f</code> inside the brackets, and added a space to separate it from the <code class="language-plaintext highlighter-rouge">x</code>. So, to define the same function as before:</p>
<div class="language-racket highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="k">define</span> <span class="p">(</span><span class="nf">f</span> <span class="nv">x</span><span class="p">)</span>
<span class="p">(</span><span class="nb">+</span> <span class="nv">x</span> <span class="mi">1</span><span class="p">))</span>
</code></pre></div></div>
<p>You’ll notice that <code class="language-plaintext highlighter-rouge">+</code> is also a function that accepts multiple arguments.</p>
<p>So now we can call the function like so:</p>
<div class="language-racket console highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">></span> <span class="p">(</span><span class="nf">f</span> <span class="mi">3</span><span class="p">)</span>
<span class="mi">4</span>
<span class="nv">></span> <span class="p">(</span><span class="nf">f</span> <span class="mi">5</span><span class="p">)</span>
<span class="mi">6</span>
<span class="nv">></span> <span class="p">(</span><span class="nf">f</span> <span class="mi">-2</span><span class="p">)</span>
<span class="mi">-1</span>
</code></pre></div></div>
<p>And that’s functional programming in a nutshell! That wasn’t so bad, was it? Now, let’s solve some of the problems given on the BBC Bitesize page using Racket:</p>
<blockquote>
<p>f(x) = 3x + 2 and g(x) = x<sup>2</sup> - 1<br />
Find f(-2) and g(3)</p>
</blockquote>
<div class="language-racket highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="k">define</span> <span class="p">(</span><span class="nf">f</span> <span class="nv">x</span><span class="p">)</span>
<span class="p">(</span><span class="nb">+</span> <span class="p">(</span><span class="nb">*</span> <span class="mi">3</span> <span class="nv">x</span><span class="p">)</span> <span class="mi">2</span><span class="p">))</span>
<span class="p">(</span><span class="k">define</span> <span class="p">(</span><span class="nf">g</span> <span class="nv">x</span><span class="p">)</span>
<span class="p">(</span><span class="nb">-</span> <span class="p">(</span><span class="nb">expt</span> <span class="nv">x</span> <span class="mi">2</span><span class="p">)</span> <span class="mi">1</span><span class="p">))</span>
</code></pre></div></div>
<div class="language-racket console highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">></span> <span class="p">(</span><span class="nf">f</span> <span class="mi">-2</span><span class="p">)</span>
<span class="mi">-4</span>
<span class="nv">></span> <span class="p">(</span><span class="nf">g</span> <span class="mi">3</span><span class="p">)</span>
<span class="mi">8</span>
</code></pre></div></div>
<blockquote>
<p>f(x) = 2x + 3 and g(x) = x<sup>2</sup><br />
Find fg(4), gf(4) and ff(4)</p>
</blockquote>
<div class="language-racket highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="k">define</span> <span class="p">(</span><span class="nf">f</span> <span class="nv">x</span><span class="p">)</span>
<span class="p">(</span><span class="nb">+</span> <span class="p">(</span><span class="nb">*</span> <span class="mi">2</span> <span class="nv">x</span><span class="p">)</span> <span class="mi">3</span><span class="p">))</span>
<span class="p">(</span><span class="k">define</span> <span class="p">(</span><span class="nf">g</span> <span class="nv">x</span><span class="p">)</span>
<span class="p">(</span><span class="nb">expt</span> <span class="nv">x</span> <span class="mi">2</span><span class="p">))</span>
</code></pre></div></div>
<div class="language-racket console highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">></span> <span class="p">(</span><span class="nf">f</span> <span class="p">(</span><span class="nf">g</span> <span class="mi">4</span><span class="p">))</span>
<span class="mi">35</span>
<span class="nv">></span> <span class="p">(</span><span class="nf">g</span> <span class="p">(</span><span class="nf">f</span> <span class="mi">4</span><span class="p">))</span>
<span class="mi">121</span>
<span class="nv">></span> <span class="p">(</span><span class="nf">f</span> <span class="p">(</span><span class="nf">f</span> <span class="mi">4</span><span class="p">))</span>
<span class="mi">25</span>
</code></pre></div></div>
<p>Piece of cake. :-)</p>
<div class="footnotes" role="doc-endnotes">
<ol>
<li id="fn:0" role="doc-endnote">
<p>The linked page is for the Edexcel exam board, but there are similar pages for <a href="https://www.bbc.com/education/guides/zqpfcj6/revision/6">AQA</a> and <a href="https://www.bbc.com/education/guides/z8cqpbk/revision/6">Eduqas</a>. <a href="#fnref:0" class="reversefootnote" role="doc-backlink">↩</a></p>
</li>
</ol>
</div>
Leon Byford<p>It took me an unbelievably long time to grasp functional programming. In the lectures I took, it was described in terms of lambda calculus with lots of weird mathematical symbols that didn’t make sense to me.</p>
<p>However, little did I know that I had already learnt functional programming back in GCSE Maths, without even knowing it!</p>
Cons pairs and lists in ECMAScript using Church encoding2018-07-15T00:00:00Z2018-07-15T00:00:00Zhttps://blog.ldjb.uk/cons-pairs-ecmascript<p>One of the really cool things covered by Abelson and Sussman’s classic series of lectures, <a href="https://ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-001-structure-and-interpretation-of-computer-programs-spring-2005/"><em>Structure and Interpretation of Computer Programs</em> (SICP)</a>, was how fundamental programming constructs could be implemented almost from nothing. This, of course, culminated in the implementation of Scheme within Scheme itself, but it’s interesting to look at some of the smaller building blocks.</p>
<!-- more -->
<p>A lot of this relies on <a href="https://en.wikipedia.org/wiki/Church_encoding">Church encoding</a>, with which we can implement one of the most fundamental data structures – the cons pair:</p>
<blockquote>
<p>cons = λx . λy . λz . z x y<br />
car = λz . z (λx . λy . x)<br />
cdr = λz . z (λx . λy . y)</p>
</blockquote>
<p>SICP explains how to implement this in Scheme, but ECMAScript (a.k.a JavaScript) is a Lisp (okay, this meme is getting old now), so it’s a straightforward translation:</p>
<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">const</span> <span class="nx">cons</span> <span class="o">=</span> <span class="p">(</span><span class="nx">x</span><span class="p">,</span> <span class="nx">y</span><span class="p">)</span> <span class="o">=></span> <span class="nx">z</span> <span class="o">=></span> <span class="nx">z</span><span class="p">(</span><span class="nx">x</span><span class="p">,</span> <span class="nx">y</span><span class="p">);</span>
<span class="kd">const</span> <span class="nx">car</span> <span class="o">=</span> <span class="nx">z</span> <span class="o">=></span> <span class="nx">z</span><span class="p">((</span><span class="nx">x</span><span class="p">,</span> <span class="nx">y</span><span class="p">)</span> <span class="o">=></span> <span class="nx">x</span><span class="p">);</span>
<span class="kd">const</span> <span class="nx">cdr</span> <span class="o">=</span> <span class="nx">z</span> <span class="o">=></span> <span class="nx">z</span><span class="p">((</span><span class="nx">x</span><span class="p">,</span> <span class="nx">y</span><span class="p">)</span> <span class="o">=></span> <span class="nx">y</span><span class="p">);</span>
</code></pre></div></div>
<p>Cool, now we can do fun stuff like:</p>
<div class="language-js console highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="o">></span> <span class="nx">car</span><span class="p">(</span><span class="nx">cons</span><span class="p">(</span><span class="dl">"</span><span class="s2">hello</span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2">world</span><span class="dl">"</span><span class="p">));</span>
<span class="dl">"</span><span class="s2">hello</span><span class="dl">"</span>
<span class="o">></span> <span class="nx">cdr</span><span class="p">(</span><span class="nx">cons</span><span class="p">(</span><span class="dl">"</span><span class="s2">hello</span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2">world</span><span class="dl">"</span><span class="p">));</span>
<span class="dl">"</span><span class="s2">world</span><span class="dl">"</span>
</code></pre></div></div>
<p>Now, how about lists? Well, we need to implement booleans first:</p>
<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">const</span> <span class="nx">myTrue</span> <span class="o">=</span> <span class="p">(</span><span class="nx">x</span><span class="p">,</span> <span class="nx">y</span><span class="p">)</span> <span class="o">=></span> <span class="nx">x</span><span class="p">;</span>
<span class="kd">const</span> <span class="nx">myFalse</span> <span class="o">=</span> <span class="p">(</span><span class="nx">x</span><span class="p">,</span> <span class="nx">y</span><span class="p">)</span> <span class="o">=></span> <span class="nx">y</span><span class="p">;</span>
<span class="kd">const</span> <span class="nx">isFalse</span> <span class="o">=</span> <span class="nx">l</span> <span class="o">=></span> <span class="nx">l</span><span class="p">(</span><span class="nx">_</span> <span class="o">=></span> <span class="nx">myFalse</span><span class="p">,</span> <span class="nx">myTrue</span><span class="p">);</span>
</code></pre></div></div>
<p><code class="language-plaintext highlighter-rouge">true</code> and <code class="language-plaintext highlighter-rouge">false</code> are reserved words in ECMAScript, so I have had to make up my own names for them. And now finally I can create lists by doing something like this:</p>
<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">const</span> <span class="nx">list</span> <span class="o">=</span> <span class="p">(...</span><span class="nx">args</span><span class="p">)</span> <span class="o">=></span> <span class="nx">args</span><span class="p">.</span><span class="nx">reduceRight</span><span class="p">((</span><span class="nx">x</span><span class="p">,</span> <span class="nx">y</span><span class="p">)</span> <span class="o">=></span> <span class="nx">cons</span><span class="p">(</span><span class="nx">y</span><span class="p">,</span> <span class="nx">x</span><span class="p">),</span> <span class="nx">myFalse</span><span class="p">);</span>
</code></pre></div></div>
<p>As you can see, lists are terminated with a <code class="language-plaintext highlighter-rouge">myFalse</code>. Implementing this without relying on ECMAScript’s built-in methods are left as an exercise to the reader.</p>
<p>Let’s try creating a list and accessing its members:</p>
<div class="language-js console highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="o">></span> <span class="kd">const</span> <span class="nx">myList</span> <span class="o">=</span> <span class="nx">list</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">);</span>
<span class="kd">function</span> <span class="nx">cons</span><span class="p">()</span>
<span class="o">></span> <span class="nx">car</span><span class="p">(</span><span class="nx">myList</span><span class="p">);</span>
<span class="mi">1</span>
<span class="o">></span> <span class="nx">car</span><span class="p">(</span><span class="nx">cdr</span><span class="p">(</span><span class="nx">myList</span><span class="p">));</span>
<span class="mi">2</span>
<span class="o">></span> <span class="nx">car</span><span class="p">(</span><span class="nx">cdr</span><span class="p">(</span><span class="nx">cdr</span><span class="p">(</span><span class="nx">myList</span><span class="p">)));</span>
<span class="mi">3</span>
</code></pre></div></div>
<p>And if we want to turn that list back into an ECMAScript-native array? We can implement a function to do that:</p>
<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">const</span> <span class="nx">listToArray</span> <span class="o">=</span> <span class="p">(</span><span class="nx">thisList</span><span class="p">,</span> <span class="nx">thisArray</span><span class="o">=</span><span class="p">[])</span> <span class="o">=></span> <span class="p">{</span>
<span class="nx">thisArray</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">car</span><span class="p">(</span><span class="nx">thisList</span><span class="p">));</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">isFalse</span><span class="p">(</span><span class="nx">cdr</span><span class="p">(</span><span class="nx">thisList</span><span class="p">))</span> <span class="o">==</span> <span class="nx">myTrue</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="nx">thisArray</span><span class="p">;}</span>
<span class="k">return</span> <span class="nx">listToArray</span><span class="p">(</span><span class="nx">cdr</span><span class="p">(</span><span class="nx">thisList</span><span class="p">),</span> <span class="nx">thisArray</span><span class="p">);}</span>
</code></pre></div></div>
<p>And call it like so:</p>
<div class="language-js console highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="o">></span> <span class="kd">const</span> <span class="nx">foo</span> <span class="o">=</span> <span class="nx">list</span><span class="p">(</span><span class="dl">"</span><span class="s2">s</span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2">u</span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2">c</span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2">c</span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2">e</span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2">s</span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2">s</span><span class="dl">"</span><span class="p">);</span>
<span class="kc">undefined</span>
<span class="o">></span> <span class="nx">listToArray</span><span class="p">(</span><span class="nx">foo</span><span class="p">);</span>
<span class="p">[</span> <span class="dl">"</span><span class="s2">s</span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2">u</span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2">c</span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2">c</span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2">e</span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2">s</span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2">s</span><span class="dl">"</span> <span class="p">]</span>
</code></pre></div></div>
Leon Byford<p>One of the really cool things covered by Abelson and Sussman’s classic series of lectures, <a href="https://ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-001-structure-and-interpretation-of-computer-programs-spring-2005/"><em>Structure and Interpretation of Computer Programs</em> (SICP)</a>, was how fundamental programming constructs could be implemented almost from nothing. This, of course, culminated in the implementation of Scheme within Scheme itself, but it’s interesting to look at some of the smaller building blocks.</p>
How I stopped my Android phone's screen from turning on in the middle of the night2018-07-01T00:00:00Z2018-07-01T00:00:00Zhttps://blog.ldjb.uk/snoozy<p><img src="/images/snoozy.png" alt="Screenshot of SnooZy Charger showing a large number of charges in the middle of the night" /></p>
<p>The Android operating system (as does iOS, I believe) has a rather annoying “feature”. That is, whenever your device starts charging, its screen turns on, presumably to let you know that the device is now charging.</p>
<p>This sort of feedback is usually considered good interaction design. It’s important to inform the user when events occur. However, this must not come at the expense of annoying and inconveniencing the user.</p>
<!-- more -->
<p>One problem with this “feature” becomes apparent when you plug your phone in to charge at night. After a couple of minutes, the device stops charging. A couple of minutes after that, the device starts to charge again, turning the screen on. A few minutes later, charging has stopped and started again, once again turning the screen on. Thus, every three minutes or so, the screen lights up.</p>
<p>This is a problem if you’re like me and keep your phone in your bedroom. It can be difficult to get to sleep when your room is illuminated by your phone every few minutes. Not to mention it is a waste of energy. I looked online to find a solution to this issue.</p>
<p>It turns out that Android does not have a built-in option for this, but as the saying goes, there’s an app for that. I found <a href="https://android.stackexchange.com/a/60254">an entry on Stack Exchange</a> that recommended an app called SnooZy Charger.</p>
<p>This app has been pulled from the Google Play Store and the link to the APK on <a href="https://snoozy.mudar.ca/">the app’s website</a> is broken (I have submitted <a href="https://github.com/mudar/SnooZy/pull/21">a pull request to fix this</a>), but it is <a href="https://github.com/mudar/SnooZy/raw/master/APK/SnooZy-release.apk">available to download from its GitHub repo</a>.</p>
<p>By going into the Settings screen, it is possible to configure the app’s behaviour. I went with the following configuration:</p>
<blockquote>
<p><strong>Screen lock status:</strong> Locked screen only<br />
<strong>Connection status:</strong> Power connection & disconnection<br />
<strong>Charger type:</strong> Any power source<br />
<strong>Screen lock delay:</strong> Immediately</p>
</blockquote>
<p>This way, the app will prevent the phone’s screen from turning on whenever the phone starts charging. This solves my problem and my bedroom no longer lights up every few minutes.</p>
<p>There is one slight nuisance that comes with using this app, however. After SnooZy Charger has prevented the screen from turning on, the next time you want to unlock your phone, you must enter your passcode to do so, and not via fingerprint scanner or some other means. This is <a href="https://github.com/mudar/SnooZy/issues/18">a limitation of the Android operating system</a> that will hopefully be rectified in a future version of Android.</p>
<p>One additional nifty feature of SnooZy Charger is the ability to view when your device started and stopped charging, as can be seen in the screenshot at the top of this post. It is evident that the app has prevented my phone’s screen from lighting up many times through the night!</p>
Leon Byford<p><img src="/images/snoozy.png" alt="Screenshot of SnooZy Charger showing a large number of charges in the middle of the night" /></p>
<p>The Android operating system (as does iOS, I believe) has a rather annoying “feature”. That is, whenever your device starts charging, its screen turns on, presumably to let you know that the device is now charging.</p>
<p>This sort of feedback is usually considered good interaction design. It’s important to inform the user when events occur. However, this must not come at the expense of annoying and inconveniencing the user.</p>
The case against HTTPS2018-06-15T00:00:00Z2018-06-15T00:00:00Zhttps://blog.ldjb.uk/the-case-against-https<p>I recently read <a href="https://scotthelme.co.uk/https-anti-vaxxers/">a blog post</a> dispelling arguments against HTTPS. I am certainly of the opinion that 99% of websites should use an encrypted connection. However, I do think critics of HTTPS do have some good points, and there are cases where an unencrypted connection is actually desirable.</p>
<!-- more -->
<h3 id="criticism-of-google">Criticism of Google</h3>
<p>One criticism highlighted in the above blog post is against Google. Whilst Google are certainly not deprecating HTTPS, they have been <a href="https://webmasters.googleblog.com/2014/08/https-as-ranking-signal.html">prioritising websites served under HTTPS</a> in web search rankings for a few years now. This means that a website may be penalised slightly for not adopting HTTPS. Whilst there are good reasons for this, it does mean a more useful website may not rank as high as a less useful one, just because it is not served over an encrypted connection. In this instance, I think Google have made the right decision, but I accept that not everyone will see it that way. Certainly, there is a point of view that says Google should provide the user with the most relevant results, regardless of whether a website uses HTTPS or not. And I think there is a valid point there. However, for me, security is more important.</p>
<h3 id="slow-and-expensive">Slow and expensive?</h3>
<p>Another argument against HTTPS brought up in the linked blog post is that HTTPS is “slow and expensive”. Whilst I wouldn’t describe it with those terms, HTTPS is certainly slower and computationally expensive than using an unencrypted connection. It also results in larger amounts of data sent over the wire.</p>
<p>Once again, security should probably take priority. But it is always worth considering people with poor Internet connectivity (if they live in a remote area, for example) and low-power devices. Security aside, using HTTPS may result in a poorer user experience.</p>
<h3 id="security-issues-with-https">Security issues with HTTPS</h3>
<p>HTTPS is not perfect. There are flaws with the system, and I don’t think these should be completely dismissed. For instance, there were <a href="https://wiki.mozilla.org/CA:Symantec_Issues">a large number of issues</a> in how Symantec handled security. These were so severe that many web browser vendors ended up distrusting Symantec certificates.</p>
<p>Unfortunately, despite these issues, HTTPS is the best solution we have. So it is still worth using. But that doesn’t mean any security concerns are invalid.</p>
<h3 id="learning-about-http">Learning about HTTP</h3>
<p>Before learning about HTTPS, it is essentially necessary to learn about HTTP. To understand how the protocol works, there is no substitute to making some actual HTTP requests yourself.</p>
<p>You can do this by opening up a TCP/IP connect with <code class="language-plaintext highlighter-rouge">telnet</code>:</p>
<div class="language-plaintext console highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ telnet example.com 80
Trying 93.184.216.34...
Connected to example.com.
Escape character is '^]'.
GET / HTTP/1.1
Host: example.com
HTTP/1.1 200 OK
Cache-Control: max-age=604800
Content-Type: text/html
Date: Mon, 11 Jun 2018 16:39:05 GMT
Etag: "1541025663+ident"
Expires: Mon, 18 Jun 2018 16:39:05 GMT
Last-Modified: Fri, 09 Aug 2013 23:54:35 GMT
Server: ECS (lga/13A2)
Vary: Accept-Encoding
X-Cache: HIT
Content-Length: 1270
<!doctype html>
[...]
</code></pre></div></div>
<p>This is a fantastic way to learn how HTTP works. But you can’t do this over HTTPS without figuring out how to deal with TLS. Sure, you can construct HTTPS requests using <code class="language-plaintext highlighter-rouge">curl</code>, but it’s not the same as actually typing out the headers manually over a live TCP/IP connection.</p>
<p>Therefore, it is useful to have some websites available over HTTP (example.com is a good one) so you can learn how the protocol works.</p>
<h3 id="demonstrating-the-need-for-https">Demonstrating the need for HTTPS</h3>
<p>A fantastic way to show someone the issues of using an unencrypted connection (and thus why HTTPS is so important) is to demonstrate it to them. Actually stage a man-in-the-middle attack and show how a requests can be hijacked. Naturally, you can’t do this over an encrypted connection, so the website being used to demonstrate this must be served over regular HTTP.</p>
<p>Without any sites using an unencrypted connection, people would probably question the necessity of HTTPS. So it’s worth having some websites that do not use HTTPS to demonstrate its purpose.</p>
<h3 id="localhost">localhost</h3>
<p>When I’m developing a website, I’ll very often have a version of the site running locally on my computer so I can test it. This saves having to constantly upload files to a remote server. In fact, as I’m typing this post now, I have a copy of my website being served from <code class="language-plaintext highlighter-rouge">localhost</code>. That way I know how this web page will look when it is published to the actual website.</p>
<p>Serving websites over HTTPS on <code class="language-plaintext highlighter-rouge">localhost</code> is cumbersome and serves little purpose. If a man-in-the-middle attack is possible on my own computer, the security of my test website is the least of my worries.</p>
<p>A similar thing can be said for websites only available on an internal network. Whilst there is a greater security risk should you be using a public Wi-Fi network, for example, my home network is only used by myself and people I trust. Therefore, serving websites over HTTPS is unnecessary. (Of course, there is always the possibility that a device on the network has been compromised. Depending on the nature of the website, HTTPS may still be useful. However, if you’re simply serving a test website to see how it looks and functions on different devices, it shouldn’t really matter.)</p>
<h3 id="connecting-to-a-public-wi-fi-network">Connecting to a public Wi-Fi network</h3>
<p>A lot of public Wi-Fi networks use a <a href="https://en.wikipedia.org/wiki/Captive_portal">captive portal</a> that requires the user to sign in or accept some terms and conditions before they can connect to the Internet.</p>
<p>To get to the captive portal, you need to make an HTTP request, which will be intercepted, and the captive portal will be served. This is, in fact, a man-in-the-middle attack. Naturally, HTTPS prevents this from working. Enter websites like <a href="http://neverssl.com/">NeverSSL</a> which claims it will never be served over HTTPS. Therefore, if you wish to connect to a network that uses a captive portal, you can simply attempt to access the NeverSSL website, and you will be taken to the captive portal. If NeverSSL were served over HTTPS, this would not work, and the website’s purpose would be defeated.</p>
<h3 id="apis-for-legacy-clients">APIs for legacy clients</h3>
<p>Suppose your company has previously produced Internet-connected devices that interact with an API over HTTP. They expect an unencrypted connection and it is not possible to upgrade the connection to HTTPS. If you were to disable unencrypted connections, these devices would cease to function and your customers would be unhappy. Whilst all future devices should support and use HTTPS, it may make sense to keep functioning devices that are already in use. As such, retaining a legacy API for those devices may be sensible.</p>
<h3 id="conclusion">Conclusion</h3>
<p>And there you have it. Whilst I believe the vast majority of websites should use HTTPS, that’s not to say it’s unfair to make criticisms about HTTPS or that there aren’t legitimate reasons for serving a website over an unencrypted connection.</p>
<p>There are further concerns that could be made about how web browsers are indicating (or not) the use of an encrypted connection to users, but that will have to be a post for another day.</p>
Leon Byford<p>I recently read <a href="https://scotthelme.co.uk/https-anti-vaxxers/">a blog post</a> dispelling arguments against HTTPS. I am certainly of the opinion that 99% of websites should use an encrypted connection. However, I do think critics of HTTPS do have some good points, and there are cases where an unencrypted connection is actually desirable.</p>
Constants can change!2018-06-01T00:00:00Z2018-06-01T00:00:00Zhttps://blog.ldjb.uk/constants-can-change<p>A common misconception I’ve noticed amongst fellow programmers is the idea that constants can never be modified. Whilst it is true that a constant’s value may never change <em>during runtime</em>, it may certainly be appropriate for a programmer to modify it <em>in the source code</em>.</p>
<!-- more -->
<p>Consider the following JavaScript for calculating a product’s price <em>before</em> value-added tax (VAT) is applied, given its price <em>after</em> it has been applied:</p>
<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">const</span> <span class="nx">VAT_PERCENT</span> <span class="o">=</span> <span class="mf">17.5</span><span class="p">;</span>
<span class="kd">let</span> <span class="nx">calcBasePrice</span> <span class="o">=</span> <span class="nx">sellingPrice</span> <span class="o">=></span> <span class="nx">sellingPrice</span> <span class="o">/</span> <span class="p">(</span><span class="mi">1</span> <span class="o">+</span> <span class="nx">VAT_PERCENT</span> <span class="o">/</span> <span class="mi">100</span><span class="p">);</span>
</code></pre></div></div>
<p>Now suppose a recession occurs and the Chancellor of the Exchequer decides to reduce VAT from 17.5% to 15%. Well in that case, we can simply change the first line of code to:</p>
<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">const</span> <span class="nx">VAT_PERCENT</span> <span class="o">=</span> <span class="mi">15</span><span class="p">;</span>
</code></pre></div></div>
<p>Since we’ve changed the value of <code class="language-plaintext highlighter-rouge">VAT_PERCENT</code>, why not just make it a variable? Well, let’s see what happens if we do. Oh, and let’s create a new function whilst we’re at it to calculate the VAT:</p>
<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">var</span> <span class="nx">VAT_PERCENT</span> <span class="o">=</span> <span class="mi">15</span><span class="p">;</span>
<span class="kd">let</span> <span class="nx">calcBasePrice</span> <span class="o">=</span> <span class="nx">sellingPrice</span> <span class="o">=></span> <span class="nx">sellingPrice</span> <span class="o">/</span> <span class="p">(</span><span class="mi">1</span> <span class="o">+</span> <span class="nx">VAT_PERCENT</span> <span class="o">/</span> <span class="mi">100</span><span class="p">);</span>
<span class="kd">var</span> <span class="nx">VAT_PERCENT</span> <span class="o">=</span> <span class="mi">15</span><span class="p">;</span>
<span class="kd">let</span> <span class="nx">calcVAT</span> <span class="o">=</span> <span class="nx">sellingPrice</span> <span class="o">=></span> <span class="nx">sellingPrice</span> <span class="o">*</span> <span class="p">(</span><span class="mi">1</span> <span class="o">-</span> <span class="mi">1</span> <span class="o">/</span> <span class="p">(</span><span class="mi">1</span> <span class="o">+</span> <span class="nx">VAT_PERCENT</span> <span class="o">/</span> <span class="mi">100</span><span class="p">));</span>
</code></pre></div></div>
<p>Well, whoever wrote the above code is clearly not the best programmer. They’ve accidentally re-declared the <code class="language-plaintext highlighter-rouge">VAT_PERCENT</code> variable, and the <code class="language-plaintext highlighter-rouge">calcVAT</code> function is a bit overly complex. Still, the code works. That’s the important part, right?</p>
<p>Now suppose the Chancellor of the Exchequer decides to increase VAT from 15% to 20%. The programmer updates the code:</p>
<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">var</span> <span class="nx">VAT_PERCENT</span> <span class="o">=</span> <span class="mi">20</span><span class="p">;</span>
<span class="kd">let</span> <span class="nx">calcBasePrice</span> <span class="o">=</span> <span class="nx">sellingPrice</span> <span class="o">=></span> <span class="nx">sellingPrice</span> <span class="o">/</span> <span class="p">(</span><span class="mi">1</span> <span class="o">+</span> <span class="nx">VAT_PERCENT</span> <span class="o">/</span> <span class="mi">100</span><span class="p">);</span>
<span class="kd">var</span> <span class="nx">VAT_PERCENT</span> <span class="o">=</span> <span class="mi">15</span><span class="p">;</span>
<span class="kd">let</span> <span class="nx">calcVAT</span> <span class="o">=</span> <span class="nx">sellingPrice</span> <span class="o">=></span> <span class="nx">sellingPrice</span> <span class="o">*</span> <span class="p">(</span><span class="mi">1</span> <span class="o">-</span> <span class="mi">1</span> <span class="o">/</span> <span class="p">(</span><span class="mi">1</span> <span class="o">+</span> <span class="nx">VAT_PERCENT</span> <span class="o">/</span> <span class="mi">100</span><span class="p">));</span>
</code></pre></div></div>
<p>Oh no! The programmer has updated the first declaration of <code class="language-plaintext highlighter-rouge">VAT_PERCENT</code>, but hasn’t noticed that <code class="language-plaintext highlighter-rouge">VAT_PERCENT</code> was declared a second time.</p>
<p>This is why constants are so useful. Once you’ve declared and assigned them, they cannot be re-declared or re-assigned.</p>
<p>So why not use these named constants all the time? Why not do:</p>
<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">const</span> <span class="nx">NINETY_NINE</span> <span class="o">=</span> <span class="mi">99</span><span class="p">;</span>
<span class="kd">const</span> <span class="nx">ONE</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span>
<span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">i</span> <span class="o">=</span> <span class="nx">NINETY_NINE</span><span class="p">;</span> <span class="nx">i</span> <span class="o">>=</span> <span class="nx">ONE</span><span class="p">;</span> <span class="o">--</span><span class="nx">i</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">i</span> <span class="o">+</span> <span class="dl">"</span><span class="s2"> bottles of beer on the wall,</span><span class="dl">"</span><span class="p">);</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">i</span> <span class="o">+</span> <span class="dl">"</span><span class="s2"> bottles of beer.</span><span class="dl">"</span><span class="p">);</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="dl">"</span><span class="s2">Take one down, pass it around,</span><span class="dl">"</span><span class="p">);</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">i</span><span class="o">-</span><span class="mi">1</span> <span class="o">+</span> <span class="dl">"</span><span class="s2"> bottles of beer on the wall.</span><span class="dl">"</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div></div>
<p>That certainly works, but there is no point in declaring a named constant for the number three. Unlike VAT which is subject to change, the number ninety-nine will always have the value <code class="language-plaintext highlighter-rouge">99</code>, and the number one will always have the value <code class="language-plaintext highlighter-rouge">1</code>. Therefore it is perfectly legitimate to use a literal constant for this purpose.</p>
<p>In summary:</p>
<ul>
<li>Use <strong>variables</strong> for things that change <em>during runtime</em>.</li>
<li>Use <strong>named constants</strong> for things that are subject to change <em>external to the program</em> (or for convenience/legibility, e.g. π).</li>
<li>Use <strong>literal constants</strong> for things that will absolutely never change (unless giving it a name is more convenient/legible).</li>
</ul>
Leon Byford<p>A common misconception I’ve noticed amongst fellow programmers is the idea that constants can never be modified. Whilst it is true that a constant’s value may never change <em>during runtime</em>, it may certainly be appropriate for a programmer to modify it <em>in the source code</em>.</p>
Updated: Adding custom amounts to your Steam Wallet2018-05-21T00:00:00Z2018-05-21T00:00:00Zhttps://blog.ldjb.uk/steam-wallet-custom-amounts<p><img src="/images/steam-wallet.png" alt="Screenshot showing the process of adding funds to a Steam Wallet" /></p>
<p><em>This post was originally written in 2015, but has been revised to reflect changes to the Steam service.</em></p>
<p>PC game distribution service Steam allows users to purchase funds for their ‘Steam Wallet’ which can then be used to buy games and in-game content.</p>
<p>That can be done on <a href="https://store.steampowered.com/steamaccount/addfunds">this webpage</a>. It’s great if you want to add £4, £10, £25, £50 or £100 to your account, but what if for some reason you wanted to add an amount that’s not listed? Is this possible?</p>
<p>The answer is, of course, yes! But it requires a little trickery:</p>
<!-- more -->
<p>On the ‘Add funds to your Steam Wallet’ webpage, enter the following into your web browser’s address bar:</p>
<div class="language-js console highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">javascript</span><span class="p">:</span><span class="nx">submitAddFunds</span><span class="p">({</span><span class="na">dataset</span><span class="p">:{</span><span class="na">amount</span><span class="p">:</span><span class="mi">401</span><span class="p">,</span><span class="na">currency</span><span class="p">:</span><span class="dl">"</span><span class="s2">GBP</span><span class="dl">"</span><span class="p">}});</span>
</code></pre></div></div>
<p>You can replace <code class="language-plaintext highlighter-rouge">401</code> with the amount you want to add in pence. <code class="language-plaintext highlighter-rouge">401</code> means £4.01. If you wish to use a different currency, replace <code class="language-plaintext highlighter-rouge">GBP</code> with the currency’s <a href="https://www.iso.org/iso-4217-currency-codes.html">ISO 4217 code</a>.</p>
<p>Pressing the Return key will direct you to pay for your funds.</p>
<p>Note that when they say £4.00 is the “minimum fund level”, they’re not kidding! It’s unfortunately not possible to add less than this amount, even with this method. There also appears to be an upper limit somewhere between £300 and £400.</p>
Leon Byford<p><img src="/images/steam-wallet.png" alt="Screenshot showing the process of adding funds to a Steam Wallet" /></p>
<p><em>This post was originally written in 2015, but has been revised to reflect changes to the Steam service.</em></p>
<p>PC game distribution service Steam allows users to purchase funds for their ‘Steam Wallet’ which can then be used to buy games and in-game content.</p>
<p>That can be done on <a href="https://store.steampowered.com/steamaccount/addfunds">this webpage</a>. It’s great if you want to add £4, £10, £25, £50 or £100 to your account, but what if for some reason you wanted to add an amount that’s not listed? Is this possible?</p>
<p>The answer is, of course, yes! But it requires a little trickery:</p>
FizzBuzz in Racket using pattern matching2018-05-11T00:00:00Z2018-05-11T00:00:00Zhttps://blog.ldjb.uk/fizzbuzz-racket<p>Today I came across <a href="https://github.com/EnterpriseQualityCoding/FizzBuzzEnterpriseEdition">this satirical take on the FizzBuzz programming test</a> (via <a href="https://news.ycombinator.com/item?id=17043541">Hacker News</a>). The <a href="http://wiki.c2.com/?FizzBuzzTest">FizzBuzz test</a> requires you to write a program that will output the positive integers 1 to n (where usually n=100) with certain substitutions, <a href="https://en.wikipedia.org/wiki/Fizz_buzz">as in the children’s game</a>. If the number is divisible by 3, the value <code class="language-plaintext highlighter-rouge">Fizz</code> is provided. If the number is divisible by 5, the value <code class="language-plaintext highlighter-rouge">Buzz</code> is provided. If the number is divisible by both 3 and 5, the value <code class="language-plaintext highlighter-rouge">FizzBuzz</code> is provided.</p>
<p>Anyway, it got me thinking about how I would implement FizzBuzz using one of my favourite programming languages – <a href="https://racket-lang.org/">Racket</a>, a descendant of <a href="https://en.wikipedia.org/wiki/Scheme_(programming_language)">Scheme</a> (itself a dialect of <a href="https://en.wikipedia.org/wiki/Lisp_(programming_language)">Lisp</a>).</p>
<!-- more -->
<p>First off, let’s create a function <code class="language-plaintext highlighter-rouge">int->fb</code> that will simply take in an integer and output the correct response. Depending on its factors, it will either output the integer itself, or one of the symbols <code class="language-plaintext highlighter-rouge">'Fizz</code>, <code class="language-plaintext highlighter-rouge">'Buzz</code> or <code class="language-plaintext highlighter-rouge">'FizzBuzz</code>:</p>
<div class="language-racket highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="k">define</span> <span class="p">(</span><span class="nf">int->fb</span> <span class="nv">int</span><span class="p">)</span>
<span class="p">(</span><span class="nf">match</span> <span class="p">(</span><span class="nb">list</span> <span class="p">(</span><span class="nb">=</span> <span class="p">(</span><span class="nb">modulo</span> <span class="nv">int</span> <span class="mi">3</span><span class="p">)</span> <span class="mi">0</span><span class="p">)</span>
<span class="p">(</span><span class="nb">=</span> <span class="p">(</span><span class="nb">modulo</span> <span class="nv">int</span> <span class="mi">5</span><span class="p">)</span> <span class="mi">0</span><span class="p">))</span>
<span class="p">[</span><span class="o">'</span><span class="p">(</span><span class="nf">#t</span> <span class="no">#t</span><span class="p">)</span> <span class="ss">'FizzBuzz</span><span class="p">]</span>
<span class="p">[</span><span class="o">'</span><span class="p">(</span><span class="nf">#t</span> <span class="no">#f</span><span class="p">)</span> <span class="ss">'Fizz</span><span class="p">]</span>
<span class="p">[</span><span class="o">'</span><span class="p">(</span><span class="nf">#f</span> <span class="no">#t</span><span class="p">)</span> <span class="ss">'Buzz</span><span class="p">]</span>
<span class="p">[</span><span class="nf">_</span> <span class="nv">int</span><span class="p">]))</span>
</code></pre></div></div>
<p>This uses a technique called <a href="https://docs.racket-lang.org/guide/match.html">pattern matching</a>. We create a list (though a cons pair would also work) with the first item being a boolean indicating whether <code class="language-plaintext highlighter-rouge">int</code> is a divisible by 3, and the second item being a boolean indicating whether <code class="language-plaintext highlighter-rouge">int</code> is divisible by 5.</p>
<p>We then determine which pattern the list matches against. If both items in the list are true, we return “FizzBuzz”. If only one is true, we return “Fizz” or “Buzz” as appropriate. If neither are true, we return <code class="language-plaintext highlighter-rouge">int</code> itself. Let’s see if it works:</p>
<div class="language-racket console highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">></span> <span class="p">(</span><span class="nf">int->fb</span> <span class="mi">6</span><span class="p">)</span>
<span class="ss">'Fizz</span>
<span class="nv">></span> <span class="p">(</span><span class="nf">int->fb</span> <span class="mi">15</span><span class="p">)</span>
<span class="ss">'Buzz</span>
<span class="nv">></span> <span class="p">(</span><span class="nf">int->fb</span> <span class="mi">60</span><span class="p">)</span>
<span class="ss">'FizzBuzz</span>
<span class="nv">></span> <span class="p">(</span><span class="nf">int->fb</span> <span class="mi">64</span><span class="p">)</span>
<span class="mi">64</span>
</code></pre></div></div>
<p>It works! Now we need to find a way to create a list of the first n numbers. We can define a function <code class="language-plaintext highlighter-rouge">fizzbuzz</code> that does this:</p>
<div class="language-racket highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="k">define</span> <span class="p">(</span><span class="nf">fizzbuzz</span> <span class="nv">n</span><span class="p">)</span>
<span class="p">(</span><span class="k">if</span> <span class="p">(</span><span class="nb"><</span> <span class="nv">n</span> <span class="mi">1</span><span class="p">)</span>
<span class="o">'</span><span class="p">()</span>
<span class="p">(</span><span class="nb">append</span> <span class="p">(</span><span class="nf">fizzbuzz</span> <span class="p">(</span><span class="nb">-</span> <span class="nv">n</span> <span class="mi">1</span><span class="p">))</span>
<span class="p">(</span><span class="nb">list</span> <span class="p">(</span><span class="nf">int->fb</span> <span class="nv">n</span><span class="p">)))))</span>
</code></pre></div></div>
<p>This takes in the parameter <code class="language-plaintext highlighter-rouge">n</code>, which is the length of the list to be returned. Although we could use iteration, it is neater to use recursion. Therefore we check to see whether <code class="language-plaintext highlighter-rouge">n</code> is less than 1. If it is, we return the empty list, otherwise we call the <code class="language-plaintext highlighter-rouge">fizzbuzz</code> function with <code class="language-plaintext highlighter-rouge">n</code> reduced by 1, appending the correct substitution for <code class="language-plaintext highlighter-rouge">n</code> to the returned list.</p>
<p>We can now produce a list of the first 100 numbers:</p>
<div class="language-racket console highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">></span> <span class="p">(</span><span class="nf">fizzbuzz</span> <span class="mi">100</span><span class="p">)</span>
<span class="p">(</span><span class="nf">1</span> <span class="mi">2</span> <span class="nv">Fizz</span> <span class="mi">4</span> <span class="nv">Buzz</span> <span class="nv">Fizz</span> <span class="mi">7</span> <span class="mi">8</span> <span class="nv">Fizz</span> <span class="nv">Buzz</span> <span class="mi">11</span> <span class="nv">Fizz</span> <span class="mi">13</span> <span class="mi">14</span> <span class="nv">FizzBuzz</span> <span class="mi">16</span> <span class="mi">17</span> <span class="nv">Fizz</span> <span class="mi">19</span> <span class="nv">Buzz</span>
<span class="nv">Fizz</span> <span class="mi">22</span> <span class="mi">23</span> <span class="nv">Fizz</span> <span class="nv">Buzz</span> <span class="mi">26</span> <span class="nv">Fizz</span> <span class="mi">28</span> <span class="mi">29</span> <span class="nv">FizzBuzz</span> <span class="mi">31</span> <span class="mi">32</span> <span class="nv">Fizz</span> <span class="mi">34</span> <span class="nv">Buzz</span> <span class="nv">Fizz</span> <span class="mi">37</span> <span class="mi">38</span> <span class="nv">Fizz</span>
<span class="nv">Buzz</span> <span class="mi">41</span> <span class="nv">Fizz</span> <span class="mi">43</span> <span class="mi">44</span> <span class="nv">FizzBuzz</span> <span class="mi">46</span> <span class="mi">47</span> <span class="nv">Fizz</span> <span class="mi">49</span> <span class="nv">Buzz</span> <span class="nv">Fizz</span> <span class="mi">52</span> <span class="mi">53</span> <span class="nv">Fizz</span> <span class="nv">Buzz</span> <span class="mi">56</span> <span class="nv">Fizz</span> <span class="mi">58</span>
<span class="mi">59</span> <span class="nv">FizzBuzz</span> <span class="mi">61</span> <span class="mi">62</span> <span class="nv">Fizz</span> <span class="mi">64</span> <span class="nv">Buzz</span> <span class="nv">Fizz</span> <span class="mi">67</span> <span class="mi">68</span> <span class="nv">Fizz</span> <span class="nv">Buzz</span> <span class="mi">71</span> <span class="nv">Fizz</span> <span class="mi">73</span> <span class="mi">74</span> <span class="nv">FizzBuzz</span> <span class="mi">76</span> <span class="mi">77</span>
<span class="nv">Fizz</span> <span class="mi">79</span> <span class="nv">Buzz</span> <span class="nv">Fizz</span> <span class="mi">82</span> <span class="mi">83</span> <span class="nv">Fizz</span> <span class="nv">Buzz</span> <span class="mi">86</span> <span class="nv">Fizz</span> <span class="mi">88</span> <span class="mi">89</span> <span class="nv">FizzBuzz</span> <span class="mi">91</span> <span class="mi">92</span> <span class="nv">Fizz</span> <span class="mi">94</span> <span class="nv">Buzz</span> <span class="nv">Fizz</span>
<span class="mi">97</span> <span class="mi">98</span> <span class="nv">Fizz</span> <span class="nv">Buzz</span><span class="p">)</span>
</code></pre></div></div>
<h3 id="bonus-fizzbuzz-in-ecmascript-using-pattern-matching">Bonus: FizzBuzz in ECMAScript using “pattern matching”</h3>
<p>If <a href="https://www.crockford.com/javascript/javascript.html"><del>JavaScript</del> ECMAScript is a Lisp</a>, and Racket is a Scheme is a Lisp, then it should be relatively straightforward to port my Racket implementation to ECMAScript, right? Here’s my attempt:</p>
<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">let</span> <span class="nx">int2fb</span> <span class="o">=</span> <span class="nx">int</span> <span class="o">=></span> <span class="p">{</span>
<span class="k">switch</span> <span class="p">([</span><span class="nx">int</span> <span class="o">%</span> <span class="mi">3</span> <span class="o">===</span> <span class="mi">0</span><span class="p">,</span> <span class="nx">int</span> <span class="o">%</span> <span class="mi">5</span> <span class="o">===</span> <span class="mi">0</span><span class="p">].</span><span class="nx">toString</span><span class="p">())</span> <span class="p">{</span>
<span class="k">case</span> <span class="dl">"</span><span class="s2">true,true</span><span class="dl">"</span><span class="p">:</span> <span class="k">return</span> <span class="dl">"</span><span class="s2">FizzBuzz</span><span class="dl">"</span><span class="p">;</span>
<span class="k">case</span> <span class="dl">"</span><span class="s2">true,false</span><span class="dl">"</span><span class="p">:</span> <span class="k">return</span> <span class="dl">"</span><span class="s2">Fizz</span><span class="dl">"</span><span class="p">;</span>
<span class="k">case</span> <span class="dl">"</span><span class="s2">false,true</span><span class="dl">"</span><span class="p">:</span> <span class="k">return</span> <span class="dl">"</span><span class="s2">Buzz</span><span class="dl">"</span><span class="p">;</span>
<span class="nl">default</span><span class="p">:</span> <span class="k">return</span> <span class="nx">int</span><span class="p">;}}</span>
<span class="kd">let</span> <span class="nx">fizzbuzz</span> <span class="o">=</span> <span class="nx">n</span> <span class="o">=></span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">n</span> <span class="o"><</span> <span class="mi">1</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="p">[];}</span>
<span class="k">else</span> <span class="p">{</span>
<span class="kd">let</span> <span class="nx">arrRecursed</span> <span class="o">=</span> <span class="nx">fizzbuzz</span><span class="p">(</span><span class="nx">n</span> <span class="o">-</span> <span class="mi">1</span><span class="p">);</span>
<span class="nx">arrRecursed</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">int2fb</span><span class="p">(</span><span class="nx">n</span><span class="p">));</span>
<span class="k">return</span> <span class="nx">arrRecursed</span><span class="p">;}}</span>
</code></pre></div></div>
<p>Okay, so ECMAScript doesn’t really have an equivalent to Racket’s <code class="language-plaintext highlighter-rouge">match</code> construct, but we can do something similar by converting an array to a string and comparing the result with other strings. And <code class="language-plaintext highlighter-rouge">Array.prototype.push</code> returns the length of the array rather than the array itself for some bizarre reason, which makes a bit of a mess. But hey, it works:</p>
<div class="language-js console highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="o">></span> <span class="nx">fizzbuzz</span><span class="p">(</span><span class="mi">100</span><span class="p">)</span>
<span class="p">[</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">,</span><span class="dl">"</span><span class="s2">Fizz</span><span class="dl">"</span><span class="p">,</span><span class="mi">4</span><span class="p">,</span><span class="dl">"</span><span class="s2">Buzz</span><span class="dl">"</span><span class="p">,</span><span class="dl">"</span><span class="s2">Fizz</span><span class="dl">"</span><span class="p">,</span><span class="mi">7</span><span class="p">,</span><span class="mi">8</span><span class="p">,</span><span class="dl">"</span><span class="s2">Fizz</span><span class="dl">"</span><span class="p">,</span><span class="dl">"</span><span class="s2">Buzz</span><span class="dl">"</span><span class="p">,</span><span class="mi">11</span><span class="p">,</span><span class="dl">"</span><span class="s2">Fizz</span><span class="dl">"</span><span class="p">,</span><span class="mi">13</span><span class="p">,</span><span class="mi">14</span><span class="p">,</span><span class="dl">"</span><span class="s2">FizzBuzz</span><span class="dl">"</span><span class="p">,</span><span class="mi">16</span><span class="p">,</span><span class="mi">17</span><span class="p">,</span>
<span class="dl">"</span><span class="s2">Fizz</span><span class="dl">"</span><span class="p">,</span><span class="mi">19</span><span class="p">,</span><span class="dl">"</span><span class="s2">Buzz</span><span class="dl">"</span><span class="p">,</span><span class="dl">"</span><span class="s2">Fizz</span><span class="dl">"</span><span class="p">,</span><span class="mi">22</span><span class="p">,</span><span class="mi">23</span><span class="p">,</span><span class="dl">"</span><span class="s2">Fizz</span><span class="dl">"</span><span class="p">,</span><span class="dl">"</span><span class="s2">Buzz</span><span class="dl">"</span><span class="p">,</span><span class="mi">26</span><span class="p">,</span><span class="dl">"</span><span class="s2">Fizz</span><span class="dl">"</span><span class="p">,</span><span class="mi">28</span><span class="p">,</span><span class="mi">29</span><span class="p">,</span><span class="dl">"</span><span class="s2">FizzBuzz</span><span class="dl">"</span><span class="p">,</span><span class="mi">31</span><span class="p">,</span><span class="mi">32</span><span class="p">,</span>
<span class="dl">"</span><span class="s2">Fizz</span><span class="dl">"</span><span class="p">,</span><span class="mi">34</span><span class="p">,</span><span class="dl">"</span><span class="s2">Buzz</span><span class="dl">"</span><span class="p">,</span><span class="dl">"</span><span class="s2">Fizz</span><span class="dl">"</span><span class="p">,</span><span class="mi">37</span><span class="p">,</span><span class="mi">38</span><span class="p">,</span><span class="dl">"</span><span class="s2">Fizz</span><span class="dl">"</span><span class="p">,</span><span class="dl">"</span><span class="s2">Buzz</span><span class="dl">"</span><span class="p">,</span><span class="mi">41</span><span class="p">,</span><span class="dl">"</span><span class="s2">Fizz</span><span class="dl">"</span><span class="p">,</span><span class="mi">43</span><span class="p">,</span><span class="mi">44</span><span class="p">,</span><span class="dl">"</span><span class="s2">FizzBuzz</span><span class="dl">"</span><span class="p">,</span><span class="mi">46</span><span class="p">,</span><span class="mi">47</span><span class="p">,</span>
<span class="dl">"</span><span class="s2">Fizz</span><span class="dl">"</span><span class="p">,</span><span class="mi">49</span><span class="p">,</span><span class="dl">"</span><span class="s2">Buzz</span><span class="dl">"</span><span class="p">,</span><span class="dl">"</span><span class="s2">Fizz</span><span class="dl">"</span><span class="p">,</span><span class="mi">52</span><span class="p">,</span><span class="mi">53</span><span class="p">,</span><span class="dl">"</span><span class="s2">Fizz</span><span class="dl">"</span><span class="p">,</span><span class="dl">"</span><span class="s2">Buzz</span><span class="dl">"</span><span class="p">,</span><span class="mi">56</span><span class="p">,</span><span class="dl">"</span><span class="s2">Fizz</span><span class="dl">"</span><span class="p">,</span><span class="mi">58</span><span class="p">,</span><span class="mi">59</span><span class="p">,</span><span class="dl">"</span><span class="s2">FizzBuzz</span><span class="dl">"</span><span class="p">,</span><span class="mi">61</span><span class="p">,</span><span class="mi">62</span><span class="p">,</span>
<span class="dl">"</span><span class="s2">Fizz</span><span class="dl">"</span><span class="p">,</span><span class="mi">64</span><span class="p">,</span><span class="dl">"</span><span class="s2">Buzz</span><span class="dl">"</span><span class="p">,</span><span class="dl">"</span><span class="s2">Fizz</span><span class="dl">"</span><span class="p">,</span><span class="mi">67</span><span class="p">,</span><span class="mi">68</span><span class="p">,</span><span class="dl">"</span><span class="s2">Fizz</span><span class="dl">"</span><span class="p">,</span><span class="dl">"</span><span class="s2">Buzz</span><span class="dl">"</span><span class="p">,</span><span class="mi">71</span><span class="p">,</span><span class="dl">"</span><span class="s2">Fizz</span><span class="dl">"</span><span class="p">,</span><span class="mi">73</span><span class="p">,</span><span class="mi">74</span><span class="p">,</span><span class="dl">"</span><span class="s2">FizzBuzz</span><span class="dl">"</span><span class="p">,</span><span class="mi">76</span><span class="p">,</span><span class="mi">77</span><span class="p">,</span>
<span class="dl">"</span><span class="s2">Fizz</span><span class="dl">"</span><span class="p">,</span><span class="mi">79</span><span class="p">,</span><span class="dl">"</span><span class="s2">Buzz</span><span class="dl">"</span><span class="p">,</span><span class="dl">"</span><span class="s2">Fizz</span><span class="dl">"</span><span class="p">,</span><span class="mi">82</span><span class="p">,</span><span class="mi">83</span><span class="p">,</span><span class="dl">"</span><span class="s2">Fizz</span><span class="dl">"</span><span class="p">,</span><span class="dl">"</span><span class="s2">Buzz</span><span class="dl">"</span><span class="p">,</span><span class="mi">86</span><span class="p">,</span><span class="dl">"</span><span class="s2">Fizz</span><span class="dl">"</span><span class="p">,</span><span class="mi">88</span><span class="p">,</span><span class="mi">89</span><span class="p">,</span><span class="dl">"</span><span class="s2">FizzBuzz</span><span class="dl">"</span><span class="p">,</span><span class="mi">91</span><span class="p">,</span><span class="mi">92</span><span class="p">,</span>
<span class="dl">"</span><span class="s2">Fizz</span><span class="dl">"</span><span class="p">,</span><span class="mi">94</span><span class="p">,</span><span class="dl">"</span><span class="s2">Buzz</span><span class="dl">"</span><span class="p">,</span><span class="dl">"</span><span class="s2">Fizz</span><span class="dl">"</span><span class="p">,</span><span class="mi">97</span><span class="p">,</span><span class="mi">98</span><span class="p">,</span><span class="dl">"</span><span class="s2">Fizz</span><span class="dl">"</span><span class="p">,</span><span class="dl">"</span><span class="s2">Buzz</span><span class="dl">"</span><span class="p">]</span>
</code></pre></div></div>
Leon Byford<p>Today I came across <a href="https://github.com/EnterpriseQualityCoding/FizzBuzzEnterpriseEdition">this satirical take on the FizzBuzz programming test</a> (via <a href="https://news.ycombinator.com/item?id=17043541">Hacker News</a>). The <a href="http://wiki.c2.com/?FizzBuzzTest">FizzBuzz test</a> requires you to write a program that will output the positive integers 1 to n (where usually n=100) with certain substitutions, <a href="https://en.wikipedia.org/wiki/Fizz_buzz">as in the children’s game</a>. If the number is divisible by 3, the value <code class="language-plaintext highlighter-rouge">Fizz</code> is provided. If the number is divisible by 5, the value <code class="language-plaintext highlighter-rouge">Buzz</code> is provided. If the number is divisible by both 3 and 5, the value <code class="language-plaintext highlighter-rouge">FizzBuzz</code> is provided.</p>
<p>Anyway, it got me thinking about how I would implement FizzBuzz using one of my favourite programming languages – <a href="https://racket-lang.org/">Racket</a>, a descendant of <a href="https://en.wikipedia.org/wiki/Scheme_(programming_language)">Scheme</a> (itself a dialect of <a href="https://en.wikipedia.org/wiki/Lisp_(programming_language)">Lisp</a>).</p>
Eurovision 2018, Semi-Final 22018-05-10T00:00:00Z2018-05-10T00:00:00Zhttps://blog.ldjb.uk/eurovision-2018-semi-2<p>Here are my thoughts on each of the acts in the second semi-final of 2018’s Eurovision Song Contest.</p>
<!-- more -->
<h3 id="1-norway">1. Norway</h3>
<p>Funky music with gimmicky visuals.</p>
<h3 id="2-romania">2. Romania</h3>
<p>Unpleasant song with creepy mannequins.</p>
<h3 id="3-serbia">3. Serbia</h3>
<p>Started off like a traditional Serbian song, which was promptly ruined when it became a pop song.</p>
<h3 id="4-san-marino">4. San Marino</h3>
<p>The dancing robots were cool. It’s a shame the song was painful to listen to.</p>
<h3 id="5-denmark">5. Denmark</h3>
<p>This definitely had Viking vibes and certainly was not bad. Though not outstanding either.</p>
<h3 id="6-russia">6. Russia</h3>
<p>I didn’t care for the song, but the staging and choreography was… pleasant.</p>
<h3 id="7-moldova">7. Moldova</h3>
<p>Moldova always puts on a good show, and this year was no different. The song was decent, but the choreography and staging was quite possibly the best of the competition so far this year. I liked how their outfits reflected the colours of the Moldovan flag.</p>
<h3 id="8-netherlands">8. Netherlands</h3>
<p>Pretty good song, though what was with all the crazy dancing?! It did not look pleasant.</p>
<h3 id="9-australia">9. Australia</h3>
<p>Australia is totally part of Europe, right? Anyway, the song was bland, but the staging and choreography were pretty good.</p>
<h3 id="10-georgia">10. Georgia</h3>
<p>A mediocre performance.</p>
<h3 id="11-poland">11. Poland</h3>
<p>My ears hurt… The lighting was nice, though.</p>
<h3 id="12-malta">12. Malta</h3>
<p>Weird, but I quite liked it!</p>
<h3 id="13-hungary">13. Hungary</h3>
<p>My ears hurt again…</p>
<h3 id="14-latvia">14. Latvia</h3>
<p>Dull.</p>
<h3 id="15-sweden">15. Sweden</h3>
<p>It was okay. Quite nice, visually.</p>
<h3 id="16-montenegro">16. Montenegro</h3>
<p>Another fairly boring song.</p>
<h3 id="17-slovenia">17. Slovenia</h3>
<p>Not very pleasant, but it had style, at least. Oh, and the fake technical issues were so cringeworthy…</p>
<h3 id="18-ukraine">18. Ukraine</h3>
<p>I quite liked it. Good performance.</p>
<p><strong>This live blog has now ended.</strong></p>
Leon Byford<p>Here are my thoughts on each of the acts in the second semi-final of 2018’s Eurovision Song Contest.</p>
Eurovision 2018, Semi-Final 12018-05-08T00:00:00Z2018-05-08T00:00:00Zhttps://blog.ldjb.uk/eurovision<p>Here are my thoughts on each of the acts in the first semi-final of 2018’s Eurovision Song Contest.</p>
<!-- more -->
<h3 id="1-azerbaijan">1. Azerbaijan</h3>
<p>Not a bad song, but not a particularly interesting one, either. Some nice staging and choreography, but not exceptional.</p>
<h3 id="2-iceland">2. Iceland</h3>
<p>Absolutely cringeworthy song. Nice suit, though.</p>
<h3 id="3-albania">3. Albania</h3>
<p>Not unpleasant.</p>
<h3 id="4-belgium">4. Belgium</h3>
<p>Weird song. Weird performance. Weird staging. I’m not sure I liked it, exactly, but it was interesting, at least.</p>
<h3 id="5-czech-republic">5. Czech Republic</h3>
<p>Not really my sort of music, but the performance was crazy enough that this has got to be my favourite of the evening so far.</p>
<h3 id="6-lithuania">6. Lithuania</h3>
<p>Boring song, but the way video clips of …seemingly random people… were overlayed on top of the live performance was quite interesting.</p>
<h3 id="7-israel">7. Israel</h3>
<p>Everything about this was insane. I… kinda liked it.</p>
<h3 id="8-belarus">8. Belarus</h3>
<p>Bland song, but I like what was done with the rose motif.</p>
<h3 id="9-estonia">9. Estonia</h3>
<p>Boring.</p>
<h3 id="10-bulgaria">10. Bulgaria</h3>
<p>Not bad. Not brilliant.</p>
<h3 id="11-fyr-macedonia">11. F.Y.R. Macedonia</h3>
<p>Yet another dull entry.</p>
<h3 id="12-croatia">12. Croatia</h3>
<p>Again, not terrible. But nothing special.</p>
<h3 id="13-austria">13. Austria</h3>
<p>Pleasant song. Interesting way they had the singer on a platform. Otherwise largely forgettable.</p>
<h3 id="14-greece">14. Greece</h3>
<p>Not outstanding, but it’s nice to have a non-English song for a change.</p>
<h3 id="15-finland">15. Finland</h3>
<p>A relatively tame but very competent entry. Probably one of my favourites.</p>
<h3 id="16-armenia">16. Armenia</h3>
<p>Back to the bland.</p>
<h3 id="17-switzerland">17. Switzerland</h3>
<p>Quite a decent song. Nice hat, too!</p>
<h3 id="18-ireland">18. Ireland</h3>
<p>Choreography was decent, but the song was very drab.</p>
<h3 id="19-cyprus">19. Cyprus</h3>
<p>One of the stronger acts of the evening. Song was alright, and the performance and choreography were good.</p>
<p><strong>This live blog has now ended.</strong></p>
Leon Byford<p>Here are my thoughts on each of the acts in the first semi-final of 2018’s Eurovision Song Contest.</p>
A look back at the Golden Age of Detective Fiction2018-05-03T00:00:00Z2018-05-03T00:00:00Zhttps://blog.ldjb.uk/golden-age-of-detective-fiction<p><em>I am a big fan of detective fiction and recently discussed the genre with some of my friends. The following is adapted from what I wrote in that discussion, and I am publishing it for posterity.</em></p>
<p>The 1920s and 1930s are termed the Golden Age of Detective Fiction, during which a great number of works from Agatha Christie and her contemporaries were published.</p>
<!-- more -->
<p>Detective fiction had gradually become increasingly popular in the previous decades, Arthur Conan Doyle’s Sherlock Holmes stories being notable examples of fiction created during this period.</p>
<p>However, whilst these stories featured detective characters, they would usually solve the mysteries using reasoning that is not possible for the reader to replicate based on the information provided by the written text.</p>
<p>And so, in the Golden Age of Detective Fiction, a new style of mystery story arose. The writer would create a game (actually the technical term) between themselves and the reader. Clues would be set out, and the reader would be challenged to solve the mystery for themselves using their knowledge and reasoning.</p>
<p>Essentially, the scenario is set out, the characters are introduced, then the crime (usually a murder) is committed. The detective character goes about the crime scene uncovering clues and red herrings alike. They question the suspects. Then, they sit everyone down and announce that they have solved the mystery.</p>
<p>With this announcement, the reader knows they have all the information they need to solve the mystery. Here, they stop reading, possibly going back to review the information. After some deliberation, the reader hopefully comes up with a solution, and so they resume reading. The detective presents their solution, and the reader confirms whether or not their solution was correct.</p>
<p>However, now came a problem. Although the mysteries were supposed to be solvable, some authors took to writing mysteries with solutions that were entirely unsatisfactory. For instance, sometimes the culprit was a secret twin brother, or the crime was caused by some obscure scientific phenomenon.</p>
<p>To counter these issues, Ronald Knox (a priest and prominent mystery writer) created his <a href="http://www.thrillingdetective.com/trivia/triv186.html">Decalogue</a>. These were ten commandments that mystery writers should follow to provide a satisfactory experience to the reader.</p>
<p>One thing worth noting: The use of the word “Chinaman” is frequently mistaken to be racist. In fact, Knox had realised that a number of mystery stories had a solution relating to a stereotype who would only appear at the very end. This was bad writing, hence that Decalogue entry.</p>
<p>Also notable is the American art critic who wrote detective fiction under the name S. S. Van Dine. He wrote an article entitled <a href="http://www.thrillingdetective.com/trivia/triv288.html">Twenty Rules for Writing Detective Stories</a>, which is frequently used along with Knox’s Decalogue when discussing mystery stories.</p>
<p>Detective fiction has developed since those days, and modern writers don’t necessarily pay these rules much attention anymore. However, in the last few decades, there has been a resurgence in Japan for the style of mystery stories that were prominent in the Golden Age. These “new orthodox” (shin-honkaku) stories recreate the experience of Golden Age detective fiction and once again invite the reader to solve their mysteries.</p>
Leon Byford<p><em>I am a big fan of detective fiction and recently discussed the genre with some of my friends. The following is adapted from what I wrote in that discussion, and I am publishing it for posterity.</em></p>
<p>The 1920s and 1930s are termed the Golden Age of Detective Fiction, during which a great number of works from Agatha Christie and her contemporaries were published.</p>
Thursday's elections are a bore2018-04-27T00:00:00Z2018-04-27T00:00:00Zhttps://blog.ldjb.uk/election-2018<p>This coming Thursday, 3<sup>rd</sup> May, <a href="https://www.yourvotematters.co.uk/elections-in-may-2018">England goes to the polls</a>. Or rather, London and a few other places do. Compared to the general election in May 2015, the various elections (including the London mayoral and London Assembly elections) in May 2016, the EU referendum in June 2016 and the general election in June 2017, this one is a bit of a bore.</p>
<!-- more -->
<p>The upcoming elections are mostly for local government, though there are a handful of mayoral elections. Previous such elections have had the benefit of preceeding major national votes and could be used as an indicator of how the various parties were performing. With the next general election some years away, that is not the case this time.</p>
<p>As such, interest in these elections seems to be the lowest I’ve seen in a while. Coverage of the elections by the media has been minimal, and campaigning in my local area has been almost non-existent. I get the impression a lot of people aren’t even going to bother paying the polling station a visit.</p>
<p>Whilst in the past, a fair number of parties have fielded candidates for my ward, save for one minor party that can only hope to gain a handful of votes, only the two largest parties have put forward candidates this time round. There aren’t even any independent candidates on the ballot paper. Much debate has been had about possible solutions, but I feel that it’s just not right to have such little choice.</p>
<p>Alas, whilst I may not like it, that is the choice we have. I plan on visiting my polling station and making my voice heard through the ballot paper, but I will do so without enthusiasm.</p>
Leon Byford<p>This coming Thursday, 3<sup>rd</sup> May, <a href="https://www.yourvotematters.co.uk/elections-in-may-2018">England goes to the polls</a>. Or rather, London and a few other places do. Compared to the general election in May 2015, the various elections (including the London mayoral and London Assembly elections) in May 2016, the EU referendum in June 2016 and the general election in June 2017, this one is a bit of a bore.</p>
<i>Umineko</i> solution website reimplemented in Markdown and Jekyll2018-04-19T00:00:00Z2018-04-19T00:00:00Zhttps://blog.ldjb.uk/umineko-solution<p>Back in 2014, I created a website to host a friend’s solutions to one of my all-time favourite mystery novels, Ryukishi07’s <em>Umineko no Naku Koro ni</em>.</p>
<p>The original solutions came in plain text, which I wanted to apply formatting to. Not realising there were existing solutions for it, I formatted the files with my own custom tags, and wrote a parser in PHP that would read the files and output the web pages.</p>
<p>The result was acceptable, though not everything was automated, so the process was a little tedious.</p>
<p>Four years later, I am now rather a fan of Markdown and Jekyll, which power this blog. These technologies can make creating static websites a real breeze. I decided to use my newfound knowledge about them to create an improved version of the website I had created before.</p>
<!-- more -->
<p>Converting the formatted text files into Markdown was a simple matter of running straightforward substitutions. I then created a template that would be applied to each Markdown file, to render them as a web page.</p>
<p>One aspect I had to get a little creative with was how to represent red text. <em>Umineko no Naku Koro ni</em> frequently makes use of red text to indicate statements the author has guaranteed can be taken as fact (this solves the problem a lot of mystery novels have where the possibility of an unreliable narrator makes it impossible to tell what the true facts of the case are). Of course, the solution website needed to use red text to quote these important statements too.</p>
<p>Markdown does not have native support for coloured text. kramdown (the Markdown converter used by Jekyll) supports the addition of classes to block elements, however I needed to do inline styling. I could have used pure HTML, but I did not fancy typing <code class="language-plaintext highlighter-rouge"><span class="red">foo</span></code> whenever I wanted to insert red text. I decided instead to hijack the emphasis style (which I didn’t need) instead.</p>
<p>In Markdown, when you place asterisks around a piece of text, it is emphasised. <code class="language-plaintext highlighter-rouge">*foo*</code> in Markdown becomes <code class="language-plaintext highlighter-rouge"><em>foo</em></code> in HTML, which appears as: <em>foo</em>. Most browsers render this in italics.</p>
<p>In <a href="https://github.com/ldjb/uminekosolution/blob/master/_layouts/default.html">my Jekyll template</a>, I used the following for the content placeholder:</p>
<div class="language-liquid highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{{</span><span class="nv">content</span><span class="err">
</span><span class="p">|</span><span class="nf">replace</span><span class="p">:</span><span class="w"> </span><span class="s1">'<em>'</span><span class="p">,</span><span class="w"> </span><span class="s1">'<span class="red">'</span><span class="err">
</span><span class="p">|</span><span class="nf">replace</span><span class="p">:</span><span class="w"> </span><span class="s1">'</em>'</span><span class="p">,</span><span class="w"> </span><span class="s1">'</span>'</span><span class="p">}}</span>
</code></pre></div></div>
<p>This meant that <code class="language-plaintext highlighter-rouge">*foo*</code> in Markdown would become <code class="language-plaintext highlighter-rouge"><span class="red">foo</span></code> in HTML, would would be displayed on the web page as: <span style="color: red;">foo</span>. I, of course, had to use CSS to style the <code class="language-plaintext highlighter-rouge">red</code> class to use red text:</p>
<div class="language-css highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nc">.red</span> <span class="p">{</span>
<span class="nl">color</span><span class="p">:</span> <span class="no">red</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>
<p>With that done, it was a simple matter of comitting my changes to a GitHub repository, and making the site available through GitHub Pages.</p>
<p>As a result of this exercise, the website is now easier to maintain, and I have had some useful practice with Jekyll at the same time.</p>
<ul>
<li><a href="https://ldjb.github.io/uminekosolution/"><em>Umineko</em> solution website</a></li>
<li><a href="https://github.com/ldjb/uminekosolution">GitHub repo</a></li>
</ul>
Leon Byford<p>Back in 2014, I created a website to host a friend’s solutions to one of my all-time favourite mystery novels, Ryukishi07’s <em>Umineko no Naku Koro ni</em>.</p>
<p>The original solutions came in plain text, which I wanted to apply formatting to. Not realising there were existing solutions for it, I formatted the files with my own custom tags, and wrote a parser in PHP that would read the files and output the web pages.</p>
<p>The result was acceptable, though not everything was automated, so the process was a little tedious.</p>
<p>Four years later, I am now rather a fan of Markdown and Jekyll, which power this blog. These technologies can make creating static websites a real breeze. I decided to use my newfound knowledge about them to create an improved version of the website I had created before.</p>
Hello, Jekyll Now!2018-04-11T00:00:00Z2018-04-11T00:00:00Zhttps://blog.ldjb.uk/hello-jekyll-now<p><em>This is an updated version of a previously published post.</em></p>
<p>Once again, I am attempting to write a blog. I’ve attempted to do so several times before, with varying degrees of success. Here are some of the services I’ve tried, what they did well, and what I didn’t like about them.</p>
<!-- more -->
<h3 id="wordpress">Wordpress</h3>
<p>This seems quite good initially. It’s free software (both as in freedom as well as beer) you can use on pretty much any web host that supports PHP and a MySQL database. It’s very customisable, so you can get your blog just how you like it.</p>
<p>However, in my experience, it’s far from lightweight, meaning you need a fairly beefy server if you don’t want your blog loading slow enough for it to be slightly annoying. There are ways you can speed things up, but that only helps so much.</p>
<p>A semi-official commercial blog hosting service is available at Wordpress.com, which is decent if you just want somewhere to write a blog, but a lot of features require payment and can be rather expensive.</p>
<h3 id="tumblr">Tumblr</h3>
<p>This is a completely centralised service with no self-hosting option (although you are able to use your own domain name for free). It’s relatively simple to use, but perhaps too simple. The formatting you can apply to blog posts are very limited (you can’t set text colour, for example), so you are very much constrained by the numerous limitations of the system.</p>
<p>Also, it seems more like a social network than a blogging platform. Whilst you can use it to write an ordinary blog, that seems to be far from the norm. One useful feature of Tumblr is you can quickly and easily reblog other people’s posts. This feature is so useful that the vast majority of posts on Tumblr appear to be reblogs.</p>
<p>I initially thought reblogs were great because I could reblog other people’s posts and share my thoughts on the matter. But whilst the system supports it, if you attempt to do so, you’ll soon face the wrath of an angry mob who insist that this is not the proper etiquette. Apparently one must not share one’s views underneath a reblog in the main section. Instead, one may do so in the post’s tags, which I’m fairly certain was not designed for this purpose.</p>
<p>And whilst I couldn’t care less what those people think, it did spur me to find a better alternative to Tumblr.</p>
<h3 id="medium">Medium</h3>
<p>Like Tumblr, this is a centralised service with no self-hosted option. However, it’s focused more on writing than on community. However, there is functionality to quite easily respond to other people’s posts. Formatting options are also very limited, and the design of your blog is very constrained. But that doesn’t really matter if you simply want to focus on your writing.</p>
<p>On the downside, although you used to be able to use a custom domain name, this is no longer possible. Also, the platform seems to be designed more for articles, rather than as a diary. I want a platform that can be used for all manner of different posts, from longer ones to just a few thoughts. So I didn’t find Medium to be completely suitable.</p>
<h3 id="ghost">Ghost</h3>
<p>This seems like decent software for running a blog. A hosted service is available for a fee, but aside from a free trial, there is no free tier. It is possible to self-host this software, and though I attempted to do so, it seemed like quite an involved process. Also, this seems to be primarily designed for journalism, not for diaries.</p>
<h3 id="mastodon">Mastodon</h3>
<p>I absolutely love this software. It’s more of an alternative to Twitter than a fully fledged blogging platform, but what it does, it does very well. I had an instance set up for a while, but due to its rapid development cycle, I had to frequently update the software. I ultimately could not justify the time required to maintain the server. But I would like to use Mastodon again in the future, so long as someone else is hosting it for me.</p>
<h3 id="github-gist">GitHub Gist</h3>
<p>Someone suggested I use GitHub Gist as a blog. I am a frequent user of GitHub Gist, and it’s a great service. It’s similar to other pastebin websites, but is designed with code in mind, although it does support Markdown. But my use of this service is the very reason why it is unsuitable for me to use it as a blog. Unless I were to create a brand new GitHub account, my blog posts would be mixed up with all my other Gists. There are third-party services that enable you to use GitHub Gist to host blog posts, but you have to access the blog through the third-party service. Also, they don’t seem to work too well, from what I can tell.</p>
<h3 id="my-own-software">My own software</h3>
<p>I tried making my own blogging software. How hard can it be, I thought. Well, much harder than I imagined, in fact. Unless you write your blog posts in HTML (and I certainly don’t want to have to do that), you need to use some other markup and convert to HTML or have some sort of WYSIWYG interface. You also have to figure out how to handle image uploads, storage and so on. There are just so many different things involved in blogging software. None of them are exactly complicated, but the sheer quantity of things to consider makes it a fair amount of work. Work that requires time. Time I didn’t have.</p>
<h3 id="livedoor">Livedoor</h3>
<p>I recently tried using a popular Japanese blogging service called Livedoor. It did a lot of the things I was looking for, but there were two main problems:</p>
<ul>
<li>
<p>By default, blogs on this platform do not use responsive web design. Therefore, blogs look and behave differently depending on whether the user is using a desktop PC or a smartphone. Some usability issues were pointed out to me about the default mobile theme, and whilst it might be possible to adjust some things, I would rather the blog have a clean design right out of the box so I do not have to go to excessive lengths to get something I feel is acceptable.</p>
</li>
<li>
<p>Since it’s a Japanese blogging service, the user interface is entirely in Japanese. Although this is not a problem for me, I have to consider the readers, the majority of which probably don’t know Japanese. Due to the language barrier, there is a high probability that visitors would have difficulty navigating the blog.</p>
</li>
</ul>
<h3 id="what-i-want-from-a-blogging-platform">What I want from a blogging platform</h3>
<p>Having used a number of different blogging platform, I considered what I actually want from one:</p>
<ul>
<li>Hosted – though I’d ideally like to host it myself, I know I just don’t have the time to maintain a live server in my free time, worry about uptime and so on. So I want someone else to host my blog.</li>
<li>Easy to use – I don’t want to spend a lot of time configuring my blog…</li>
<li>Customisable – …but I’d like to be able to make my blog feel like it’s mine.</li>
<li>Custom domain name – it’s my blog, so it should be served from a domain I control.</li>
<li>Easy export – if I ever want to leave the service, I want to be able to take my content with me, without resorting to scraping my own blog.</li>
<li>No community woes – I don’t want the existing community to have a go at me because I’m not using the service the way they’d like me to.</li>
<li>Clean design - the blog should look good right out of the box.</li>
<li>Does not require knowledge of non-English languages - I don’t want to make things difficult for visitors.</li>
</ul>
<p>After sharing these requirements with a friend, he suggested I try <a href="https://www.jekyllnow.com/">Jekyll Now</a>. I had tried using Jekyll before, but had found it a tad complicated, but Jekyll Now seems like a good way to quickly get a blog up and running, which can then be customised further. Jekyll Now is what is powering this blog, and I’ve been quite impressed with it so far. I have made some adjustments to the code, and I love how easy it is to make things feel the way you want them to.</p>
<p>There are, however, two slight concerns I have at the moment:</p>
<ul>
<li>
<p>There does not seem to be an easy way to compress or reduce the size of images I want to include in blog posts. Therefore, if I want to use an image that has a large file size, I would likely have to manually adjust the image before uploading it to the GitHub repo.</p>
</li>
<li>
<p>Lack of pagination – It seems that the front page will list every single blog post, which could mean a very long front page if I write enough posts. Jekyll does seem to have some sort of pagination feature, so that might be something I’ll look into.</p>
</li>
</ul>
<p>These are only minor concerns, however, and are things I might be able to address at a later time. At this time, however, I look forward to blogging using Jekyll Now.</p>
<h3 id="this-blog-what-is-it">This blog… what is it?</h3>
<p>Like all my previous endeavours, this will simply be a place where I’ll post whatever comes to mind. I might write about a topic that’s of interest to me, or I might simply post a link to an interesting website I found. I don’t really use social media anymore, so this will hopefully take the place of that.</p>
<p>There have been times when I’ve tended to write lengthy pieces of writing but only shared them with a small number of friends. I aim to post such pieces of writing here from now on.</p>
<p>I won’t spend a lot of time thinking about <em>how</em> to present what I want to say. I mostly just want to get my thoughts down. After all, this blog is actually primarily for me. But if you take interest in anything I have to say, then you’re more than welcome here.</p>
<p>Anyway, until next time~</p>
Leon Byford<p><em>This is an updated version of a previously published post.</em></p>
<p>Once again, I am attempting to write a blog. I’ve attempted to do so several times before, with varying degrees of success. Here are some of the services I’ve tried, what they did well, and what I didn’t like about them.</p>