<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Nick McCurdy on Medium]]></title>
        <description><![CDATA[Stories by Nick McCurdy on Medium]]></description>
        <link>https://medium.com/@nickserv?source=rss-cfb2e9361c11------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*oCGVaxTRT6tMAWnG0e2flQ.png</url>
            <title>Stories by Nick McCurdy on Medium</title>
            <link>https://medium.com/@nickserv?source=rss-cfb2e9361c11------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sat, 14 Nov 2026 17:49:44 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@nickserv/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com/" rel="hub"/>
        <item>
            <title><![CDATA[Simple Web Templating with Jekyll]]></title>
            <link>https://nickserv.medium.com/simple-web-templating-with-jekyll-b2189630c9ec?source=rss-cfb2e9361c11------2</link>
            <guid isPermaLink="false">https://medium.com/p/b2189630c9ec</guid>
            <category><![CDATA[web-development]]></category>
            <category><![CDATA[html]]></category>
            <category><![CDATA[jekyll]]></category>
            <category><![CDATA[markdown]]></category>
            <dc:creator><![CDATA[Nick McCurdy]]></dc:creator>
            <pubDate>Sat, 16 May 2020 05:14:47 GMT</pubDate>
            <atom:updated>2020-05-16T09:24:26.457Z</atom:updated>
            <content:encoded><![CDATA[<p>Jekyll is a well-supported static site generator that makes it easy to build websites using templates and themes, without having to duplicate HTML or add JS code to your frontend. In this tutorial, we’ll walk through some basic use cases of Jekyll’s templating system from scratch.</p><h3>Prerequisites</h3><p>Knowledge of HTML and command line is important for comprehension, but don’t worry if you don’t know Ruby, as most Jekyll sites don’t require custom Ruby code.</p><h3>Installing Jekyll</h3><p>Jekyll can be installed using gem, the package manager for the Ruby programming language. A version of Ruby comes preinstalled on macOS Catalina and earlier, but if you’re on a different system you may need to <a href="https://www.ruby-lang.org/en/downloads/">download Ruby manually</a>.</p><p>gem install jekyll</p><h3>Creating a layout</h3><p>While Jekyll has a default template (used via jekyll new ),we don’t need most of the features it offers, and it’s easier to understand how templating works by starting from scratch. You may want to create a directory first to keep your Jekyll site separate from other projects.</p><p>One common issue with writing static HTML sites by hand is the repetition in copying &lt;head&gt; tags, navbars, footers, scripts, and other common HTML between pages. Jekyll’s most basic form of templating is a layout file, which stores common HTML structures of related pages and inserts custom content inside each instance. All layouts go in the _layouts directory, any any page can use them.</p><p>Let’s create our main HTML template in _layouts/default.html:</p><pre>&lt;!DOCTYPE html&gt;<br>&lt;html lang=&quot;en&quot;&gt;<br>  &lt;head&gt;<br>    &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1&quot;&gt;<br>    &lt;meta charset=&quot;utf-8&quot;&gt;<br>    &lt;title&gt;My Jekyll Site&lt;/title&gt;<br>  &lt;/head&gt;<br>  &lt;body&gt;<br>    {{ content }}<br>  &lt;/body&gt;<br>&lt;/html&gt;</pre><p>{{ content }} is how we use the layout’s content variable, which contains the actual HTML content of each page as it’s built.</p><h3>Creating pages</h3><p>By default, Jekyll pages can be placed in the root of the site (or subdirectories) and can use HTML or Markdown content.</p><p>Let’s start with our default page, index.html, in our site’s root directory. This functions similarly to how a plain index file would without Jekyll, except it’s used within our default.html layout’s content variable. To tell Jekyll to use the default layout, we use default: layout in the file’s YAML metadata section (which is always in between two sets of ---).</p><pre>---<br>layout: default<br>---</pre><pre>&lt;h1&gt;My Jekyll Site&lt;/h1&gt;<br>&lt;p&gt;Hello, world!&lt;/p&gt;</pre><p>Alternatively, we can write the same content in index.md using Markdown to make content easier to read and write, without having to rely on an external content editor. Either way, any custom HTML is fully supported!</p><pre>---<br>layout: default<br>---</pre><pre># My Jekyll Site<br>Hello, world!</pre><h3>Running Jekyll</h3><p>Now to see the result of our work, we’ll need to run jekyll serve to start a local Jekyll server. By default, Jekyll will build and serve your site at <a href="http://localhost:4000/">http://localhost:4000/</a>, rebuilding after content changes.</p><h4>Production note</h4><p>While jekyll serve is convenient for development, it’s not an ideal server for production. Instead, jekyll build should be used to build Jekyll sites to static HTML files in _site. These static files don’t rely on a backend, so they should work with any existing static file server. Alternatively, you may find it easier to deploy your site with a static site host like <a href="https://pages.github.com/">GitHub Pages</a> (free for open source GitHub repositories) or <a href="https://www.netlify.com/">Netlify</a> (free for most sites and very flexible). For more in depth instructions and recommendations, check out the official <a href="https://jekyllrb.com/docs/deployment/">deployment guide</a>.</p><h3>Creating includes</h3><p>Reusing common template code between HTML files is useful, but sometimes we need to share common HTML within a page’s content. For that, we can put shared content in the _includes directory, which can then be referenced inside pages, layouts, or even other includes.</p><p>The basic code for using an include is {% include example.html %} . Similarly to the content variable in a layout, this will grab the contents of the referenced file, which in this case would be located at _includes/example.html . You can create as many as you like as long as the filename matches a file in _includes.</p><h3>Next steps</h3><p>We’ve covered the basics of what makes Jekyll useful for HTML sites written from scratch, but it can also help with more complex use cases. For example, if you want to create multiple pages and blog posts quickly, you can follow the <a href="https://jekyllrb.com/docs/">quickstart guide</a> to use the default theme, which sets up layouts, styles, and blogging features automatically. For a more in-depth overview of Jekyll’s most useful features, try out the <a href="https://jekyllrb.com/docs/step-by-step/01-setup/">step by step tutorial</a>, which covers custom metadata fields, data files, blogs, and deployment.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=b2189630c9ec" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Benefits of Functional Programming by Example]]></title>
            <link>https://nickserv.medium.com/benefits-of-functional-programming-by-example-76f1135b0b18?source=rss-cfb2e9361c11------2</link>
            <guid isPermaLink="false">https://medium.com/p/76f1135b0b18</guid>
            <category><![CDATA[javascript]]></category>
            <category><![CDATA[functional-programming]]></category>
            <dc:creator><![CDATA[Nick McCurdy]]></dc:creator>
            <pubDate>Mon, 18 Jun 2018 21:48:06 GMT</pubDate>
            <atom:updated>2020-05-26T14:08:03.986Z</atom:updated>
            <content:encoded><![CDATA[<p>Functional programming is a programming paradigm (technique) where functions are used together to return new values, rather than modifying variable values multiple times. Functions that always return the same result given the same inputs are said to be free of side effects, or pure. When code relies on changes to external variables, it can lose its purity because the same inputs no longer create the same outputs consistently. By finding purer ways to design programs, we can use functions in ways that won’t impact how other code works through side effects. This functional approach to programming often leads to more reusable, testable, and stable code.</p><p>Functional programming can be difficult to understand at first, especially due to its complex terminology. Rather than learning more theoretical aspects of functional programming, we’ll look at some examples of how to improve existing JavaScript code using functional programming (though these concepts can be applied to most languages).</p><h4>Iterating with forEach</h4><p>for loops are commonly used to iterate over collections in many languages including JavaScript. Let’s say we have an array of values we need to display in alerts individually.</p><pre>const beatles = [&#39;John&#39;, &#39;Paul&#39;, &#39;George&#39;, &#39;Ringo&#39;]<br>for (const beatle of beatles) {<br>  alert(beatle)<br>}</pre><p>This example can be simplified further with a newer JavaScript function called forEach.</p><pre>const beatles = [&#39;John&#39;, &#39;Paul&#39;, &#39;George&#39;, &#39;Ringo&#39;]<br>beatles.forEach(beatle =&gt; alert(beatle))</pre><p>Using forEach we can pass a function called an iteratee, which is called with each value of the array, giving us the same result. forEach is called a high order function because it takes a function as an argument. This is a powerful functional programming technique for composing functionality with small, simple functions. Because alert is a function and functions are also values in JavaScript, we can refer to the existing alert function instead of wrapping it in a new function.</p><pre>const beatles = [&#39;John&#39;, &#39;Paul&#39;, &#39;George&#39;, &#39;Ringo&#39;]<br>beatles.forEach(alert)</pre><h4>Creating new arrays with map</h4><p>One of the most common use cases for iterating over an array is modifying each item of the array in place. For example, let’s take an array of numbers and round them individually. We will also need to keep track of the current array index.</p><pre>const numbers = [1.4, 2.6, 3.14]<br>let index = 0<br>for (const number of numbers) {<br>  numbers[index] = Math.round(number)<br>  index++<br>}<br>numbers // [1, 3, 3]</pre><p>numbers is in the preferred format, but what if we’re only formatting numbers to make them easier to read, and we still need the decimal places for precise calculations? We’ve lost precision of our numbers, and any math code relying on the same array may have less accurate results. This is an unwanted side effect of rounding numbers in a for loop. Instead, we can take a more functional approach and create a new array instead of modifying the values in the original array, preventing subtle bugs and promoting reuse.</p><pre>const numbers = [1.4, 2.6, 3.14]<br>const rounded = []<br>for (const number of numbers) {<br>  rounded.push(Math.round(number))<br>}<br>rounded // [1, 3, 3]</pre><p>This is safer, but the nature of for loops still requires the side effect of pushing to the new rounded array. What if we could iterate over the array like with forEach, but create a new array by applying Math.round to every value? Fortunately, there’s a similar function called map which returns a new array based on the return values of the given function.</p><pre>const numbers = [1.4, 2.6, 3.14]<br>const rounded = numbers.map(Math.round) // [1, 3, 3]</pre><p>This gives us the result we want without modifying a temporary array variable. We could even replace Math.round with a different pure function, and the original numbers would remain the same. These functional changes have added a lot of safety and reusability to our code, without requiring us to write in a different functional programming language.</p><h4>Creating new values with reduce</h4><p>The map function is handy for updating array values individually, but we often need to calculate a value that isn’t an array of the same length as the original. For example, let’s add numbers in an array together.</p><pre>let sum = 0<br>const numbers = [1, 2, 3, 4]<br>numbers.forEach(number =&gt; sum += number)<br>sum // 10</pre><p>We need to modify our sum here to add each number to it, but there’s a more pure way to combine these values without creating side effects in a temporary sum variable. Like the functions we’ve tried so far, reduce iterates over each value of an array, except it lets us build any new value (not just an array) one step at a time. The reduce function works by passing a special value called an accumulator along with each value of the original array, which is replaced by the return value of our given function after iterating over each value.</p><pre>const numbers = [1, 2, 3, 4]<br>const sum = numbers.reduce((accumulator, number) =&gt; accumulator + number) // 10</pre><p>We can combine our numbers into a new accumulator value individually, without modifying the original array of numbers. Here our iteratee function is called a reducer because it takes two values (the previous accumulator and the current number) and reduces (combines) them into a single value, our new sum. The initial value of accumulator defaults to the first array value (1 in this case), so reduce will add each number in sequence to accumulator until we reach our final result. This initial value makes sense for a sum, but sometimes we need to change the initial value too. Let’s build a new array by doubling each of its numbers.</p><pre>const numbers = [1, 2, 3, 4]<br>const doubled = numbers.reduce((accumulator, number) =&gt; accumulator.concat(number * 2), []) // [2, 4, 6, 8]</pre><p>Along with our reducer function, we also pass add a second argument which overrides the initial accumulator to an empty array (instead of the first item, 1). This is necessary because you can’t call concat on a number, so we need to wrap the first number in an array like all the others. This end result is similar to map, which we just reimplemented ourselves by concatenating each number one at a time. map is an example of a function that can be replaced with reduce, but functional code is often easier to read with map.</p><pre>const numbers = [1, 2, 3, 4]<br>const doubled = numbers.map(number =&gt; number * 2) // [2, 4, 6, 8]</pre><h4>Filtering arrays with filter</h4><p>Let’s write a reducer that concatenates only even numbers into a new array.</p><pre>const numbers = [1, 2, 3, 4]<br>const isEven = number =&gt; number % 2 === 0<br>const even = numbers.reduce((accumulator, number) =&gt; isEven(number) ? accumulator.concat(number) : accumulator, []) // [2, 4]</pre><p>As powerful as reduce is, there are other simplified high order functions besides map. The filter function also iterates over array values, but instead of returning a new accumulator for each value, it only concatenates values into the new array if a certain condition is truthy. Let’s use filter to get even numbers from our array using our isEven function. isEven is an example of a predicate, a function that takes a value and returns a boolean.</p><pre>const numbers = [1, 2, 3, 4]<br>const isEven = number =&gt; number % 2 === 0<br>const even = numbers.filter(isEven) // [2, 4]</pre><h4>Testing conditions with some and every</h4><p>Sometimes we want to use predicates to test the values in existing arrays, without creating new arrays. some and every also take predicates, but they return true if our predicate is true for some (any) or every (all) values of the array respectively.</p><pre>const numbers = [1, 2, 3, 4]<br>const isEven = number =&gt; number % 2 === 0<br>const someEven = numbers.some(isEven) // true<br>const everyEven = numbers.every(isEven) // false</pre><p>We could alternatively use a for loop with new variables or even reduce, but these simpler functions clarify the intent of our code while avoiding the side effects of a for loop.</p><h4>Function composition</h4><p>Sometimes a more complex reducer can be simplified by calling multiple pure high order functions together. Let’s combine some of the concepts we reviewed and square all the even numbers in our array.</p><pre>const numbers = [1, 2, 3, 4]<br>const isEven = number =&gt; number % 2 === 0<br>const square = number =&gt; Math.pow(number, 2)<br>const evenSquared = numbers.reduce((accumulator, number) =&gt; isEven(number) ? accumulator.concat(square(number)) : accumulator, []) // [4, 16]</pre><p>Our reducer is combining two concepts: filtering if number is even and mapping number to its square. This sounds a lot like what filter and map already do, but because they receive and return new arrays, we can use them together. Combining smaller functions together to build bigger functions is called function composition.</p><pre>const numbers = [1, 2, 3, 4]<br>const isEven = number =&gt; number % 2 === 0<br>const square = number =&gt; Math.pow(number, 2)<br>const evenSquared = numbers.filter(isEven).map(square) // [4, 16]</pre><p>Our newer functional code is easier to read, while still taking advantage of our isEven predicate and our square iteratee. Like any effective software design practice, functional programming lets us separate functionality into simpler units of code (like our functions) that are easier to reuse and test in isolation.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=76f1135b0b18" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>