<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Jason Steinhauser</title>
    <description>The latest articles on DEV Community by Jason Steinhauser (@jdsteinhauser).</description>
    <link>https://dev.to/jdsteinhauser</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F34531%2F90fce97c-49f0-443c-8f67-fc9544b2d623.jpeg</url>
      <title>DEV Community: Jason Steinhauser</title>
      <link>https://dev.to/jdsteinhauser</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/jdsteinhauser"/>
    <language>en</language>
    <item>
      <title>Field Guide to Merging Codebases</title>
      <dc:creator>Jason Steinhauser</dc:creator>
      <pubDate>Sat, 15 Jan 2022 20:31:09 +0000</pubDate>
      <link>https://dev.to/jdsteinhauser/field-guide-to-merging-codebases-bb8</link>
      <guid>https://dev.to/jdsteinhauser/field-guide-to-merging-codebases-bb8</guid>
      <description>&lt;p&gt;Congratulations, your company has just acquired another smaller company to expand your product line! Pop the champagne, dress up the puppies, eat so much cake that you wake up full of regret! Now that the dust has settled and you've met your new teammates, you all come to the sudden realization that...&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--wK1pKO5Z--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/63paabnw2vl2oy28xkdm.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--wK1pKO5Z--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/63paabnw2vl2oy28xkdm.jpeg" alt="We have to... merge our codebases?" width="700" height="449"&gt;&lt;/a&gt;&lt;/p&gt;
Oh. No.



&lt;p&gt;Your out-of-date documentation? It'll be on full display to a new group of developers. That important business logic you wrote 2 years ago with the &lt;code&gt;TODO: Write some tests&lt;/code&gt; above it? Better scramble to get some in there! The spreadsheet that product shares around for features, well... you get the idea. And that doesn't even start to cover what the other folks have stewing in their code cauldron.&lt;/p&gt;

&lt;p&gt;Never fear! Many have been there before you. Many are currently in the middle of their own jungle of curly braces. When I joined Terminus about a year ago, they had already acquired 3 different companies and have since purchased another 2. Your mileage may vary, but here are some ways we've worked our way through the proverbial jungle.&lt;/p&gt;

&lt;h2&gt;
  
  
  Let's Talk
&lt;/h2&gt;

&lt;p&gt;After a merger the product team, investors, and executives will want to see progress made towards merging the companies' product offerings. This is a good thing for the business! However, you're still going to have figure out how to talk - in just about every sense of the word.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--SiaC4WdH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://static.wikia.nocookie.net/starcraft/images/5/5e/1._Archon_Default.jpg/revision/latest/scale-to-width-down/1000%3Fcb%3D20200609022439" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--SiaC4WdH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://static.wikia.nocookie.net/starcraft/images/5/5e/1._Archon_Default.jpg/revision/latest/scale-to-width-down/1000%3Fcb%3D20200609022439" alt="You'll get there!" width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;
Final form of fully merged products



&lt;h3&gt;
  
  
  Documentation
&lt;/h3&gt;

&lt;p&gt;Documentation is a four-letter word, I know. But when you start interfacing with OtherCorp's whizzbang analytics dashboard, you're going to wish they'd documented it.&lt;/p&gt;

&lt;p&gt;If you haven't documented your services yet... you're not alone! But to make it easier for you to work on your new buddies' services (or vice versa), you'll need to have things documented. Whether it's via a wiki (we have one conveniently named &lt;code&gt;man&lt;/code&gt;) or through testing, you'll want to have an understood method of documentation.&lt;/p&gt;

&lt;h3&gt;
  
  
  Lingua Franca
&lt;/h3&gt;

&lt;p&gt;When you're smashing together multiple products' codebases, you're likely going to have several different languages floating around. At Terminus, we've had/still have services written in Ruby, Groovy, Elixir, Go, Node (both JS and TS), Angular, and React. They all have their purpose and their reasons for being used, but moving forward you've gotta be able to have folks work across different repositories. People have their pet languages for sure. But people who have only ever written JS/TS are not going to want to "pick up Haskell" for that one service that Kelly wrote before leaving for AnotherCorp. (This is just an example, not trying to pick on JS/TS devs!)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Tob59Lpv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://www.ethann.com/wp-content/uploads/2016/01/common-language.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Tob59Lpv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://www.ethann.com/wp-content/uploads/2016/01/common-language.jpg" alt="So close!" width="600" height="300"&gt;&lt;/a&gt;&lt;/p&gt;
If only they spoke the same way..



&lt;p&gt;As much as it pains me to say it, coming up with a common set of languages to use is going to pay dividends in the end. I've worked on projects in different areas of our platform, and because they're in languages that are common across our product suite (and sometimes documented and tested well!) I spent minimal time ramping up to contribute to those services. It doesn't feel like it while you're adjusting, but it really does make things better in the long run.&lt;/p&gt;

&lt;h2&gt;
  
  
  Infrastructure
&lt;/h2&gt;

&lt;p&gt;So we've identified the end goal: merging our codebases into a more cohesive platform! But where do we start? Just like with constructing a house, we need to have a good foundation to build everything on. We need... infrastructure! &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--IDKrPPab--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/http://theinfrastructureshow.com/images/51.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--IDKrPPab--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/http://theinfrastructureshow.com/images/51.jpg" alt="Probably best to avoid this." width="502" height="324"&gt;&lt;/a&gt;&lt;/p&gt;
Okay, so hopefully not like this.



&lt;p&gt;You've got an AWS account... for most of your stuff. You've got that one Heroku experiment that too that we try not to mention often. And now your new coworkers are bringing all of their cloud accounts as well! I swear, if they even &lt;em&gt;mention&lt;/em&gt; on prem hardware...&lt;/p&gt;

&lt;p&gt;The end goal is more than likely going to be a single cloud provider account. So how do you get there? It's not going to be an easy or short-term fix. Environment variables to different services are scattered around everywhere. Identity and Access Management (IAM) roles and policies exist in more places than you realize. Let's make sense of all this.&lt;/p&gt;

&lt;h3&gt;
  
  
  Security
&lt;/h3&gt;

&lt;p&gt;You don't want to inadvertently put your users' data at risk &lt;em&gt;especially&lt;/em&gt; now that you're growing as a company! If I haven't hammered it home enough yet, security will have to be something people agree on. How should we encrypt data at rest? How do we protect services that are meant for internal use from outside snooping? Whether that's configured with IAM roles/policies, cordoned off in different VPCs/VPNs, use of some sort of protocol or token-based security (JWTs for example), work together to figure out the best (possibly not the easiest) way to keep data secure with minimal impact to performance.&lt;/p&gt;

&lt;h3&gt;
  
  
  Infrastructure as Code
&lt;/h3&gt;

&lt;p&gt;In the beginning, you and/or your founders were probably tinkering around with the cloud, learning new concepts, and breaking all the things. This is perfectly normal in the startup world, but eventually it gets to be unwieldy.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ieJPwEnw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/http://2.bp.blogspot.com/-YqNopG6VOF0/UDTnM8Dqm5I/AAAAAAAAIkQ/V0MpSDQBqiY/s1600/wd-duct-tape.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ieJPwEnw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/http://2.bp.blogspot.com/-YqNopG6VOF0/UDTnM8Dqm5I/AAAAAAAAIkQ/V0MpSDQBqiY/s1600/wd-duct-tape.jpeg" alt="I am guilty of this." width="500" height="500"&gt;&lt;/a&gt;&lt;/p&gt;
My first cloud development toolkit



&lt;p&gt;Now that you're joining forces with others, you'll want to keep track of things in a more programmatic way. Using an Infrastructure as Code tool such as &lt;a href="https://www.terraform.io"&gt;Terraform&lt;/a&gt; is a great way to express platform configuration in an understandable fashion. You can import existing infrastructure into Terraform for configuration management, and when you want to modify your architecture you can see what will change before you pull the metaphorical trigger. And with IaC, you can version control all of your infrastructure changes in Git just like application code!&lt;/p&gt;

&lt;h3&gt;
  
  
  Tooling
&lt;/h3&gt;

&lt;p&gt;Everyone monitors differently. Papertrail, New Relic, Datadog, Kibana, a shell into k8s pods... I've seen LOTS of ways that people monitor things, but y'all are going to have to figure out a unified way to keep an eye on services. If there's one thing I've learned, it's that people do &lt;em&gt;not&lt;/em&gt; want to check more tools than they have to. Settling on one monitoring platform (if possible) will take effort, but in the end it'll make everyone's life easier.&lt;/p&gt;

&lt;p&gt;CI/CD pipelines are another thing that people can be strongly opinionated about. I'll just echo here what I'd said about monitoring - there's a lot of ways to do the things. Bring everyone together to work out a common solution that everyone hates the least. Keeping stuff the same across the now singular organization will help folks move around as needed to different projects more easily.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;So what's the big takeaway here? You're going to need common practices, common definitions, and common languages. It will take time to do it, but do as much of it up front as you can. Product will still want to ship new features and that's fine; you can do that while integrating everything together.&lt;/p&gt;

&lt;p&gt;Our CEO has said this multiple times in regards to business strategy, but it applies to engineering as well: "Sometimes you have to slow down to speed up." When you take the time to blend together up front (or at least start executing a plan to unify processes 'n' such), it's going to help you to execute more quickly in the future.&lt;/p&gt;

&lt;p&gt;I hope you enjoyed this! If you have experience with uniting codebases post-M&amp;amp;A, I'm happy to hear your comments below!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--aT349q6u--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://pbs.twimg.com/profile_images/1462591244211789827/yX1Rws2f_400x400.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--aT349q6u--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://pbs.twimg.com/profile_images/1462591244211789827/yX1Rws2f_400x400.jpg" alt="Fully formed platform" width="400" height="400"&gt;&lt;/a&gt;&lt;/p&gt;
Artist's rendition of your new, unified platform



</description>
      <category>career</category>
      <category>startup</category>
    </item>
    <item>
      <title>"Oh I Can Do That!" - How Everyone Is An "Expert"</title>
      <dc:creator>Jason Steinhauser</dc:creator>
      <pubDate>Wed, 17 Feb 2021 14:51:50 +0000</pubDate>
      <link>https://dev.to/jdsteinhauser/oh-i-can-do-that-how-everyone-is-an-expert-10bd</link>
      <guid>https://dev.to/jdsteinhauser/oh-i-can-do-that-how-everyone-is-an-expert-10bd</guid>
      <description>&lt;p&gt;One of the upper level executives at my company (Terminus Software, and shameless plug: &lt;a href="https://terminus.com/about-us/#careers"&gt;we're hiring software engineers!&lt;/a&gt;) recently posted this on Twitter:&lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1361866448562438144-102" src="https://platform.twitter.com/embed/Tweet.html?id=1361866448562438144"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1361866448562438144-102');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1361866448562438144&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;p&gt;And I mean, he's not wrong in that everyone seems to think they could be an "actual marketer". However, I've had many people tell me that they can do something better than I've done things all throughout my career. Sometimes they had good advice and prefaced it this way ("have you considered &lt;code&gt;x&lt;/code&gt;?" when I actually hadn't), but most akin to "I saw this Python tutorial on how to do a weather service and you need to do that... but for &lt;em&gt;your&lt;/em&gt; project" 😒.&lt;/p&gt;

&lt;p&gt;And I get it why Sangram has his viewpoint - he's been in marketing for nearly 2 decades, and he's probably heard "marketing is easy"  constantly. And people seem to think marketing is magic, because marketers' worth is hard to quantify without solid data. When I ran a local escape room with my wife, I tried my hand at marketing. It turns out... I had no idea what I was doing. WTH are impressions? I ran TV and radio spots. How effective were they? I have no idea because I didn't know how to get data to see which marketing channels were working for me. And as you can undoubtedly tell, I decided to continue a software career.&lt;/p&gt;

&lt;p&gt;Hell, I've even done it too. While I was running that escape room, I was also writing the software to interface with the electronically-controlled puzzles in our room, as well as the monitors in the rooms, and the game masters' consoles. I definitely thought, "I've written software; I can make good UIs!" As it turns out, I had to learn a lot before I could "make good UIs". I'm still not great at it, but I'm passable!&lt;/p&gt;

&lt;p&gt;When I dabbled in standup comedy, I took classes on how to craft jokes, and then expand those into bigger bits, and then into solid timed sets. That never stopped people from saying "Hey, I've got a joke idea for you!" 🧐 Someone outside of your field will inevitably tell you they can do your job.&lt;/p&gt;

&lt;p&gt;So... what stories have you got? I want to hear them below!&lt;/p&gt;

</description>
      <category>discuss</category>
    </item>
    <item>
      <title>Modern C++ Isn't Scary</title>
      <dc:creator>Jason Steinhauser</dc:creator>
      <pubDate>Fri, 16 Aug 2019 16:58:06 +0000</pubDate>
      <link>https://dev.to/jdsteinhauser/modern-c-isn-t-scary-7ai</link>
      <guid>https://dev.to/jdsteinhauser/modern-c-isn-t-scary-7ai</guid>
      <description>&lt;p&gt;C++ has a reputation for being an obtuse, antiquated language that is only for neckbeards and angry professors. Sure, it's fast, but why do you want to learn all of that nasty overhead just for a little more speed? And I love my package manager and tooling! Does C++ have anything modern?&lt;/p&gt;

&lt;p&gt;This is exactly how I felt after every time I looked at C++ or worked on a C++ project since I graduated college. However, I've had to write a considerable amount of C++ recently and I have to say...&lt;/p&gt;

&lt;p&gt;C++17 ain't your dad's C++.&lt;/p&gt;

&lt;h1&gt;
  
  
  Less horrendous syntax
&lt;/h1&gt;

&lt;p&gt;C++ is notorious for its horrendous syntax. However, starting with C++11 the syntax has gradually been made much more appealing. A lot of it involves the use of the keyword &lt;code&gt;auto&lt;/code&gt;. You can now use range-based &lt;code&gt;for&lt;/code&gt; loops like in Python and C# (technically &lt;code&gt;foreach&lt;/code&gt;):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="mf"&gt;1.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;2.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;3.0&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;auto&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;endl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;&amp;amp;&lt;/code&gt; after &lt;code&gt;auto&lt;/code&gt; signifies that we don't want to make a copy of the item in the array (or &lt;code&gt;std::vector&lt;/code&gt; or any other iterable collection).&lt;br&gt;
Auto can be used to destructure &lt;code&gt;std::tuple&lt;/code&gt;s and &lt;code&gt;std::pair&lt;/code&gt;s, as well as &lt;code&gt;struct&lt;/code&gt;s and arrays! If we use our array above, we can destructure the whole thing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;auto&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// auto [a, b] won't compile because our array is length 3&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can use it in &lt;code&gt;for&lt;/code&gt; loops on &lt;code&gt;std::map&lt;/code&gt;s as well:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="k"&gt;auto&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;dictionary&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Destructuring tuples works the same way:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;tuple&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;double&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="mf"&gt;4.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"GPA"&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="k"&gt;auto&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;label&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That tuple looks to be defined in standard, verbose C++. Well, they've got a fix for that too...&lt;/p&gt;

&lt;h1&gt;
  
  
  Template Parameter Inference
&lt;/h1&gt;

&lt;p&gt;If the type can be inferred in a template type, then there is no need to specify the types! I can rewrite the &lt;code&gt;std::tuple&lt;/code&gt; definition above as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;tuple&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="mf"&gt;4.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;R"(GPA)"&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="c1"&gt;// or better yet&lt;/span&gt;
&lt;span class="k"&gt;auto&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;tuple&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="mf"&gt;4.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;R&lt;/span&gt;&lt;span class="s"&gt;"(GPA"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;R"(...)"&lt;/code&gt; creates a string literal instead of a character array. This is considerably less bulky than previous iterations of the C++ language standard, and it makes type signatures a lot less irritating. You'll still have to fully qualify the type on function return types, but you can &lt;code&gt;auto&lt;/code&gt; the pain away everywhere else.&lt;/p&gt;

&lt;p&gt;The language standard committee has also added &lt;code&gt;std::tie&lt;/code&gt; to integrate with pre-existing code as well, where you want to tie values as output of a function to variables that already exist. The language has really made it &lt;strong&gt;MUCH&lt;/strong&gt; nicer than it used to be regarding functions that have multiple output values, and I'm quite satisfied with it.&lt;/p&gt;

&lt;h1&gt;
  
  
  Literals
&lt;/h1&gt;

&lt;p&gt;C++ has long had some literals for integer and floating point types (i.e., defining zero as an unsigned long as &lt;code&gt;0UL&lt;/code&gt; or as a float as &lt;code&gt;0.0f&lt;/code&gt;). In C++11/14, have expanded the scope of literals to include booleans, strings (both UTF-8 &lt;em&gt;and&lt;/em&gt; UTF-16), units of time (&lt;code&gt;42ns&lt;/code&gt; is the same as &lt;code&gt;std::chrono::nanoseconds(42)&lt;/code&gt;), and a lot more! There is also the option for &lt;a href="https://en.cppreference.com/w/cpp/language/user_literal"&gt;user-defined literals&lt;/a&gt;, and the documentation is pretty solid. This has been one of the more exciting features for me personally!&lt;/p&gt;

&lt;h1&gt;
  
  
  More platform independent libraries
&lt;/h1&gt;

&lt;p&gt;Several things were classically OS-specific in C++; there were no overarching abstractions. Thankfully, in C++11 and beyond that has been remedied.&lt;/p&gt;

&lt;p&gt;For example, if you wanted to sleep the current thread for 5 seconds, in grandpa's C++ you'd write:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;unistd.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;sleep_func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;unsigned&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;milliseconds&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;usleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;milliseconds&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt;

&lt;span class="kt"&gt;unsigned&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;sleep_seconds&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;sleep_func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sleep_seconds&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and that would work for *nix environments &lt;strong&gt;only&lt;/strong&gt;. If you wanted to do sleep for some unit other than microseconds (the Unix implementation's unit of measure), you would have to do the conversion yourself. While not difficult, it's still prone to human error. If you wanted to do it on a specific thread... well, that's a whole different story. In C++11, you can use the &lt;code&gt;std::chrono&lt;/code&gt; library, with a &lt;a href="https://en.cppreference.com/w/cpp/header/chrono"&gt;variety of clocks&lt;/a&gt;, as well as the &lt;code&gt;std::thread&lt;/code&gt; library for thread-specific tasks.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;chrono&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;thread&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;sleep_func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;chrono&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;duration&lt;/span&gt; &lt;span class="n"&gt;duration&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;this_thread&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;sleep_for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;duration&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt;

&lt;span class="k"&gt;auto&lt;/span&gt; &lt;span class="n"&gt;sleep_seconds&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;sleep_func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;chrono&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;seconds&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sleep_seconds&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There are several pre-defined durations in the &lt;code&gt;std::chrono&lt;/code&gt; namespace also, so that it is incredibly clear to see how the units of your time span, and all the conversions are handled by the compiler. Less work for us!&lt;/p&gt;

&lt;p&gt;They've also &lt;strong&gt;finally&lt;/strong&gt; implemented a &lt;a href="https://en.cppreference.com/w/cpp/filesystem/path"&gt;filesystem&lt;/a&gt; abstraction in C++17! It was experimental in C++14 but officially became a part of the language standard with the last release.&lt;/p&gt;

&lt;h1&gt;
  
  
  Creating objects in template classes
&lt;/h1&gt;

&lt;p&gt;In the "good ol' days" of C++, using template collections was &lt;strong&gt;super annoying&lt;/strong&gt;. If you wanted to push something to the back of a queue, for instance, you would have to create the object and then pass a copy of that object into the queue.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;vector&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;thing&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;things&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="n"&gt;thing&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"foo"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
   &lt;span class="n"&gt;things&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;emplace_back&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A lot of template classes now have functions that would copy previously that have an &lt;code&gt;Args&amp;amp;&amp;amp;&lt;/code&gt;-style implementation now so that a new object of that type can be created in place in the template class! That looks something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;vector&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;thing&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;things&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;things&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;emplace_back&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"foo"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This saves some copying overhead and speeds things up as well, and discourages the use of pointers in collections (when appropriate).&lt;/p&gt;

&lt;h1&gt;
  
  
  Better Pointers
&lt;/h1&gt;

&lt;p&gt;Let's face it: dealing with raw pointers SUCKS. Allocating memory. Freeing memory. Creating a pointer in one scope and assuming ownership transfers to a new scope later. All of these cases require a lot of ceremony, can cause memory leaks, and require a lot of mental overhead to make sure you don't cause memory leaks. Thankfully, C++11 brought different pointer types developed in the Boost library into the language specification.&lt;/p&gt;

&lt;h2&gt;
  
  
  Unique Pointers
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;std::unique_ptr&amp;lt;T&amp;gt;&lt;/code&gt; can only ever be referenced by one object. If ownership needs to be transferred to a different scope (but still only maintain one copy), std::move can be used to transfer ownership. This can be useful in factories, or any other time that you might want to create something and pass its ownership to another object. For example, you may want to create a stream of bytes coming off a &lt;code&gt;Socket&lt;/code&gt; and pass the ownership of that data to a requesting object.&lt;/p&gt;

&lt;h2&gt;
  
  
  Shared Pointers
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;std::shared_ptr&amp;lt;T&amp;gt;&lt;/code&gt; are officially one of my favorite things in C++. If some point needs to be referenced by multiple objects (like, say, a Singleton for a Websocket), in old school C++ you would've created a raw pointer to that object and destroy it on cleanup or after its last use... &lt;em&gt;hopefully&lt;/em&gt;. Raw pointers are one of the single biggest contributors to memory leaks in C++. They probably rank up there with NULL pointers as a billion dollar mistake.&lt;/p&gt;

&lt;p&gt;Thankfully, shared pointers are now a thing and widely accepted in the C++ community. When copied (and they should &lt;strong&gt;always&lt;/strong&gt; be copied, not passed by reference or pointer), they increment an internal reference count. When these copies are destroyed, the reference count is decremented. When the reference count reaches zero, then the object is destroyed and the memory is freed up. No more manual memory management hassle! Yay! You can still shoot your foot off with shared pointers if you don't strictly copy them, but there's a better safety mechanism available now over shared, raw pointers, IMHO.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;Though it still feels like it has more syntax than necessary, C++ is not as bad as I remembered it being. I've enjoyed the past 4 months developing in it on a daily basis much more than I have in past jobs. If you check it out again, hopefully it won't be as scary to you either!&lt;/p&gt;

&lt;p&gt;Happy coding!&lt;/p&gt;

</description>
      <category>cpp</category>
    </item>
    <item>
      <title>Congressional District-based Encoding</title>
      <dc:creator>Jason Steinhauser</dc:creator>
      <pubDate>Mon, 05 Aug 2019 01:23:08 +0000</pubDate>
      <link>https://dev.to/jdsteinhauser/congressional-district-based-encoding-4a6</link>
      <guid>https://dev.to/jdsteinhauser/congressional-district-based-encoding-4a6</guid>
      <description>&lt;p&gt;&lt;strong&gt;Note: this project has no political basis. I did this just because I thought it would be funny.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;My Twitter-verse was all aflutter this late last week due to the release of a &lt;a href="https://twitter.com/UglyGerry/status/1153661354462588929"&gt;typeface based on gerrymandering&lt;/a&gt;. Neutral of its possible perceived political implications, I thought this was hysterical, and that it warranted having its own encoding.&lt;/p&gt;

&lt;h1&gt;
  
  
  Introducing Gerry Cipher!
&lt;/h1&gt;

&lt;p&gt;Gerry Cipher is basically translating Base64 encoding into congressional districts. This was interesting in a couple of regards:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Some letters were formed by combining two districts&lt;/li&gt;
&lt;li&gt;M and W were the same district, just mirrored&lt;/li&gt;
&lt;li&gt;There were no districts provided for numerals&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To address converting the district-based encodings to upper-/lowercase letters, it was fairly trivial: if a letter was comprised of one district, the uppercase encoding had uppercase letters, and likewise for lowercase. If the letter was a composite, then the left/upper district was the uppercase encoding, and the right/bottom district was the lowercase encoding. In the case of M/W being mirrored (NY's 8th district), the encodings are mirrored (&lt;code&gt;NY08&lt;/code&gt;/&lt;code&gt;80YN&lt;/code&gt; and &lt;code&gt;ny08&lt;/code&gt;/&lt;code&gt;80yn&lt;/code&gt; for &lt;code&gt;M&lt;/code&gt;/&lt;code&gt;W&lt;/code&gt; and &lt;code&gt;m&lt;/code&gt;/&lt;code&gt;w&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;Addressing numerals was something not covered by the Ugly Gerry typeface. To this effect, I used the ten largest congressional districts by area. Since I was using Base64 encoding as a basis, there was the matter of handling &lt;code&gt;+&lt;/code&gt; and &lt;code&gt;/&lt;/code&gt;. I determined that the two longest-running non-voting delegations would be used - Puerto Rico (PR01) and Washington D.C. (DC01).&lt;/p&gt;

&lt;h1&gt;
  
  
  What's Next?
&lt;/h1&gt;

&lt;p&gt;It's just a silly little project, and I may or may not translate it to other languages just to propagate the silliness. I will code up... er... decoding... soon as well. I welcome you to check it out!&lt;/p&gt;

&lt;p&gt;Happy coding!&lt;/p&gt;

</description>
      <category>elixir</category>
      <category>showdev</category>
    </item>
    <item>
      <title>Wormhole - Data Collection Cheat Sheet and Library in 4 Languages</title>
      <dc:creator>Jason Steinhauser</dc:creator>
      <pubDate>Mon, 25 Feb 2019 21:09:02 +0000</pubDate>
      <link>https://dev.to/jdsteinhauser/wormhole---data-collection-cheat-sheet-and-library-in-4-languages-56de</link>
      <guid>https://dev.to/jdsteinhauser/wormhole---data-collection-cheat-sheet-and-library-in-4-languages-56de</guid>
      <description>&lt;p&gt;During the &lt;a href="https://adventofcode.org" rel="noopener noreferrer"&gt;Advent of Code&lt;/a&gt; this past year, I was trying to enhance my knowledge of Elixir, as well as just functional programming in general. There were times where I found a function that most other languages I used didn't have an analogous function (a glaringly obvious one being &lt;a href="https://hexdocs.pm/elixir/Enum.html#reduce_while/3" rel="noopener noreferrer"&gt;&lt;code&gt;Enum.reduce_while&lt;/code&gt;&lt;/a&gt;), and other times where I was writing functions I'd used often in other languages (Clojure's &lt;a href="http://clojuredocs.org/clojure.core/frequencies" rel="noopener noreferrer"&gt;&lt;code&gt;frequencies&lt;/code&gt;&lt;/a&gt; would've been mighty handy!). I finally decided to bite the bullet and try to create a list of collection manipulation functions I used often in other languages, implement them in others I've learned/currently trying to learn, and discover new functions that I wouldn't want to live without!&lt;/p&gt;

&lt;h1&gt;
  
  
  What Is Wormhole?
&lt;/h1&gt;

&lt;p&gt;It's this, really:&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/jdsteinhauser" rel="noopener noreferrer"&gt;
        jdsteinhauser
      &lt;/a&gt; / &lt;a href="https://github.com/jdsteinhauser/wormhole" rel="noopener noreferrer"&gt;
        wormhole
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Some of my most used functions implemented in different languages
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Wormhole&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;You ever think, "Hey I wish this langugage had the capability of some other language I like?" Enter Wormhole.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Motivation&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;During the &lt;a href="https://http://adventofcode.com/" rel="nofollow noopener noreferrer"&gt;Advent of Code&lt;/a&gt; 2018, I found myself writing the same functions in Elixir that
I knew I had used in Clojure, F#, or some other language. In order to prevent myself from doing this in the future, I
decided that building a library to do house all of these helpful functions across languages that I either knew or
wanted to learn.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Desired functions&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;These are the functions that I've used and that I'd like to have in multiple languages. Some of them are already implemented
in the language already, so I won't reimplement them. Each implementation will list the functions as implemented in the language,
as well as links to their documentation.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;map&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;filter&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;reduce&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;reduce_while&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;chunk&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;chunk_by&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;juxt&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;min_by&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;max_by&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;frequencies&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;group_by&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;scan&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;inc&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;dec&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;zip&lt;/code&gt;…&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/jdsteinhauser/wormhole" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;I've got an addiction. I love learning new languages. With learning new languages, you end up finding functions, classes, and concepts that you wish that you had in other languages. Sometimes, those functions are named different things and it gets confusing when you switch between languages. I end up doing a lot of data collection manipulation, and so I decided to start with what I knew best and branch out from there!&lt;/p&gt;

&lt;h1&gt;
  
  
  What Functions Am I Looking For?
&lt;/h1&gt;

&lt;p&gt;For a non-exhaustive list, I wanted to have at least the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Collection basics: &lt;code&gt;map&lt;/code&gt;, &lt;code&gt;filter&lt;/code&gt;, &lt;code&gt;reduce&lt;/code&gt;, and &lt;code&gt;scan&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Chunking data: &lt;code&gt;chunk&lt;/code&gt;, &lt;code&gt;chunk_by&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Common stats: &lt;code&gt;min_by&lt;/code&gt;, &lt;code&gt;max_by&lt;/code&gt;, &lt;code&gt;group_by&lt;/code&gt;, &lt;code&gt;frequencies&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Other hella useful things: &lt;code&gt;reduce_while&lt;/code&gt;, &lt;code&gt;juxt&lt;/code&gt;, &lt;code&gt;identity&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  What Languages Am I Targeting?
&lt;/h1&gt;

&lt;p&gt;For now, I have filled in my perceived gaps in functions in C#, Clojure, and Elixir. I have an F# solution that I'll be comfortable with early this week, and I've started looking at a comprehensive list of Ruby functions as well. After that... well, I'm not entirely sure! I think I'm going to go through Rust, JavaScript, Java, and possibly Kotlin and Python 3 to see what other handy things I can implement across all those languages.&lt;/p&gt;

&lt;h1&gt;
  
  
  Will These Be Deployed to Package Managers?
&lt;/h1&gt;

&lt;p&gt;Yes... but not right now. I need to get the documentation to a suitable state. I've pulled down several packages before but I've never pushed mine up to any! I'm sure that will end up being a blog post in and of itself.&lt;/p&gt;

&lt;h1&gt;
  
  
  Current Cheat Sheet
&lt;/h1&gt;

&lt;p&gt;Here's a summary of the languages I've targeted so far, with documentation links to each function that either already exists, or that I've implemented in Wormhole.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Function&lt;/th&gt;
&lt;th&gt;C#&lt;/th&gt;
&lt;th&gt;F#&lt;/th&gt;
&lt;th&gt;Clojure&lt;/th&gt;
&lt;th&gt;Elixir&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;map&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://docs.microsoft.com/en-us/dotnet/api/system.linq.enumerable.select?view=netcore-2.2" rel="noopener noreferrer"&gt;&lt;code&gt;Enumerable.Select&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://msdn.microsoft.com/en-us/visualfsharpdocs/conceptual/seq.map%5b't,'u%5d-function-%5bfsharp%5d" rel="noopener noreferrer"&gt;&lt;code&gt;Seq.map&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="http://clojuredocs.org/clojure.core/map" rel="noopener noreferrer"&gt;&lt;code&gt;clojure.core/map&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;
&lt;a href="https://hexdocs.pm/elixir/Enum.html#map/2" rel="noopener noreferrer"&gt;&lt;code&gt;Enum.map/2&lt;/code&gt;&lt;/a&gt;, &lt;a href="https://hexdocs.pm/elixir/Stream.html#map/2" rel="noopener noreferrer"&gt;&lt;code&gt;Stream.map/2&lt;/code&gt;&lt;/a&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;filter&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://docs.microsoft.com/en-us/dotnet/api/system.linq.enumerable.where?view=netcore-2.2" rel="noopener noreferrer"&gt;&lt;code&gt;Enumerable.Where&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://msdn.microsoft.com/en-us/visualfsharpdocs/conceptual/seq.filter%5b't%5d-function-%5bfsharp%5d" rel="noopener noreferrer"&gt;&lt;code&gt;Seq.filter&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="http://clojuredocs.org/clojure.core/filter" rel="noopener noreferrer"&gt;&lt;code&gt;clojure.core/filter&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;
&lt;a href="https://hexdocs.pm/elixir/Enum.html#filter/2" rel="noopener noreferrer"&gt;&lt;code&gt;Enum.filter/2&lt;/code&gt;&lt;/a&gt;, &lt;a href="https://hexdocs.pm/elixir/Stream.html#filter/2" rel="noopener noreferrer"&gt;&lt;code&gt;Stream.filter/2&lt;/code&gt;&lt;/a&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;reduce&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://docs.microsoft.com/en-us/dotnet/api/system.linq.enumerable.aggregate?view=netcore-2.2" rel="noopener noreferrer"&gt;&lt;code&gt;Enumerable.Aggregate&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://msdn.microsoft.com/en-us/visualfsharpdocs/conceptual/seq.reduce%5b't%5d-function-%5bfsharp%5d" rel="noopener noreferrer"&gt;&lt;code&gt;Seq.reduce&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="http://clojuredocs.org/clojure.core/reduce" rel="noopener noreferrer"&gt;&lt;code&gt;clojure.core/reduce&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://hexdocs.pm/elixir/Enum.html#reduce/2" rel="noopener noreferrer"&gt;&lt;code&gt;Enum.reduce&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;reduce_while&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ReduceWhile&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;reduceWhile&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;reduce-while&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://hexdocs.pm/elixir/Enum.html#reduce_while/3" rel="noopener noreferrer"&gt;&lt;code&gt;Enum.reduce_while/3&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;scan&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Scan&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://msdn.microsoft.com/en-us/visualfsharpdocs/conceptual/seq.scan%5b't,'state%5d-function-%5bfsharp%5d" rel="noopener noreferrer"&gt;&lt;code&gt;Seq.scan&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="http://clojuredocs.org/clojure.core/reductions" rel="noopener noreferrer"&gt;&lt;code&gt;clojure.core/reductions&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;
&lt;a href="https://hexdocs.pm/elixir/Enum.html#scan/2" rel="noopener noreferrer"&gt;&lt;code&gt;Enum.scan&lt;/code&gt;&lt;/a&gt;, &lt;a href="https://hexdocs.pm/elixir/Stream.html#scan/2" rel="noopener noreferrer"&gt;&lt;code&gt;Stream.scan&lt;/code&gt;&lt;/a&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;chunk&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Chunk&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;chunk&lt;/code&gt;*&lt;/td&gt;
&lt;td&gt;&lt;a href="http://clojuredocs.org/clojure.core/partition" rel="noopener noreferrer"&gt;&lt;code&gt;clojure.core/partition&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;
&lt;a href="https://hexdocs.pm/elixir/Enum.html#chunk_every/4" rel="noopener noreferrer"&gt;&lt;code&gt;Enum.chunk_every/4&lt;/code&gt;&lt;/a&gt;, &lt;a href="https://hexdocs.pm/elixir/Stream.html#chunk_every/4" rel="noopener noreferrer"&gt;&lt;code&gt;Stream.chunk_every/4&lt;/code&gt;&lt;/a&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;chunk_by&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ChunkBy&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;chunkBy&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="http://clojuredocs.org/clojure.core/partition-by" rel="noopener noreferrer"&gt;&lt;code&gt;clojure.core/partition-by&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;
&lt;a href="https://hexdocs.pm/elixir/Enum.html#chunk_by/2" rel="noopener noreferrer"&gt;&lt;code&gt;Enum.chunk_by/2&lt;/code&gt;&lt;/a&gt;, &lt;a href="https://hexdocs.pm/elixir/Stream.html#chunk_every/4" rel="noopener noreferrer"&gt;&lt;code&gt;Stream.chunk_by/2&lt;/code&gt;&lt;/a&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;juxt&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Juxt&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;juxt&lt;/code&gt;, &lt;code&gt;juxt2&lt;/code&gt;, &lt;code&gt;juxt3&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;&lt;a href="http://clojuredocs.org/clojure.core/juxt" rel="noopener noreferrer"&gt;&lt;code&gt;clojure.core/juxt&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Wormhole.juxt/1&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;min_by&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;MinBy&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://msdn.microsoft.com/en-us/visualfsharpdocs/conceptual/seq.minby%5b't,'u%5d-function-%5bfsharp%5d" rel="noopener noreferrer"&gt;&lt;code&gt;Seq.minBy&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;min-by&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://hexdocs.pm/elixir/Enum.html#min_by/3" rel="noopener noreferrer"&gt;&lt;code&gt;Enum.min_by/3&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;max_by&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;MaxBy&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://msdn.microsoft.com/en-us/visualfsharpdocs/conceptual/seq.maxby%5b't,'u%5d-function-%5bfsharp%5d" rel="noopener noreferrer"&gt;&lt;code&gt;Seq.maxBy&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;max-by&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://hexdocs.pm/elixir/Enum.html#max_by/3" rel="noopener noreferrer"&gt;&lt;code&gt;Enum.max_by/3&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;frequencies&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Frequencies&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;freqs&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="http://clojuredocs.org/clojure.core/frequencies" rel="noopener noreferrer"&gt;&lt;code&gt;clojure.core/frequencies&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Wormhole.freqs/1&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;group_by&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://docs.microsoft.com/en-us/dotnet/api/system.linq.enumerable.groupby?view=netcore-2.2" rel="noopener noreferrer"&gt;&lt;code&gt;Enumerable.GroupBy&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://msdn.microsoft.com/en-us/visualfsharpdocs/conceptual/seq.groupby%5B't%2C'key%5D-function-%5Bfsharp%5D" rel="noopener noreferrer"&gt;&lt;code&gt;Seq.groupBy&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="http://clojuredocs.org/clojure.core/group-by" rel="noopener noreferrer"&gt;&lt;code&gt;clojure.core/group-by&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://hexdocs.pm/elixir/Enum.html#group_by/3" rel="noopener noreferrer"&gt;&lt;code&gt;Enum.group_by/3&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;identity&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Identity&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://msdn.microsoft.com/en-us/visualfsharpdocs/conceptual/operators.id%5B't%5D-function-%5Bfsharp%5D" rel="noopener noreferrer"&gt;&lt;code&gt;Operators.id&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="http://clojuredocs.org/clojure.core/identity" rel="noopener noreferrer"&gt;&lt;code&gt;clojure.core/identity&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Wormhole.identity/1&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;F# contains a &lt;a href="https://msdn.microsoft.com/en-us/visualfsharpdocs/conceptual/seq.windowed%5B't%5D-function-%5Bfsharp%5D" rel="noopener noreferrer"&gt;&lt;code&gt;Seq.windowed&lt;/code&gt;&lt;/a&gt; function, but it only moves the chunk one element at a time.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Why Is This Stuff Useful?
&lt;/h1&gt;

&lt;p&gt;Well, some of the functions are either self-explanatory or already written about in several other articles. I'll cover some of the lesser known ones and why I personally found them useful.&lt;/p&gt;

&lt;h2&gt;
  
  
  Chunking
&lt;/h2&gt;

&lt;p&gt;I've written about &lt;code&gt;chunk&lt;/code&gt; and &lt;code&gt;chunk_by&lt;/code&gt; before, but in case you missed it, check out my previous article!&lt;/p&gt;


&lt;div class="ltag__link"&gt;
  &lt;a href="/jdsteinhauser" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F34531%2F90fce97c-49f0-443c-8f67-fc9544b2d623.jpeg" alt="jdsteinhauser"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="/jdsteinhauser/alright-break-it-up-using-partitionchunk-h15" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;Alright, Break It Up! Using Partition/ Chunk&lt;/h2&gt;
      &lt;h3&gt;Jason Steinhauser ・ Oct 18 '18&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#functional&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#programming&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#coding&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#algorithms&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


&lt;h2&gt;
  
  
  Reduce While
&lt;/h2&gt;

&lt;p&gt;I'll admit that this is possibly a not-so-often used case. Sometimes you don't want to reduce an entire sequence - just up to a certain point. Unfortunately, &lt;code&gt;reduce&lt;/code&gt; is typically all or nothing. That doesn't really work when you have a potentially infinite series of data. However, Elixir's &lt;code&gt;reduce_while&lt;/code&gt; helped me keep my solution for &lt;a href="https://adventofcode.com/2018/day/1" rel="noopener noreferrer"&gt;AoC 2018 Day 1 Part 2&lt;/a&gt; compact. I'm hoping to find more real-world use cases for it... but it's still one of my favorite data processing functions I've found.&lt;/p&gt;

&lt;h2&gt;
  
  
  Juxt
&lt;/h2&gt;

&lt;p&gt;While I admit that, at first glance, &lt;code&gt;juxt&lt;/code&gt; is nothing special. Take an array of functions that operate on the same parameters, and then return a single function that takes that parameter and returns an array of each function run on those parameters? Why use that?&lt;/p&gt;

&lt;p&gt;I've ported this function from Clojure into other work projects before. For instance, I had a &lt;em&gt;very&lt;/em&gt; large collection of data (1MM+ entries!) and I couldn't afford to iterate over them multiple times. I used &lt;code&gt;juxt&lt;/code&gt; to compose my analysis functions together so that I only had to iterate over the collection one time.&lt;/p&gt;

&lt;p&gt;Similarly, since a keyword in Clojure can be treated as a function for retrieving a value out of a map with that key (&lt;code&gt;(:foo {:foo 5 :bar 3})&lt;/code&gt; returns &lt;code&gt;5&lt;/code&gt;), you can compose several keywords for accessing data out of a collection of maps and returning the results in kind of like a table format. I wrote about that as part of a previous post on dense Clojure code:&lt;/p&gt;


&lt;div class="ltag__link"&gt;
  &lt;a href="/jdsteinhauser" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F34531%2F90fce97c-49f0-443c-8f67-fc9544b2d623.jpeg" alt="jdsteinhauser"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="/jdsteinhauser/a-verbose-explanation-of-compact-code-546g" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;A verbose explanation of compact code&lt;/h2&gt;
      &lt;h3&gt;Jason Steinhauser ・ May 21 '18&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#showdev&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#clojure&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#productivity&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


&lt;h2&gt;
  
  
  Frequencies
&lt;/h2&gt;

&lt;p&gt;Because sometimes, you just need a histogram. &lt;code&gt;frequencies&lt;/code&gt; provides that in one single function!&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;Hopefully someone out there will find this useful, either as a cheat sheet or as a library. In the near-term, I will be investigating Ruby and Rust (in that order) to see what other handy functions I could foresee using across multiple languages. I'll also put Wormhole up as a package in your favorite package managers soon, and probably write about the things I do/don't like about each.&lt;/p&gt;

&lt;p&gt;Happy coding, and I'd love to hear about other general purpose data manipulation functions you've found useful!&lt;/p&gt;

</description>
      <category>showdev</category>
    </item>
    <item>
      <title>I Don't Know How To Take Compliments</title>
      <dc:creator>Jason Steinhauser</dc:creator>
      <pubDate>Tue, 23 Oct 2018 21:14:02 +0000</pubDate>
      <link>https://dev.to/jdsteinhauser/i-dont-know-how-to-take-compliments-36b4</link>
      <guid>https://dev.to/jdsteinhauser/i-dont-know-how-to-take-compliments-36b4</guid>
      <description>&lt;p&gt;Today was a good day. My wife complimented me in my new shirt and pants (totally rocking some floral print), I helped a coworker with design on a different project, and I wrapped up a proposal and thanked a coworker for his assistance. I can handle my wife's compliments... but I wasn't sure how to deal with the other two situations.&lt;/p&gt;

&lt;h1&gt;
  
  
  What Happened?
&lt;/h1&gt;

&lt;p&gt;My coworker asked me about handling role-based view components. We white-boarded it for a few minutes, and I finally mentioned that we could just use the role names as map keys and the values as components that role had access to as a list. We finally settled on (as his idea) the map values being another map which contained boolean properties that we could use in an &lt;code&gt;ngIf&lt;/code&gt; so that there was constant lookup time and minimal logic in his view. He said to me "I've had to do role-based management on several different projects, and this is &lt;em&gt;by far&lt;/em&gt; the cleanest way I've ever seen it done. Thanks for your help!"&lt;/p&gt;

&lt;h2&gt;
  
  
  So what's wrong with that?
&lt;/h2&gt;

&lt;p&gt;I don't really feel like the credit is all mine. His idea was half of the implementation, and the last part to make the lookup constant time instead of linear time. It's not a big deal, considering we have few components and roles right now, but still! Half of the idea was his. It doesn't feel like anything incredible, honestly. I was just doing my job. I mean, I reminded him that he was part of the solution, but I still felt a little... not really embarrassed? More like sheepish, I guess?&lt;/p&gt;

&lt;h1&gt;
  
  
  Anything Else?
&lt;/h1&gt;

&lt;p&gt;Another coworker had been helping me work on my proposal and I pulled him in at the last minute to help, and I apologized to him up front for not engaging him earlier. After we wrapped everything up and I went to his desk to thank him for his help and apologized again for roping him in so late. He said "Well, I definitely appreciate you thanking me. A lot of people expect me to just drop what I'm doing even with late notice, but I appreciate your courtesy."&lt;/p&gt;

&lt;h2&gt;
  
  
  AND?!?!
&lt;/h2&gt;

&lt;p&gt;I blushed when he thanked me for being courteous and told him, "Well, I didn't know what else to do but apologize and thank you." And I just really didn't think that what I did was extraordinary by any means. I thought it was... well... just what should happen.&lt;/p&gt;

&lt;h1&gt;
  
  
  So what are you getting at?
&lt;/h1&gt;

&lt;p&gt;The first situation, where I helped my friend/coworker with a design issue... I can handle relatively well. I did help him with something, and he finished out the idea. I'm totally fine for taking the partial credit for a good idea, but I really just felt like I was doing my job... nothing special.&lt;/p&gt;

&lt;p&gt;The second situation, however, I can't really get past that one. I was raised to be polite to everyone who is providing you service - a waiter, a mechanic, a coworker - and so it made me uneasy to know that I was the exception rather than the rule when it came to showing appreciation.&lt;/p&gt;

&lt;p&gt;Is it wrong to feel like this? To feel like what you think is common courtesy or just doing your job is praised? Have any of y'all experienced this feeling and worked through it? I'd love to hear some feedback!&lt;/p&gt;

</description>
      <category>discuss</category>
    </item>
    <item>
      <title>Alright, Break It Up! Using Partition/ Chunk</title>
      <dc:creator>Jason Steinhauser</dc:creator>
      <pubDate>Thu, 18 Oct 2018 22:08:08 +0000</pubDate>
      <link>https://dev.to/jdsteinhauser/alright-break-it-up-using-partitionchunk-h15</link>
      <guid>https://dev.to/jdsteinhauser/alright-break-it-up-using-partitionchunk-h15</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Programming Should Be About Transforming Data&lt;/strong&gt; [...] I don't want to hide data I want to transform it.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Dave Thomas, &lt;a href="https://www.amazon.com/Programming-Elixir-1-6-Functional-Concurrent/dp/1680502999/ref=sr_1_1?ie=UTF8&amp;amp;qid=1538580193&amp;amp;sr=8-1&amp;amp;keywords=programming+elixir+dave+thomas" rel="noopener noreferrer"&gt;Programming Elixir&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;Whether it's calculating students' final grades, turning mouse clicks into t-shirt orders, or reading and publishing temperature data from a RPi, programming is basically distilling data from one form into another. Oftentimes, it doesn't feel like pure data transformation because we try to handle how the data is stored as well as its transformation in one step. This can make code awfully confusing, especially to anyone that has to maintain the code.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Any fool can write code that a computer can understand. Good programmers write code that humans can understand.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Martin Fowler&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;I've got a couple of examples from past projects that I'd like to share, going from how I'd written algorithms when I was more concerned about the place of my datapoints, and then after I discovered partitioning/chunking functions.&lt;/p&gt;

&lt;h1&gt;
  
  
  What is Partitioning/Chunking?
&lt;/h1&gt;

&lt;p&gt;Partitioning and chunking, in the context of this article, is subdividing existing collections, streams, and enumerables/iterables, into pieces more useful to your algorithm. This chunking can be done either by: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Size (from &lt;a href="https://clojuredocs.org/clojure.core/partition" rel="noopener noreferrer"&gt;ClojureDocs&lt;/a&gt;)
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight clojure"&gt;&lt;code&gt;&lt;span class="c1"&gt;;; partition a list of 22 items into 5 (20/4) lists of 4 items &lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="c1"&gt;;; the last two items do not make a complete partition and are dropped.&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;partition&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;range&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;22&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="c1"&gt;;;=&amp;gt; ((0 1 2 3) (4 5 6 7) (8 9 10 11) (12 13 14 15) (16 17 18 19))&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Max Size (from &lt;a href="https://lodash.com/docs/4.17.10" rel="noopener noreferrer"&gt;LoDash&lt;/a&gt;)
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;_&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;chunk&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;a&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;b&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;c&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;d&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// =&amp;gt; [['a', 'b'], ['c', 'd']]&lt;/span&gt;

&lt;span class="nx"&gt;_&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;chunk&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;a&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;b&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;c&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;d&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// =&amp;gt; [['a', 'b', 'c'], ['d']]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;A mapping function to group contiguous items in the stream that map to the same value (from &lt;a href="https://hexdocs.pm/elixir/Enum.html#chunk_by/2" rel="noopener noreferrer"&gt;Elixir Docs&lt;/a&gt;)
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="no"&gt;Enum&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;chunk_by&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;&amp;amp;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; [[1], [2, 2], [3], [4, 4, 6], [7, 7]]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F0y5m5qompf6u26w7rq0z.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F0y5m5qompf6u26w7rq0z.jpeg" alt="Divide and Conquer?"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Basically, yes... divide and conquer.&lt;/p&gt;

&lt;h1&gt;
  
  
  Parsing Arrays from Binary Streams
&lt;/h1&gt;

&lt;p&gt;If you've ever had to get raw data off of a wire or read in a proprietary/lesser-used binary format, then you've probably had to write your own parser for it. And more often than not, you've had to read an array whose length is defined by an earlier declared variable. &lt;a href="https://en.wikipedia.org/wiki/Endianness" rel="noopener noreferrer"&gt;Endianness&lt;/a&gt; aside, that in and of itself is not the most fun. The format is usually akin to:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;th&gt;Type&lt;/th&gt;
&lt;th&gt;Size&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Sync Word (0xC011FEFE)&lt;/td&gt;
&lt;td&gt;int32&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Timestamp (µsec)&lt;/td&gt;
&lt;td&gt;int64&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;nElements&lt;/td&gt;
&lt;td&gt;int32&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Data elements&lt;/td&gt;
&lt;td&gt;int32[]&lt;/td&gt;
&lt;td&gt;4*nElements&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Now, normally how I would have normally built something to read in the packet (without validation) like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;DataFrame&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;DateTime&lt;/span&gt; &lt;span class="n"&gt;Timestamp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;Data&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;DataFrame&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;DateTime&lt;/span&gt; &lt;span class="n"&gt;timestamp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Timestamp&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;timestamp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;Data&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="nf"&gt;FromBytes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;rawData&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;timeUsec&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;BitConverter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ToInt64&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rawData&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;4&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;    &lt;span class="c1"&gt;// Skip the sync word&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;timestamp&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;DateTime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FromFileTimeUtc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;timeUsec&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;BitConverter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ToInt32&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rawData&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;12&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

        &lt;span class="c1"&gt;// Skip the first 16 bytes before we start reading the data&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;++)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;BitConverter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ToInt32&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rawData&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;16&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="m"&gt;4&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;DataFrame&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;timestamp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Granted, I have to care a lot about where the header information is, but there has to be a way to make my intention clearer on reading the array of data into &lt;code&gt;data&lt;/code&gt;. The same thing, written in F#, feels a little cleaner to me:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ocaml"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="nc"&gt;DateFrame&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nc"&gt;Timestamp&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;DateTime&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nc"&gt;Data&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="kt"&gt;array&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;fromBytes&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; 
  &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;BitConverter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;ToInt64&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;numItems&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;BitConverter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;ToInt32&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;Timestamp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;DateTime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;FromFileTimeUtc&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;
    &lt;span class="nc"&gt;Data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;
           &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;skip&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;
           &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;chunkBySize&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;
           &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;take&lt;/span&gt; &lt;span class="n"&gt;numItems&lt;/span&gt;
           &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;BitConverter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;ToInt32&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Chunking &lt;code&gt;data&lt;/code&gt; into 4 byte increments allows me to very cleanly pass info to the &lt;code&gt;BitConverter&lt;/code&gt; to make the conversion to 32-bit integers. I don't have to keep track of offsets, and have effectively removed the entire category of offset or "off by x" errors from my code!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fpmx7ey6a1fdyb3fu5ggp.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fpmx7ey6a1fdyb3fu5ggp.jpg" alt="No one expects off by one errors!"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Only parts of the data matter
&lt;/h1&gt;

&lt;p&gt;Let's face it: sometimes you just don't care about a lot of your data.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fntbdkpvuu2wdmx22bu7i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fntbdkpvuu2wdmx22bu7i.png" alt="It's really about like that"&gt;&lt;/a&gt;&lt;br&gt;
Image credit to &lt;a href="https://www.capgemini.com/2012/09/communities-crossing-the-dont-care-line-and-love-your-haters/" rel="noopener noreferrer"&gt;this blog post&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's say you're a delivery company and you want to make sure that your drivers are obeying speed limits. You really don't care about times that they're actually doing that, but when they go over the speed limit they might want to figure out why. Maybe they were going downhill and started to brake late. Perhaps they were texting and not paying attention. Who knows? But you're supposed to take the speed limit from your map API and velocity from the GPS and figure out when, and for how long, a driver was going over the speed limit. Let's see what it might look like to find drivers that were speeding for more than one minute:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;DriverData&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;DateTime&lt;/span&gt; &lt;span class="n"&gt;Timestamp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;Speed&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;SpeedLimit&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;DriverData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;DateTime&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;speed&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;speedLimit&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Timestamp&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;Speed&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;speed&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;SpeedLimit&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;speedLimit&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Driver&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;IEnumerable&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;DriverData&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;DrivingHistory&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;IEnumerable&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;(&lt;/span&gt;&lt;span class="n"&gt;DateTime&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;TimeSpan&lt;/span&gt;&lt;span class="p"&gt;)&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;SpeedingMoreThanAMinute&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

        &lt;span class="c1"&gt;// If the collection has no values or only one value, result is empty&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;DrivingHistory&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt; &lt;span class="p"&gt;||&lt;/span&gt; &lt;span class="n"&gt;DrivingHistory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Count&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;isSpeeding&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;speedingStart&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;DateTime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;lastTime&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;DateTime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;point&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;DrivingHistory&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;isSpeedingNow&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;point&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Speed&lt;/span&gt; &lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;point&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SpeedLimit&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;isSpeedingNow&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(!&lt;/span&gt;&lt;span class="n"&gt;isSpeeding&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="n"&gt;speedingStart&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;point&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Timestamp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
                &lt;span class="n"&gt;isSpeeding&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                &lt;span class="n"&gt;lastTime&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;point&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Timestamp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;isSpeeding&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;     &lt;span class="c1"&gt;// We were speeding, and now we're not&lt;/span&gt;
                    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;duration&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lastTime&lt;/span&gt; &lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="n"&gt;speedingStart&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;TotalSeconds&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
                    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;duration&lt;/span&gt; &lt;span class="p"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="m"&gt;60&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                        &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;speedingStart&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;duration&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                    &lt;span class="p"&gt;}&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
                &lt;span class="n"&gt;isSpeeding&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Yuck. That's a lot of ugly logic! There are six possible conditions there, and we have to keep all of those internal state variables and their functions in our head as we write this out. We &lt;strong&gt;need&lt;/strong&gt; all of this overhead to find out when our drivers are speeding? Surely you can't be serious!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fd0eahtoe2yneapwdl2b8.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fd0eahtoe2yneapwdl2b8.jpg" alt="Surely you can't be serious?"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This where chunking by a function comes in handy. Trying this in Elixir (EDIT: slight fix thanks to Aleksei Matiushkin!) :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="k"&gt;defmodule&lt;/span&gt; &lt;span class="no"&gt;DriverData&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="k"&gt;defstruct&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:timestamp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:speed&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:speed_limit&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;is_speeding_one_minute_plus&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;data&lt;/span&gt;
        &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Enum&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;drop_while&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="nv"&gt;&amp;amp;1&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;speed&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="nv"&gt;&amp;amp;1&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;speed_limit&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
        &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Enum&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;chunk_by&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="nv"&gt;&amp;amp;1&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;speed&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;&amp;amp;1&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;speed_limit&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
        &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Enum&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;take_every&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Enum&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fun&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; 
            &lt;span class="p"&gt;%{&lt;/span&gt;&lt;span class="n"&gt;start&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;hd&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="n"&gt;timestamp&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
              &lt;span class="n"&gt;duration&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;DateTime&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;diff&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;List&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;last&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="n"&gt;timestamp&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;hd&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="n"&gt;timestamp&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
            &lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Enum&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="nv"&gt;&amp;amp;1&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;duration&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Since this is one of five languages I've used in this post (six if you count English!), I'll walk you through what's going on since it's less simple. The Elixir &lt;code&gt;|&amp;gt;&lt;/code&gt; operator takes the previously evaluated expression and uses this as the first argument in the next function call. This functions the same way as Clojure's &lt;code&gt;-&amp;gt;&lt;/code&gt; macro, but differently than F#'s &lt;code&gt;|&amp;gt;&lt;/code&gt; operator (which uses the previous statement as the last argument in the next function). I use &lt;code&gt;Enum.drop_while/2&lt;/code&gt; to drop off all the points at the beginning from where the driver isn't speeding, and then I use &lt;code&gt;Enum.chunk_by/2&lt;/code&gt; then break the list into chunks based on whether or not the driver's speed exceeds the speed limit, and then use &lt;code&gt;Enum.take_every/2&lt;/code&gt; to take every 2nd element (as specified by the &lt;code&gt;2&lt;/code&gt; in the arguments). That leaves me with only Lists of times where the driver was speeding. I then use &lt;code&gt;Enum.map/2&lt;/code&gt; to turn those lists into maps with keys of &lt;code&gt;:start&lt;/code&gt; and &lt;code&gt;:duration&lt;/code&gt;, and then filter those based on a &lt;code&gt;duration &amp;gt;= 60&lt;/code&gt; seconds. We did the whole thing solely by operating on the chunks of data we cared about, filtered out what we didn't need, and turned the output into something we could use, all without using any conditional branches or any internal state.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;Admittedly, it took me quite a while to wrap my head around chunking/ partitioning data into useful bits. It's hard to make that transition from how I'm used to developing algorithms in over a decade of procedural and OO programming, to thinking about everything as just data transformations. If the concept seems difficult for you, just understand that lots of other people, including me, have been there too! If you find yourself building considerable amount of internal state just to parse some data out of an iterable/ enumerable collection, use that as a code smell to see if chunking is right for your problem.&lt;/p&gt;

&lt;p&gt;Happy coding!&lt;/p&gt;

</description>
      <category>functional</category>
      <category>programming</category>
      <category>coding</category>
      <category>algorithms</category>
    </item>
    <item>
      <title>We Don't Need No Stinking map() or filter()</title>
      <dc:creator>Jason Steinhauser</dc:creator>
      <pubDate>Sat, 22 Sep 2018 22:29:33 +0000</pubDate>
      <link>https://dev.to/jdsteinhauser/we-dont-need-no-stinking-map-or-filter-1hp4</link>
      <guid>https://dev.to/jdsteinhauser/we-dont-need-no-stinking-map-or-filter-1hp4</guid>
      <description>&lt;p&gt;Pretty clickbait-y title, I know, but hear me out! I posed a &lt;a href="https://www.businessinsider.com/why-people-get-their-best-ideas-in-the-shower-2016-1" rel="noopener noreferrer"&gt;shower thinking&lt;/a&gt; question to some of our junior developers. If you had to choose one of &lt;code&gt;map&lt;/code&gt;, &lt;code&gt;filter&lt;/code&gt;, or &lt;code&gt;reduce&lt;/code&gt; to use for the rest of your life, which one would you pick? While I use &lt;code&gt;map&lt;/code&gt; and &lt;code&gt;filter&lt;/code&gt; quite regularly in programs - pretty much independent of language - and I prefer to use them... they're basically derivatives or optimizations of &lt;code&gt;reduce&lt;/code&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  How?!
&lt;/h1&gt;

&lt;p&gt;So, let's look at some examples of &lt;code&gt;Array.prototype.reduce()&lt;/code&gt; in JavaScript. It takes a &lt;code&gt;callback&lt;/code&gt; function and an optional &lt;code&gt;initial value&lt;/code&gt;. The &lt;code&gt;callback&lt;/code&gt; function takes an &lt;code&gt;accumulator&lt;/code&gt; and the &lt;code&gt;currentValue&lt;/code&gt; in the array that we're reducing. Reduce is often used to sum the terms of a collection:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sum&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;accumulator&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;currentValue&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;currentValue&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;accumulator&lt;/span&gt;

&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;val&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;val&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;// =&amp;gt; prints 15 to the console&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's walk through the individual steps of what happens. In the first step, we have an accumulated value of 0 (we pass that as the initial value), and the current value is 1. We repeat this for each element in the array, and we return the final accumulated value.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nf"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;     &lt;span class="c1"&gt;// remaining values to accumulate: [2,3,4,5]&lt;/span&gt;
&lt;span class="nf"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;     &lt;span class="c1"&gt;// remaining values to accumulate: [3,4,5]&lt;/span&gt;
&lt;span class="nf"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;     &lt;span class="c1"&gt;// remaining values to accumulate: [4,5]&lt;/span&gt;
&lt;span class="nf"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;    &lt;span class="c1"&gt;// remaining value to accumulate: [5]&lt;/span&gt;
&lt;span class="nf"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt; &lt;span class="c1"&gt;// remaining values to accumulate: []&lt;/span&gt;

&lt;span class="c1"&gt;// return accumulator of 15&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a pretty straightforward use case. Reduce seems to be most often used for sums and products.&lt;/p&gt;

&lt;h1&gt;
  
  
  You sure we don't need a map?
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F29q3nrdrzw2xlmz5aj9v.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F29q3nrdrzw2xlmz5aj9v.jpg" alt="Lost in the desert"&gt;&lt;/a&gt;Photo from &lt;a href="https://julianpetersphotography.de/blog/getting-lost-in-the-desert-my-trip-to-the-sahara/" rel="noopener noreferrer"&gt;Julian Peters Photography&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Array.prototype.map()&lt;/code&gt; takes a function to apply to each element of the array, and returns the resulting array. The classic example of &lt;code&gt;map&lt;/code&gt;ping is doubling integers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;doubler&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;

&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;val&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;doubler&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;val&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;    &lt;span class="c1"&gt;// =&amp;gt; prints [2,4,6,8,10] to the console&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pretty straightforward, right? So how in the world can we build &lt;code&gt;map&lt;/code&gt; using &lt;code&gt;reduce&lt;/code&gt;? Instead of our accumulator being a single value now, our accumulator will be an array. We'll apply the function to each &lt;code&gt;currentValue&lt;/code&gt; and append that to the end of the accumulator array:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;pushAndReturn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;arr&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;map&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;f&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;acc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;pushAndReturn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;acc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;f&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt; &lt;span class="p"&gt;[])&lt;/span&gt;

&lt;span class="c1"&gt;// Let's try it!&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;doubler&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;    &lt;span class="c1"&gt;// =&amp;gt; prints [2,4,6,8,10]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Excellent! Works exactly as we expected. But what were all the steps taken to get that answer?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;[].&lt;/span&gt;&lt;span class="nf"&gt;pushAndReturn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;doubler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="c1"&gt;// remaining values to accumulate: [2,3,4,5]&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;pushAndReturn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;doubler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="c1"&gt;// remaining values to accumulate: [3,4,5]&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;pushAndReturn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;doubler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="c1"&gt;// remaining values to accumulate: [4,5]&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;pushAndReturn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;doubler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="c1"&gt;// remaining value to accumulate: [5]&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;pushAndReturn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;doubler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="c1"&gt;// remaining values to accumulate: []&lt;/span&gt;

&lt;span class="c1"&gt;// return accumulator of [2,4,6,8,10]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It's important to keep in mind that the accumulator can be &lt;strong&gt;any type we want&lt;/strong&gt;. It doesn't just have to be number for summing a list of numbers. It can be literally anything.&lt;/p&gt;

&lt;h1&gt;
  
  
  Let's filter our $#!+
&lt;/h1&gt;


&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F09dpkjt6pwyzrmh4w6hh.jpg" alt="Filtering stream water"&gt;&lt;br&gt;
Image from &lt;a href="https://www.outsideonline.com/2316951/know-when-its-time-new-water-filter" rel="noopener noreferrer"&gt;Outside Magazine&lt;/a&gt;

&lt;p&gt;&lt;code&gt;Array.prototype.filter()&lt;/code&gt; takes a predicate function and returns an array of values that return a truthy value when the predicate is applied. For example, if we want to get only odd numbers out of an array, we can use:&lt;br&gt;
&lt;/p&gt;

&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;isOdd&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;

&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;val&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;isOdd&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;val&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;        &lt;span class="c1"&gt;// =&amp;gt; prints [1,3,5]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;



&lt;p&gt;Let's implement filter with just reduce! It's going to seem awfully similar to our map implementation above.&lt;br&gt;
&lt;/p&gt;

&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;filter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;pred&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;acc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;pred&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nf"&gt;pushAndReturn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;acc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;acc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[])&lt;/span&gt;

&lt;span class="c1"&gt;// Let's try this one now!&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;isOdd&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;    &lt;span class="c1"&gt;// =&amp;gt; prints [1,3,5]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;



&lt;p&gt;Again, let's walk through the steps to see what happens:&lt;br&gt;
&lt;/p&gt;

&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nf"&gt;isOdd&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="p"&gt;[].&lt;/span&gt;&lt;span class="nf"&gt;pushAndReturn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="c1"&gt;// remaining values to accumulate: [2,3,4,5]&lt;/span&gt;
&lt;span class="nf"&gt;isOdd&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;pushAndReturn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="c1"&gt;// remaining values to accumulate: [3,4,5]&lt;/span&gt;
&lt;span class="nf"&gt;isOdd&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;pushAndReturn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="c1"&gt;// remaining values to accumulate: [4,5]&lt;/span&gt;
&lt;span class="nf"&gt;isOdd&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;pushAndReturn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="c1"&gt;// remaining value to accumulate: [5]&lt;/span&gt;
&lt;span class="nf"&gt;isOdd&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;pushAndReturn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="c1"&gt;// remaining values to accumulate: []&lt;/span&gt;

&lt;span class="c1"&gt;// return accumulator of [1,3,5]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;



&lt;h1&gt;
  
  
  So... why?
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fejvtface3pqfspj3wkrf.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fejvtface3pqfspj3wkrf.gif" alt="Ryan Reynolds' existential question"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;While this was mostly a thought exercise (I wouldn't necessarily use &lt;code&gt;reduce()&lt;/code&gt; to replace &lt;code&gt;map()&lt;/code&gt; in production code), it's important to remember that &lt;code&gt;reduce()&lt;/code&gt; can return any sort of value. Sure you can do sums, products, and concatenation with reduce... but you can also do mapping, filtering, taking elements while they match a predicate, build tree structures, create dictionaries/maps from lists/arrays... all by using reduce.&lt;/p&gt;

&lt;p&gt;Thanks for reading!&lt;/p&gt;

</description>
      <category>showdev</category>
      <category>programming</category>
      <category>learning</category>
    </item>
    <item>
      <title>When Math Fails You</title>
      <dc:creator>Jason Steinhauser</dc:creator>
      <pubDate>Wed, 01 Aug 2018 17:46:44 +0000</pubDate>
      <link>https://dev.to/jdsteinhauser/when-math-fails-you-2if8</link>
      <guid>https://dev.to/jdsteinhauser/when-math-fails-you-2if8</guid>
      <description>&lt;p&gt;It was after midnight, and I couldn't sleep. I opened up Chrome on my phone and I'd pulled up &lt;a href="https://medium.com/@bellmar/is-cobol-holding-you-hostage-with-math-5498c0eb428b" rel="noopener noreferrer"&gt;an editorial about COBOL&lt;/a&gt; earlier in the evening, and it gets me thinking about how our computers actually do math. The author linked &lt;a href="https://www3.nd.edu/~markst/cast-award-speech.pdf" rel="noopener noreferrer"&gt;an article&lt;/a&gt; all about issues with floating point math and some of the issues it's caused. You'd be surprised how many issues come from just not realizing that &lt;a href="https://www.exploringbinary.com/why-0-point-1-does-not-exist-in-floating-point/" rel="noopener noreferrer"&gt;0.1 can't be exactly represented in binary&lt;/a&gt;. So I decided to check out an example in the article with their test values, x=77617, y=33096:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/http%3A%2F%2Fquicklatex.com%2Fcache3%2Fce%2Fql_3839c2e0dde0907b0969dd4af343d6ce_l3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/http%3A%2F%2Fquicklatex.com%2Fcache3%2Fce%2Fql_3839c2e0dde0907b0969dd4af343d6ce_l3.png" alt="f(x,y)=333.75y^6 + x^2)(11x^2y^2 - y^6 - 121y^4 - 2) + 5.5y^8 + x/2y"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Thanks to &lt;a href="http://quicklatex.com/" rel="noopener noreferrer"&gt;Quick LaTeX&lt;/a&gt; for the formatting!&lt;/p&gt;

&lt;h1&gt;
  
  
  Trying It Out
&lt;/h1&gt;

&lt;p&gt;I wanted to see if I could replicate their findings:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Calculation Precision&lt;/th&gt;
&lt;th&gt;Result&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Single&lt;/td&gt;
&lt;td&gt;1.172603...&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Double&lt;/td&gt;
&lt;td&gt;1.1726039400531...&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Extended&lt;/td&gt;
&lt;td&gt;1.172603940053178...&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Actual Value&lt;/td&gt;
&lt;td&gt;-0.827396059946&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;So I implemented the function in Clojure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight clojure"&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;defn&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;trial-double&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; 
    &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;+&lt;/span&gt;&lt;span class="w"&gt; 
        &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;333.75&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;Math/pow&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;-&lt;/span&gt;&lt;span class="w"&gt; 
                &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;11&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;Math/pow&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;121&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;Math/pow&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="mf"&gt;2.0&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;5.5&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;Math/pow&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;/&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Calling &lt;code&gt;(trial-double 77617 33096)&lt;/code&gt; yields the result &lt;code&gt;-1.1805916207174113E21&lt;/code&gt;. Oddly, this is &lt;strong&gt;not&lt;/strong&gt; the same incorrect answer that they achieved in the article. Mine was 21 orders of magnitude different, and the wrong sign! I tested it out in Excel as well...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;=333.75 * y^6 + x^2 * (11*x^2*y^2 - y^6 - 121 * y^4 - 2) + 5.5 * y^8 + x/2/y)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;... and I got the same wrong number that I did with Clojure!&lt;/p&gt;

&lt;p&gt;However, as the article mentions, this is &lt;strong&gt;not&lt;/strong&gt; the correct answer. So I set out to calculate the right answer. I ended up trying it out with a combination of Clojure's Ratio type and Java's BigInteger type (since Clojure's BigInt had an overflow issue):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight clojure"&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;defn&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;trial-rational&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;^&lt;/span&gt;&lt;span class="n"&gt;java.math.BigInteger&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;^&lt;/span&gt;&lt;span class="n"&gt;java.math.BigInteger&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; 
    &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;+&lt;/span&gt;&lt;span class="w"&gt; 
        &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1335&lt;/span&gt;&lt;span class="n"&gt;/4&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;.pow&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;-&lt;/span&gt;&lt;span class="w"&gt; 
                &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;11&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;.pow&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;121&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;.pow&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;11&lt;/span&gt;&lt;span class="n"&gt;/2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;.pow&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;/&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Evaluating this with the test values, &lt;code&gt;(trial-rational (biginteger 77617) (biginteger 33096)&lt;/code&gt; yielded the fraction &lt;code&gt;-54767/66192&lt;/code&gt;. Coercing that to a &lt;code&gt;double&lt;/code&gt; evaluated to &lt;code&gt;-0.8273960599468214&lt;/code&gt;. I'd gotten the right answer!&lt;/p&gt;

&lt;h1&gt;
  
  
  What Does It Mean?
&lt;/h1&gt;

&lt;p&gt;While this example was clearly meant to show that floating point operations can break in dramatic fashion, let's not chalk it up as just an academic example. Instead, let's think about things that you've written in the past. How many times have you tried to increment something by 0.1 or 0.01, only to have errors accrue? If I add up 0.1 ten times (like you would expect to do in a simulation with 10 Hz data), depending on the precision I get either 1.0000000149011612 or 0.9999999999999999, &lt;strong&gt;not&lt;/strong&gt; 1.0. Accretion of floating point errors just like this caused Patriot missiles to miss their targets in the 90s during the Gulf War, and soldiers died as a result. Regardless of your stance on the military, I think we can all agree that people ought not die because people and machines represent numbers differently.&lt;/p&gt;

&lt;h1&gt;
  
  
  How Did You Get Here from COBOL?
&lt;/h1&gt;

&lt;p&gt;The editorial that got me thinking about all this was diving into why a lot of the financial sector - especially the IRS - was still using COBOL. It turns out that floating point calculations were easier to understand (though more costly to perform at the time) than fixed point calculations, and so they progressively won out. However, when more exact representation of numbers are required, it turns out that fixed point gets the job done much better. I have no clue if the formula at the center of this thought exercise would be --more accurate-- even in the ballpark of the correct answer, so I can't say that it is always going to be better than floating point calcs.&lt;/p&gt;

&lt;h1&gt;
  
  
  What Should We Do?
&lt;/h1&gt;

&lt;p&gt;As it turns out, floating points are &lt;em&gt;generally&lt;/em&gt; accurate enough for most applications, and that accuracy tends to degrade only as you add/multiply more and more numbers that don't have an exact floating point representations. However, if you absolutely have to have accuracy, there are a couple of options.&lt;/p&gt;

&lt;h2&gt;
  
  
  Store as Integers
&lt;/h2&gt;

&lt;p&gt;If you're consistently dealing with a consistent number of decimal places, you could consider storing values as integers with a known scale factor. For example, &lt;a href="https://api.youneedabudget.com/#formats" rel="noopener noreferrer"&gt;You Need a Budget&lt;/a&gt; stores currency values as "milliunits". So (USD) $123.45 is stored as 123450 millidollars. Why not 100? Because some currencies (they list the Jordanian dinar as an example) go to 3 decimal places. Storing things as scaled integers and casting to floating point as needed will increase the accuracy of your calculations in this case.&lt;/p&gt;

&lt;h2&gt;
  
  
  Use Rational Numbers
&lt;/h2&gt;

&lt;p&gt;If you find yourself dealing with fractional values often, it might be worth considering a library for rational numbers. Some languages have them built-in - Haskell and Clojure come immediately to mind, and I'm sure that others exist. Using rational numbers under the hood and only coercing to a floating point when necessary will reduce the amount of error that can creep into your calculations.&lt;/p&gt;

&lt;h2&gt;
  
  
  Symbolic Computing
&lt;/h2&gt;

&lt;p&gt;What if you find yourself dealing with lots of numerical methods? Anyone who has dealt with ordinary differential equation solvers has had to worry about floating point errors in fixed step solvers (Runge-Kutta 4 from Numeric Recipes, anyone?). While you could always migrate to an adaptive step size solver (assuming you have a continuous function), we now have the computing power available to us to perform symbolic computations now. Think of it like &lt;a href="https://wolframalpha.com" rel="noopener noreferrer"&gt;Wolfram Alpha&lt;/a&gt; but built in to your program. Remember the power rule for derivatives? So do symbolic computation engines. &lt;a href="https://www.youtube.com/watch?v=7PoajCqNKpg" rel="noopener noreferrer"&gt;Colin Smith&lt;/a&gt; has ported a lot of Gerald Sussman's ideas from SICP and Structure and Interpretation of Classical Mechanics (SICM) from Scheme into Clojure. If you don't need to go quite that far, &lt;a href="https://codon.com/automatic-differentiation-in-ruby" rel="noopener noreferrer"&gt;Automatic Differentiation&lt;/a&gt; may work out well.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;Floating point calculations are generally accurate enough. If you need better accuracy, thankfully there are several options available that you can explore. Just remember to take the time to determine what level of accuracy you need (or more importantly, what your customers need), and pick the type of calculations that suit those needs best. Good luck, and happy coding!&lt;/p&gt;

</description>
      <category>showdev</category>
      <category>computerscience</category>
      <category>learning</category>
    </item>
    <item>
      <title>What is today's "goto"?</title>
      <dc:creator>Jason Steinhauser</dc:creator>
      <pubDate>Wed, 20 Jun 2018 15:37:15 +0000</pubDate>
      <link>https://dev.to/jdsteinhauser/what-is-todays-goto-2g1c</link>
      <guid>https://dev.to/jdsteinhauser/what-is-todays-goto-2g1c</guid>
      <description>&lt;p&gt;50 years ago, Edgar Dijkstra published a controversial (at the time) editorial entitled &lt;a href="https://homepages.cwi.nl/~storm/teaching/reader/Dijkstra68.pdf"&gt;"Go To Statement Considered Harmful"&lt;/a&gt;. In it, he stated what others had already hinted at - notably, Tony Hoare (creator of ALGOL and &lt;a href="https://www.infoq.com/presentations/Null-References-The-Billion-Dollar-Mistake-Tony-Hoare"&gt;the billion dollar mistake&lt;/a&gt;), and John McCarthy (creator of LISP) - that &lt;code&gt;goto&lt;/code&gt; statements in high-level languages impeded understanding of the code. Since then, we've seen movement away from &lt;code&gt;goto&lt;/code&gt;... but we're still not fully clear of it.&lt;/p&gt;

&lt;p&gt;One of my first projects as a software engineering intern was to take legacy FORTRAN and convert it into true OO C++... and make it a drop-in replacement to be called from other legacy FORTRAN as a full conversion of the codebase was performed. This was around 30 years after Djikstra's editorial and yet... in 1999, my partner and I found &lt;strong&gt;excessive&lt;/strong&gt; used of &lt;code&gt;goto&lt;/code&gt;s in functions that were hundreds of lines long. Having the code printed out, with lines drawn between labels and their respective &lt;code&gt;goto&lt;/code&gt;s, trying to adapt the logic into &lt;code&gt;if..else&lt;/code&gt; and &lt;code&gt;return&lt;/code&gt;, &lt;code&gt;continue&lt;/code&gt;, and &lt;code&gt;break&lt;/code&gt; equivalents took the better part of the summer. &lt;/p&gt;

&lt;p&gt;Unfortunately, that wasn't my last encounter with that dreaded four-letter word: &lt;code&gt;goto&lt;/code&gt;. On one of my former projects, I tried to use my "free time" in long release cycles to try to remove one &lt;code&gt;goto&lt;/code&gt; that we had in a relatively new C# project. It was buried deep inside of a numerical method. I spent the better part of a day trying to figure out how in the world I could rid of it, and... there wasn't a good, clean way. I called up the developer who'd written the code (he had moved to another company, but we're still good friends) and asked him "What in the world were you thinking?" After a long laugh at my misfortune, he said he'd ported that method from C++ at the recommendation of one of our data scientists and that was the &lt;strong&gt;one&lt;/strong&gt; goto he was unable to remove cleanly. And so it stayed, presumably to this day.&lt;/p&gt;

&lt;p&gt;It's actually pretty amazing to me that C#, a language developed around the turn of the millennium, still allowed developers to use &lt;code&gt;goto&lt;/code&gt;! Java actually has &lt;code&gt;goto&lt;/code&gt; as a reserved word, but has it marked as unused. JavaScript, with all its faults, doesn't have goto defined as a keyword. Of course, that has stopped someone from &lt;a href="https://stackoverflow.com/questions/9751207/how-can-i-use-goto-in-javascript"&gt;adding them in&lt;/a&gt; for some reason.&lt;/p&gt;

&lt;p&gt;This kind of led me to an interesting question: what do we do in everyday development that we &lt;strong&gt;can&lt;/strong&gt; do, but &lt;em&gt;shouldn't&lt;/em&gt;? People have since posited that several things are "considered dangerous," from &lt;a href="https://ewontfix.com/11/"&gt;NULL&lt;/a&gt; &lt;a href="https://www.infoq.com/presentations/Null-References-The-Billion-Dollar-Mistake-Tony-Hoare"&gt;references&lt;/a&gt;, to &lt;a href="https://tools.ietf.org/html/draft-itojun-v6ops-v4mapped-harmful-02"&gt;IPv4 wrapped addresses&lt;/a&gt; to even &lt;a href="https://blog.invisiblethings.org/papers/2015/x86_harmful.pdf"&gt;entire chipset families&lt;/a&gt;. I've found one that I agree with (to an extent) about the &lt;a href="https://drewdevault.com/2016/11/24/Electron-considered-harmful.html"&gt;the overuse of Electron&lt;/a&gt; due to its severe bloat.&lt;/p&gt;

&lt;p&gt;What practices and processes do you "consider harmful"? JavaScript everywhere? Measuring the wrong metrics for software quality? Crypto-everything? Let's discuss in the comments!&lt;/p&gt;

</description>
      <category>discuss</category>
      <category>learning</category>
      <category>tips</category>
      <category>history</category>
    </item>
    <item>
      <title>Intro to Property-Based Testing</title>
      <dc:creator>Jason Steinhauser</dc:creator>
      <pubDate>Sat, 09 Jun 2018 01:17:00 +0000</pubDate>
      <link>https://dev.to/jdsteinhauser/intro-to-property-based-testing-2cj8</link>
      <guid>https://dev.to/jdsteinhauser/intro-to-property-based-testing-2cj8</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Property-based tests make statements about the output of your code based on the input, and these statements are verified for many different possible inputs. - Jessica Kerr (&lt;a href="https://twitter.com/jessitron"&gt;@jessitron&lt;/a&gt;)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Property-based testing is generative testing. You do not supply specific example inputs with expected outputs as with unit tests. Instead, you define properties about the code and use a generative-testing engine (e.g., QuickCheck) to create randomized inputs to ensure the defined properties are correct.&lt;/p&gt;

&lt;h1&gt;
  
  
  What is the purpose of generative testing?
&lt;/h1&gt;

&lt;p&gt;Generally speaking, property-based tests require only a few lines of code (like unit tests), but unlike unit tests they test a different set of inputs each time. Because of this, you end up covering more domain space with roughly the same amount of test code.&lt;/p&gt;

&lt;p&gt;Property-based testing also promotes a more in-depth understanding of the function under test. Sure, we know that for addition 2 + 2 = 4, but how can you say that you truly have implemented an addition function correctly with that one example?&lt;/p&gt;

&lt;p&gt;From a business standpoint, a better understanding of the functionality of your code will lead to more accurate determination of requirements being met in your code.&lt;/p&gt;

&lt;h1&gt;
  
  
  Does it replace unit tests?
&lt;/h1&gt;

&lt;p&gt;While it is tempting to say that unit tests could be completely replaced by high quality property-based tests, unit tests still have their place in the software development cycle. Example-based testing is fantastic for early stages of TDD. These serve as anchor points to ensure that your development efforts are proceeding as desired. For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You can ensure that your sine function is generating proper values (&lt;code&gt;sin(0) = 0&lt;/code&gt;, &lt;code&gt;sin(π/2) = 1&lt;/code&gt;, etc.)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;HTTP POST&lt;/code&gt;s to your &lt;code&gt;/login&lt;/code&gt; route without proper authentication headers/cookies results in a &lt;code&gt;401&lt;/code&gt; response code&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;However, eventually these example-based tests end up being passive tests; the tests become part of a regression suite and provide no new information about the functionality. Property-based tests, however, are always active tests as they generate new data each time the test suite is run. This can help root out issues that developers overlook. For example, you may expect that the output of your sine function for any floating-point representation to be in the set [-1,-1], but the developer may not think to test for ±∞ or NaN. To this end, when a failing case is identified, this unexpected error can be used as a future unit test to validate fixes were made. This reason alone makes example-based testing an effective practice for enhancing property-based test suites.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Don't write tests. Generate them!" - John Hughes, co-author of Haskell's original QuickCheck&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  What are some common properties?
&lt;/h1&gt;

&lt;p&gt;If you correlate software functions with mathematical functions, then you can apply some standard mathematical properties to some expected functionality. However, some of those properties aren't as apparent in non-mathematical applications. Here are a few example mathematical properties translated to function properties (with updates from Eric Normand), ignoring performance differences:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Associative – &lt;code&gt;a + (b + c) = (a + b) + c&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;hashmap1.merge(hashmap2.merge(hashmap3)) = (hashmap.merge(hashmap2)).merge(hashmap3)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;list1.append(list2.append(list3)) = (list1.append(list2).append(list3)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Math.max(Math.max(a, b), c) = Math.max(a, Math.max(b, c))&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;(bool1 &amp;amp;&amp;amp; bool2) &amp;amp;&amp;amp; bool3 = bool1 &amp;amp;&amp;amp; (bool2 &amp;amp;&amp;amp; bool3)&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;

&lt;p&gt;Commutative – &lt;code&gt;a + b = b + a&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;users.Sort().Filter(x =&amp;gt; !x.IsAdmin) = (users.Filter(x =&amp;gt; !x.IsAdmin)).Sort()&lt;/code&gt; 
(relocated from Associative)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;image.flipX().flipY() = image.flipY().flipX()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Math.max(a,b) = Math.max(b,a)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;bool1 &amp;amp;&amp;amp; bool2 = bool2 &amp;amp;&amp;amp; bool1&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;average(a,b) = average(b, a)&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;

&lt;p&gt;Distributive – &lt;code&gt;a(b + c) = ab + ac&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;title.ToUpper() + author.ToUpper() = (title + author).ToUpper()&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;

&lt;p&gt;Idempotent – &lt;code&gt;f(a) = f(f(a))&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Math.abs(x) = Math.abs(Math.abs(x))&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;hashmap.merge({a:1}) = hashmap.merge({a:1}).merge({a:1})&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;title.Trim() = title.Trim().Trim()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;list.Sort() = list.Sort().Sort()&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;

&lt;p&gt;Identity – &lt;code&gt;f(a, i) where i is identity value of f = a&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;a + 0 = a&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;a * 1 = a&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;userNames.append([]) = userNames&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;hashmap.merge({}) = hashmap&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;bool1 &amp;amp;&amp;amp; true = bool1&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;

&lt;p&gt;Zero – &lt;code&gt;f(a, z) where z is zero value of f = z&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;a * 0 = 0&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;intersect(valueSet, emptySet) = emptySet&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;bool1 &amp;amp;&amp;amp; false = false&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There are additional, commonly-tested properties that are not necessarily rooted in math, but are equally as useful:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Bilbo Testing (aka, There And Back Again)

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;list = list.Reverse().Reverse()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;obj = JSON.parse(JSON.stringify(obj))&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;No Unexpected Changes

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;list.Length = list.Sort().Length&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Hard to Prove, Easy to Verify

&lt;ul&gt;
&lt;li&gt;Sorting: each element should be greater than or equal to the previous element&lt;/li&gt;
&lt;li&gt;Tokenizing: concatenating tokens with separator interposed should equal the original string, number of tokens should equal number of separators in original string - 1&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Is PBT actually used in the "real world"?
&lt;/h1&gt;

&lt;p&gt;In short, yes. Property-based testing is absolutely used to solve real-world problems.&lt;/p&gt;

&lt;h2&gt;
  
  
  Volvo
&lt;/h2&gt;

&lt;p&gt;Volvo has employed QuviQ's QuickCheck to validate third-party components conforming to communication bus standards. John Hughes and his team analyzed 3k pages of requirements, wrote 20k lines of QuickCheck tests, and applied those properties to 1MM+ lines of vendor code. By checking their properties generated around the specifications, they found 200 issues that had slipped through the test fixtures that the vendors had generated... and 100 of those issues were in the actual specifications themselves. By refining the code analyzed (as well as the defining specifications), property-based testing has saved lives.&lt;/p&gt;

&lt;h2&gt;
  
  
  Clojure
&lt;/h2&gt;

&lt;p&gt;Clojure (a LISP variant on the JVM) uses immutable data structures by default. However, mutable datatypes are available for performance increases. Using property-based testing, an issue was found when converting to/from transient (mutable) and persistent (immutable) structures that none of the example-based tests (re: unit tests). However, property-based testing was able to readily reproduce the issue. A diff patch was provided to Cognitect (the developers/maintainers of Clojure), and it was incorporated in the Clojure 1.6 release.&lt;/p&gt;

&lt;h2&gt;
  
  
  Personal experience
&lt;/h2&gt;

&lt;p&gt;I've also used property-based testing on a project where we were calculating network performance by various metrics (QoS, packet type, packet size, etc.). I had to prove that my packet classification and matching algorithm wouldn't provide false matches, so I set my CI server up to generate 100 million different packets, distributed between the different packet types we were interested in. As of now, we have randomly generated over 10 billion packets and have not had a single false matches.&lt;/p&gt;

&lt;h1&gt;
  
  
  What are some awesome parts to look for in PBT suites?
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Shrinking
&lt;/h2&gt;

&lt;p&gt;While large inputs may produce the errors, several property-based test suites (most QuickCheck variants) will attempt to shrink the input sequence to the smallest possible that will reproduce the error. The smaller the input, the easier it is to reproduce and fix.&lt;/p&gt;

&lt;h2&gt;
  
  
  Race Conditions
&lt;/h2&gt;

&lt;p&gt;Race conditions are notoriously hard to set up via example-based testing. Some PBT suites (notably, QuviQ's QuickCheck in Erlang) can perform many actions in parallel in order to test if the actions, performed in any serial combination, would produce the same output. If the parallelized version can not be matched to a serialized version, then the race condition is identified and shrunk to the smallest possible set of operations to reproduce the error.&lt;/p&gt;

&lt;h2&gt;
  
  
  Custom generators
&lt;/h2&gt;

&lt;p&gt;You may want to limit the input domain you are testing, or have data structures constructed in a particular fashion. Most PBT suites will allow you to create custom generators, and many common custom ones are generally included as well – limiting strings to printable characters, constraining floating point values, etc.&lt;br&gt;
If you're migrating from one algorithm to another, a PBT test suite that passes the same input to both the old and new implementations can be used to ensure that the new implementation produces the same output.&lt;/p&gt;

&lt;h1&gt;
  
  
  Where can I learn more?
&lt;/h1&gt;

&lt;p&gt;Thankfully, there are several good learning resources for property-based testing lurking around on the Internet. Here are some of the ones I've found to be extremely helpful.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://hypothesis.works/articles/quickcheck-in-every-language/"&gt;Hypothesis, Quick Check in Every Language&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=zi0rHwfiX1Q"&gt;John Hughes, Testing the Hard Stuff and Staying Sane&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://propertesting.com"&gt;Fred Herbert, PropEr Testing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blog.jessitron.com/2013/04/property-based-testing-what-is-it.html"&gt;Jessica Kerr, Property-based Testing: What Is It?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://fsharpforfunandprofit.com/posts/property-based-testing/"&gt;Scott Wlaschin, Intro to Property-Based Testing&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>testing</category>
      <category>beginners</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Don't Put Personal Information in Code!</title>
      <dc:creator>Jason Steinhauser</dc:creator>
      <pubDate>Mon, 04 Jun 2018 22:14:52 +0000</pubDate>
      <link>https://dev.to/jdsteinhauser/dont-put-personal-information-in-code-3566</link>
      <guid>https://dev.to/jdsteinhauser/dont-put-personal-information-in-code-3566</guid>
      <description>&lt;p&gt;Normally, I wouldn't cringe during a code review when I see&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var testValue = 716.1976;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;BUT&lt;/em&gt; when I include the rest of the line...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var testValue = 716.1976;      // Carl's birthday
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Well, then I start to question what in the world you were thinking! &lt;em&gt;(Note: some names and dates have been changed to protect the innocent)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Most online tutorials involving DevOps or API keys will warn you to not include keys and passwords in your repo; those are the sort of things that are best relegated to environment variables (or some other secure method). But usually you don't come across tutorials warning to exclude Personally Identifiable Information (PII).&lt;/p&gt;

&lt;h1&gt;
  
  
  What is PII?
&lt;/h1&gt;

&lt;p&gt;In short, PII is anything that you can use to figure out who somebody is. You usually hear it in identity theft discussion. Several things are included as PII, such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Birth date&lt;/li&gt;
&lt;li&gt;Home city&lt;/li&gt;
&lt;li&gt;Social Security Number (in the U.S.)&lt;/li&gt;
&lt;li&gt;High school&lt;/li&gt;
&lt;li&gt;Location of birth&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You know all those security questions for password recovery? Yeah, all of that is PII.&lt;/p&gt;

&lt;h1&gt;
  
  
  What can you do with that?
&lt;/h1&gt;

&lt;p&gt;Well, there are several websites that, given a few tidbits of your personal info, can be used to find out all sorts of things. Current and past addresses. Names of relatives. Former/maiden names. All with a few simple keystrokes on &lt;a href="https://www.pipl.com/"&gt;Pipl&lt;/a&gt; or &lt;a href="https://www.intelius.com/"&gt;Intelius&lt;/a&gt; and you can find a lot of information.&lt;/p&gt;

&lt;p&gt;Going back to the comment that started all of this, I didn't have a surname for "Carl," but I did have the developer's last name thanks to a comment block at the top of the file (not to mention, a commit history). A quick search got me his address, Facebook profile, occupation (a nurse!), and an age that corroborated his birthday in the code.&lt;/p&gt;

&lt;h1&gt;
  
  
  Did you send "Carl" a birthday card?
&lt;/h1&gt;

&lt;p&gt;I totally did... in my mind. But then, I played through how freaky that would be for Carl, and how mad he would be at "Lucy" despite no ill intentions. I didn't want to fracture any relationships solely to make a point... But "Lucy" is now well aware of the ramifications.&lt;/p&gt;

&lt;h1&gt;
  
  
  Is this an isolated incident?
&lt;/h1&gt;

&lt;p&gt;I know people that have hidden spouse's birthdays in code as "magic" or "test" values... but they've never explicitly stated that in comments like "Lucy" did. Has anyone else come across any issue like this before? How did you resolve it? And how would you have liked to resolve it?&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Please don't use real names/info if at all possible!&lt;/em&gt;&lt;/p&gt;

</description>
      <category>security</category>
    </item>
  </channel>
</rss>
