<?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: Peter Aba</title>
    <description>The latest articles on DEV Community by Peter Aba (@peteraba).</description>
    <link>https://dev.to/peteraba</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%2F9527%2F6ee8e673-7cbf-4032-ab4c-9569f0387a46.png</url>
      <title>DEV Community: Peter Aba</title>
      <link>https://dev.to/peteraba</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/peteraba"/>
    <language>en</language>
    <item>
      <title>Revised: The danger of detached management</title>
      <dc:creator>Peter Aba</dc:creator>
      <pubDate>Fri, 08 Dec 2023 13:42:00 +0000</pubDate>
      <link>https://dev.to/peteraba/revised-the-danger-of-detached-management-4gp5</link>
      <guid>https://dev.to/peteraba/revised-the-danger-of-detached-management-4gp5</guid>
      <description>&lt;p&gt;This post was originally posted on my blog. The original version you can find &lt;a href="https://peteraba.com/blog/revised-the-danger-of-detached-management/"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Preface
&lt;/h2&gt;

&lt;p&gt;4.5 years ago I wrote a little blog post that I’d like to republish, after spending 4 more years in management. Note that at the time of writing of the original piece, I’ve had roughly 3 years of management experience and I had managed about 5-7 people in total. Since then, I spent another 4 years in management and have managed another 15-20 people at least. Below is a slightly revised version of the original post, which is still available &lt;a href="https://peteraba.com/blog/the-danger-of-detached-management/"&gt;here&lt;/a&gt;. If you’ve read that post, you can script straight to the solutions section.&lt;/p&gt;

&lt;h2&gt;
  
  
  Scenario - The good parts
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--b1LkYQr_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://peteraba.com/media/revised-the-danger-of-detached-management/happy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--b1LkYQr_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://peteraba.com/media/revised-the-danger-of-detached-management/happy.png" alt="The good parts" title="Happy unicorns and fluffy mythical creatures in front of a rainbow" width="800" height="457"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So let's say you have a software feature team made up of a handful of focused and experienced professionals and perhaps a few juniors just for good measure. Let's also imagine that this is true for both the engineers and the product managers. Let's say they together manage to implement a very fruitful culture where things to deliver and their priorities are always clear. Things also get delivered more or less on time and technical debt is also kept under control. Sounds great so far, right?&lt;/p&gt;

&lt;p&gt;To color that picture a bit further, let's also imagine that this imaginary team has some process in place to improve their internal processes and discuss pressing issues. For example, they might meet regularly for &lt;a href="https://www.wikiwand.com/en/Kaizen"&gt;Kaizen meetings&lt;/a&gt; to keep things generally improving.&lt;/p&gt;

&lt;p&gt;Now let's say that said team also has a lead, but that lead is mostly involved in high level discussions, long term plans and in some cases aligning with other teams on said long term plans and their execution. She has her calendar full of meetings with stakeholders and upper management while she also takes part in the hiring process.&lt;/p&gt;

&lt;h2&gt;
  
  
  Impact - The bad parts
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--dxOz4y5B--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://peteraba.com/media/revised-the-danger-of-detached-management/sad.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--dxOz4y5B--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://peteraba.com/media/revised-the-danger-of-detached-management/sad.png" alt="The bad parts" title="Gloomy image of unicorns and fluffy mythical creatures looking for food" width="800" height="457"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It's obvious that she lifts a lot of weight off the team's back, practically enabling them to focus on the product and engineering tasks. I suppose this should still sound great, there's hardly anything to boost team performance more than cutting out distractions. The problems start when she decides not to have one-on-one's with her team members since she's not really part of the team's day-to-day work. She also considers attending stand-ups and Kaizens to be optional for her. This however can render her practically detached from her team.&lt;/p&gt;

&lt;p&gt;These actions can and will in-effect the team in a few ways.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Hard to get help
&lt;/h3&gt;

&lt;p&gt;Perhaps least importantly, if and when there is a problem that the team can not solve themselves, it will be harder to get the lead to make good decisions or even weigh in, because first she’s not used to weighing in on team issues, and second she might lack some important context which is not always easy to obtain on the spot.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Awkward team activities
&lt;/h3&gt;

&lt;p&gt;Team members may also feel somewhat awkward or even anxious around a detached lead as she may be seen as some sort of outsider without sufficient amount of regular interaction. As a consequence, this may also poison team activities such as team events to some extent, simply because some might feel less ready to open up in front of someone who has not earned their trust. This is probably more of a problem for introverted team members, but still worth mentioning.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Lack of trust
&lt;/h3&gt;

&lt;p&gt;Lack of touch can also cause a lack of transparency and team members might start wondering what their lead is doing most of her time and whether she has enough insight into the teams' work to be able to properly represent them in long term planning sessions with other managers.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Understanding team performance
&lt;/h3&gt;

&lt;p&gt;Let’s say the &lt;a href="https://en.wikipedia.org/wiki/Objectives_and_key_results"&gt;OKR&lt;/a&gt; says product X will be delivered by the end of the quarter but then some urgent request comes up that pushes the team to deliver product Y first. Or perhaps there’s also a dependency on team Z to deliver product X and they’re late. Either way at the end of the business quarter product X is not delivered, therefore a detached manager may think that the overall performance of our imaginary team is less than great. Needless to say, technical improvements throughout the quarter might go unnoticed even more easily of course.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Understanding individual performance
&lt;/h3&gt;

&lt;p&gt;Team members might be judged on weird measures like being typically vocal or less vocal during selected meetings attended by the lead. Imagine if that was being used as a deciding factor for your relative performance compared to the team average. This can of course further lead to team members getting unfair and unhelpful promotion feedback, which will inevitably force valuable employees to seek better treatment and potentially promotions elsewhere.&lt;/p&gt;

&lt;p&gt;Another common consequence is looking at somewhat artificial numbers like tickets reviewed, tickets closed, number of lines changed, etc. (While I don't think I was ever really detached from my teams, I'm also guilty of this, I plan to write about this in some later post.) &lt;/p&gt;

&lt;h3&gt;
  
  
  6. Creating legacy systems
&lt;/h3&gt;

&lt;p&gt;Possibly the most important consequence of such unfair feedback is that people who don't quit will typically adjust. When technical greatness is not appreciated, people will simply focus on product delivery and quality will naturally decline. In software development this means that eventually the system will become a mess that no one wants to touch anymore. When this happens, the lead will have her job failed as hard as possible, no matter how great a job she does doing her day-to-day job.&lt;/p&gt;

&lt;p&gt;When closed tickets and similar are used to measure performance, engineers will adjust, and in extreme cases they might create a new ticket for the tiniest of things, which will obviously make them less performant as they'll spend more time with administration, then development. (More about that in some later post.)&lt;/p&gt;

&lt;p&gt;I imagine most of the above would apply to any delivery team, in or outside of IT, however with software feature teams there's an extra risk: Whether the product delivered is of poor or great quality can be very hard to tell. Yes, if the live system is broken every second day, that's a clear sign. Or in case the UI is not usable, it's easy to assume that the code is one big pile of stinky brown material. However, the complexity of even the simplest software systems is still more complex than most other products in life and this means even software that does a decent job on the surface might be less than pleasant to work on as an engineer. When a leader is detached from the team, there's a good chance that she'll only realise the poor state of the system her team manages when people are already leaving or have left as a consequence. (This tends to be the story behind most, if not all, "legacy-refactoring" projects.)&lt;/p&gt;

&lt;h2&gt;
  
  
  Solutions
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--XElK4ZS3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://peteraba.com/media/revised-the-danger-of-detached-management/hope.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--XElK4ZS3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://peteraba.com/media/revised-the-danger-of-detached-management/hope.png" alt="Solutions" title="Asian girl holding a glowing crystal ball" width="800" height="457"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here's what I think our imaginary lead should do:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;She should create rapport with her team members. Regular one-on-ones should be considered a foundation for that. If applicable, she should even schedule regular skip-level one-on-ones.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;She should make sure to be present in some team meetings regularly which shows that she cares about team dynamics. (In the above scenario, this would mostly mean the Kaizen meetings.) It's okay for her to weigh in on issues as well, but it's more important to offer her support in implementing some of the solutions best fit for her capabilities, expertise and pay grade. There's no need to take all the team issues upon herself of course, good professionals don't need babysitting, but being ready to help can go a long way.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;She should also make sure that the team knows what she's doing day-to-day. Of course this does not mean that she needs to report everything to the team every day, but letting the team know regularly what she's focusing on, what problems are on her plate is usually appreciated.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Attend team events and team celebrations religiously. The team should always be aware that their lead is a human being, someone that can relate to their issues and is there for them in bad and good times alike.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I guess being a manager is not easy, and one of the toughest things about it is that sometimes there's very little difference between being great or bad at it.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note: The images for this post were generated by DALL-E. No unicorns, pegasuses or any other beings were harmed in the process.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>management</category>
    </item>
    <item>
      <title>10 years later</title>
      <dc:creator>Peter Aba</dc:creator>
      <pubDate>Tue, 05 Dec 2023 15:26:12 +0000</pubDate>
      <link>https://dev.to/peteraba/10-years-later-3k39</link>
      <guid>https://dev.to/peteraba/10-years-later-3k39</guid>
      <description>&lt;p&gt;The second 10 years or so in a developer's life. Mine to be precise.&lt;/p&gt;

&lt;p&gt;It touches on going from PHP to Go, but it's certainly a very personal post, which may not have a lot of instant take-aways. I hope some people will still enjoy it:&lt;br&gt;
&lt;a href="https://peteraba.com/blog/10-years-later/"&gt;https://peteraba.com/blog/10-years-later/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>php</category>
      <category>go</category>
      <category>career</category>
    </item>
    <item>
      <title>3 recent posts on tech management I loved</title>
      <dc:creator>Peter Aba</dc:creator>
      <pubDate>Tue, 06 Aug 2019 23:20:05 +0000</pubDate>
      <link>https://dev.to/peteraba/3-recent-posts-on-tech-management-i-loved-44ae</link>
      <guid>https://dev.to/peteraba/3-recent-posts-on-tech-management-i-loved-44ae</guid>
      <description>&lt;p&gt;This post was first published on my &lt;a href="https://peteraba.com/blog/3-recent-posts-on-tech-management-i-loved"&gt;blog&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Have you ever read a blog post so great, that you thought everyone  should read it? I sure have, more than once, but I found that in most  cases "everyone" just didn't care. Today however I decided to try  something new. I'll cherry pick a few posts from the recent  years by topic and share them as a single blog post. I'll throw in some of  my  own comments and act like I've actually done something creative today.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;The article that pushed me to create this post was &lt;a href="https://medium.com/better-programming/the-3-capacities-of-a-good-manager-a950e798aaaa"&gt;"The 3 Capacities of a Good Manager"&lt;/a&gt;. It details 3 ways how bright engineers can end up as  less than great managers. It also explains how to identify each way by  symptoms. It describes how managers need to think about their roles. Finally, it provides managers with a simple framework to assess themselves. To some extent I felt like I was reading an excellent excerpt of a book, but somehow it felt complete at the same time. &lt;a href="https://medium.com/@ropstenrich"&gt;Matthew Werner&lt;/a&gt; did a great job here, I'll re-read this post many times for sure.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;I really appreciated &lt;a href="https://charity.wtf/2017/05/11/the-engineer-manager-pendulum/"&gt;"The Engineer/Manager Pendulum"&lt;/a&gt; by &lt;a href="https://charity.wtf/author/mipsytipsy/"&gt;mipsytipsy&lt;/a&gt;. In this post she argues that tech managers do their jobs best within the first 2 to 3 years after being removed from tech, and that people should generally go back and forth between engineering and management roles.&lt;br&gt;
To be honest my motivations were slightly different, but I have become a tech lead for 3 years, only to become an individual contributor again. I grew to understand how I may have become a better leader / manager by not being one for a while. Of course, I understand that many in higher management may do well way after said 2 to 3 years. Still, chances are, they won't be doing a lot of tech at that point. I'd also argue that oftentimes any experienced manager could do a good job as CTO, except at times it's useful to actually understand the techies.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Finally, I loved &lt;a href="https://medium.com/@skamille"&gt;Camille Fournier&lt;/a&gt;'s &lt;a href="https://medium.com/@skamille/i-hate-manager-readmes-20a0dd9a70d0"&gt;"I hate manager READMEs"&lt;/a&gt;. In this post she argues that manager READMEs might be well-intended, but they scream &lt;code&gt;"I'm the boss here"&lt;/code&gt;. They also sound like their authors are making weak excuses for their own weaknesses, quirks, and challenges. They can even suggest their readers that they're at fault if they don't know how to "handle" said managers properly.&lt;br&gt;
Truth is, I also liked &lt;a href="https://hackernoon.com/12-manager-readmes-from-silicon-valleys-top-tech-companies-26588a660afe"&gt;"12 “Manager READMEs” from Silicon Valley’s Top Tech Companies"&lt;/a&gt;, but what I liked about them was the insight into how these people think. I  never felt that it would be great to read such thing from my manager.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Okay, so that's 3 posts, therefore we're done. But since I just can't stop there, I'll add 3 more very briefly:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;I just found out today that as for everything in tech, there's an &lt;strong&gt;awesome&lt;/strong&gt; &lt;a href="https://github.com/LappleApple/awesome-leading-and-managing"&gt;"awesome list" for management&lt;/a&gt; too. I'm especially stoked about the &lt;a href="https://github.com/LappleApple/awesome-leading-and-managing/blob/master/Meetings-and-Time-Management.md"&gt;Meetings and Time Management&lt;/a&gt; page, which is a topic I definitely want to learn more about.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://dev.to/bndr/switching-from-engineering-to-management-56hf"&gt;Switching from Engineering to Management&lt;/a&gt; is a good read for people who need to decide whether to make a career shift to management or not.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A while back I wrote about &lt;a href="https://peteraba.com/blog/the-danger-of-detached-management/"&gt;the dangers of detached management&lt;/a&gt;, which might be a nice addition to the first post: "The 3 Capacities of a Good Manager". Obviously, I'm biased though.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;What are your favorites?&lt;/p&gt;

</description>
      <category>management</category>
    </item>
    <item>
      <title>Test running Parcel with Elm 0.19 and Furtive (with Sass)</title>
      <dc:creator>Peter Aba</dc:creator>
      <pubDate>Mon, 17 Sep 2018 12:26:45 +0000</pubDate>
      <link>https://dev.to/peteraba/test-running-parcel-with-elm-019-and-furtive-with-sass-5e8d</link>
      <guid>https://dev.to/peteraba/test-running-parcel-with-elm-019-and-furtive-with-sass-5e8d</guid>
      <description>&lt;h2&gt;
  
  
  Premise
&lt;/h2&gt;

&lt;p&gt;So &lt;a href="https://dev.to/ben"&gt;Ben&lt;/a&gt; started a &lt;a href="https://dev.to/ben/im-having-some-not-this-again-feelings-with-parcel-how-should-i-be-feeling-about-this-tool-241p"&gt;discussion about Parcel&lt;/a&gt; the other day. I didn't participate in it, mainly because I've never even heard of Parcel before.&lt;/p&gt;

&lt;p&gt;I did however open up the &lt;a href="https://parceljs.org/"&gt;project website&lt;/a&gt; and it got me really interested for two reasons: First it seemed much simpler than webpack, second it promised to be much faster than webpack. Now my webpack experience is just slightly above what I'd describe as advanced beginner even though I already started a few dozen projects using it and watched many courses using it both on Youtube and Udemy. Most of the time however I just started with copying something that others crafted and adjusted it to my needs. I wouldn't go as far as to say that I had no idea what I was doing, but I certainly didn't master the tool.&lt;br&gt;
I have copied webpack setups of some really knowledgeable people in the past, but I always felt that that the end result is somewhat clumsy and extremely slow, therefore I decided to give Parcel a shot. To make things more interesting, I decided to try to set it up with &lt;a href="https://elm-lang.org/"&gt;Elm&lt;/a&gt; &lt;a href="https://elm-lang.org/blog/small-assets-without-the-headache"&gt;0.19&lt;/a&gt; and &lt;a href="http://furtive.co"&gt;Furtive&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I literally just installed the tool this morning so I will not try to assess its performance in real-life projects but it sure feels much faster so far. What I will say however is that it was a breeze setting it up, even for me, even for such a weird setup. Let me drive you through:&lt;/p&gt;
&lt;h2&gt;
  
  
  Path #1: Quick and dirty way (&amp;lt;2 mins)
&lt;/h2&gt;
&lt;h3&gt;
  
  
  1. Clone my repo
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/peteraba/elm0.19-furtive-parcel.git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  2. Install the missing dependencies
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yarn install
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Path #2: DIY (~10 mins)
&lt;/h2&gt;
&lt;h3&gt;
  
  
  1. Create a new project directory
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir &lt;/span&gt;path/to/your/project
&lt;span class="nb"&gt;cd &lt;/span&gt;path/to/your/project
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  2. Initialize your project
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn init &lt;span class="nt"&gt;-y&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  3. Add Furtive
&lt;/h3&gt;

&lt;p&gt;For this project I decided to choose a tiny frontend framework called &lt;a href="http://furtive.co"&gt;Furtive&lt;/a&gt; to keep things fast. I could have stayed with just including a minimized css from a CDN but I wanted to test Parcel so I decided to add Sass compilation instead:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn add node-sass
yarn add furtive
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4. Add Elm support
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;UPDATE (2018-09-20)&lt;/em&gt;:&lt;/p&gt;

&lt;p&gt;This part has become much easier as 0.19 support is now added to &lt;a href="https://github.com/ssuman/parcel-plugin-elm"&gt;parcel-plugin-elm&lt;/a&gt;, simply add it with yarn:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn add parcel-plugin-elm
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;del&gt;Now this part was a bit tricky, because I wanted to use the latest Elm 0.19 and &lt;a href="https://github.com/ssuman/parcel-plugin-elm"&gt;the main Elm plugin for Parcel&lt;/a&gt; is outdated. There is a &lt;a href="https://github.com/ssuman/parcel-plugin-elm/pull/10"&gt;pull request&lt;/a&gt; from &lt;a href="https://twitter.com/benpaulhanna"&gt;Ben Hanna&lt;/a&gt; for 0.19 but it's not yet merged. Also, I'm not really a yarn expert, so I had to look up how to use his code instead of the official one. Okay, it only took about 2 minutes, but still..&lt;/del&gt;&lt;/p&gt;

&lt;p&gt;&lt;del&gt;So basically I downloaded Ben's code and extracted it to a directory called &lt;code&gt;outdated&lt;/code&gt; and added it via yarn (&lt;em&gt;yarn add file:./outdated/parcel-plugin-elm&lt;/em&gt;). This should remind me to use the main repo once the changes get merged.&lt;/del&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Initialize your elm project
&lt;/h3&gt;

&lt;p&gt;Parcel still doesn't know about Elm, so we should probably install it locally:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn add elm@^0.19.0-bugfix2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then we can also initialize our Elm project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;yes&lt;/span&gt; | ./node_modules/.bin/elm init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  &lt;em&gt;Optional:&lt;/em&gt; global Elm install
&lt;/h4&gt;

&lt;p&gt;In case you don't have Elm 0.19 installed but want to toy with it, please find the &lt;a href="https://guide.elm-lang.org/install.html"&gt;installation instructions&lt;/a&gt; in the &lt;a href="https://guide.elm-lang.org/"&gt;Official Guide&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. Create project files
&lt;/h3&gt;

&lt;h4&gt;
  
  
  &lt;code&gt;sass/main.scss&lt;/code&gt;
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sass"&gt;&lt;code&gt;&lt;span class="nv"&gt;$font-family&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'Lato'&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Helvetica&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;sans-serif&lt;/span&gt;&lt;span class="err"&gt;;&lt;/span&gt;
&lt;span class="nv"&gt;$dark-gray&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mh"&gt;#222&lt;/span&gt;&lt;span class="err"&gt;;&lt;/span&gt;
&lt;span class="nv"&gt;$text-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;$dark-gray&lt;/span&gt;&lt;span class="err"&gt;;&lt;/span&gt;
&lt;span class="nv"&gt;$body-bg&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mh"&gt;#fafafa&lt;/span&gt;&lt;span class="err"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;@import&lt;/span&gt; &lt;span class="s"&gt;"node_modules/furtive/scss/all.scss";&lt;/span&gt;

&lt;span class="nc"&gt;.elm-container&lt;/span&gt; &lt;span class="err"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;5px&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="err"&gt;;&lt;/span&gt;

    &lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="err"&gt;{&lt;/span&gt;
        &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;inline-block&lt;/span&gt;&lt;span class="err"&gt;;&lt;/span&gt;
        &lt;span class="nl"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2px&lt;/span&gt;&lt;span class="err"&gt;;&lt;/span&gt;
    &lt;span class="err"&gt;}&lt;/span&gt;
&lt;span class="err"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  &lt;code&gt;src/Main.elm&lt;/code&gt;:
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elm"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;Browser&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;Html&lt;/span&gt; &lt;span class="k"&gt;exposing&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Html&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;button&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;div&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;Html&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Events&lt;/span&gt; &lt;span class="k"&gt;exposing&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;Html&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Attributes&lt;/span&gt; &lt;span class="k"&gt;exposing&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;main&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="kt"&gt;Browser&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sandbox&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;init&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="n"&gt;update&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;update&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;view&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;view&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="kt"&gt;Msg&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;Increment&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kt"&gt;Decrement&lt;/span&gt;

&lt;span class="n"&gt;update&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt;
    &lt;span class="kt"&gt;Increment&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
      &lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;

    &lt;span class="kt"&gt;Decrement&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
      &lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;

&lt;span class="n"&gt;view&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="n"&gt;div&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;elm-container txt--center"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;button&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;onClick&lt;/span&gt; &lt;span class="kt"&gt;Decrement&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;class&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;btn btn--blue btn--s"&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&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;div&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fromInt&lt;/span&gt; &lt;span class="n"&gt;model&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="n"&gt;button&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;onClick&lt;/span&gt; &lt;span class="kt"&gt;Increment&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;class&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;btn btn--green btn--s"&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="s2"&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;h4&gt;
  
  
  &lt;code&gt;index.html&lt;/code&gt;:
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;html&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;Hello, Parcel!&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"./index.js"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;main&amp;gt;&amp;lt;/main&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  &lt;code&gt;index.js&lt;/code&gt;:
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./sass/main.scss&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;hot&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;hot&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dispose&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="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;location&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reload&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;import&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./src/Main.elm&lt;/span&gt;&lt;span class="dl"&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;then&lt;/span&gt;&lt;span class="p"&gt;(({&lt;/span&gt; &lt;span class="nx"&gt;Elm&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="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;node&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;main&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;Elm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;init&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;node&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;node&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;&lt;em&gt;Note:&lt;/em&gt; The if part in the middle is a workaround for a Parcel issue, might become obsolete soon.&lt;/p&gt;

&lt;h2&gt;
  
  
  End result
&lt;/h2&gt;

&lt;p&gt;Okay, now we have everything in place, let's give it a go:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;➤ parcel index.html
Server running at http://localhost:1234 
Success! Compiled 1 module.                                          
Success! Compiled 1 module.                                          
✨  Built in 2.23s.
^C

➤ parcel index.html
Server running at http://localhost:1234 
✨  Built in 724ms.
^C
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Less than 3 seconds without cache, less than a second with cache, hot reload works as expected. What is more important however is that &lt;strong&gt;I didn't have to edit any configuration files&lt;/strong&gt;.&lt;/p&gt;

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

&lt;p&gt;I have to say I'm really impressed with Parcel so far. Its getting started guide is quite short, but it still allowed me to achieve what I wanted without getting confused or stuck even once. I think this might just be the beginning of a beautiful friendship...&lt;/p&gt;

</description>
      <category>elm</category>
      <category>furtive</category>
      <category>parcel</category>
    </item>
    <item>
      <title>Will PHP save your startup?</title>
      <dc:creator>Peter Aba</dc:creator>
      <pubDate>Sun, 09 Sep 2018 15:34:33 +0000</pubDate>
      <link>https://dev.to/peteraba/will-php-save-your-startup-4b30</link>
      <guid>https://dev.to/peteraba/will-php-save-your-startup-4b30</guid>
      <description>&lt;p&gt;About two months ago &lt;a href="https://medium.com/@alexkatrompas"&gt;Alexander Katrompas&lt;/a&gt; wrote a post on medium titled &lt;a href="https://medium.com/@alexkatrompas/java-will-kill-your-startup-php-will-save-it-f3051968145d"&gt;Java will kill your startup. PHP will save it.&lt;/a&gt;. I already posted a short response as a &lt;a href="https://medium.com/@peteraba/disclaimer-ive-done-over-15-years-of-php-development-currently-mostly-work-with-go-but-i-love-9f42699430e1"&gt;comment there&lt;/a&gt;, but I thought it might be worthwhile to elaborate on that a little.&lt;/p&gt;

&lt;p&gt;Again, if there's anything of which I can call myself an expert, that would probably be PHP. I don't really like PHP anymore, I don't write a lot of PHP anymore, but I do know it very well.&lt;/p&gt;

&lt;h2&gt;
  
  
  The arguments
&lt;/h2&gt;

&lt;p&gt;Just to quickly recap, here are Alexander's arguments in a nutshell:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Many large-scale projects started off being written in PHP and over 80% of the top 10M web sites use PHP.&lt;/li&gt;
&lt;li&gt;PHP programmers are more plentiful and cheaper than Java programmers. (web-only)&lt;/li&gt;
&lt;li&gt;PHP has excellent performance and it continuously gets better and in-practice easily rivals compiled languages.&lt;/li&gt;
&lt;li&gt;PHP application time to market is a fraction of Java EE applications.&lt;/li&gt;
&lt;li&gt;PHP is not a “scripting” language (whatever that means), it’s a fully function, object oriented, web powerhouse.&lt;/li&gt;
&lt;li&gt;PHP 7.x is a vast improvement over previous versions and 8.0 promises to surpass all expectations.&lt;/li&gt;
&lt;li&gt;Frameworks are plentiful and powerful. The power, popularity, and dominance of Symfony and Laravel is undeniable.&lt;/li&gt;
&lt;li&gt;WordPress (PHP driven) is the dominant CMS with almost 60% market share. The next top 5 CMSs, are all PHP driven.&lt;/li&gt;
&lt;li&gt;PHP is simply made for the web. No extra servers, processors, hacks, tricks needed. It is literally one with your web server.&lt;/li&gt;
&lt;li&gt;Most dominant open source e-commerce systems are all written in PHP. (WooCommerce, Magento, OpenCart, PrestaShop, ZenCart, Drupal, Joomla, OsCommerce, and on, and on, and on…&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  My comments on the arguments
&lt;/h2&gt;

&lt;p&gt;As the title and the above list shows, Alexander was comparing PHP to Java EE. Now I have very little knowledge on the latter, but I can tell you that for most startups PHP is no longer the best choice.&lt;/p&gt;

&lt;p&gt;Just to clarify, there are a few points that I strongly disagree with. In my opinion:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;PHP is a scripting language. It does have decent OO features, but that has nothing to do with it being a scripting language. What it does affect is first that not all of your code will be loaded into memory when a request is served (good), that all of your errors will be runtime errors (bad) and of course that your code will be interpreted on an as-needed basis instead of having it all compiled to byte code or some intermediate language. &lt;em&gt;Sidenote:&lt;/em&gt; Alexander mentions "function, .. oriented" there as well, but I'm hoping that was nothing more then some copy-paste mistake.&lt;/li&gt;
&lt;li&gt;PHP 7 is a step in the right direction, but it wasn't brave enough to really clean up the API and I doubt PHP 8 will be.&lt;/li&gt;
&lt;li&gt;PHP is made for the web but there are extra servers, processors, hacks and tricks needed. It is absolutely not one with your web server and if you've been close enough to operational teams of big PHP projects you'll know how much a pain in the ass it can be. Not that it's a PHP-specific thing but just to get things straight. I'm guessing that Alexander was referring to the PHP apache extension, but that's not something I've seen running live in the last 10 years and probably you shouldn't either...&lt;/li&gt;
&lt;li&gt;PHP is fast enough for serving as the backend of an API. If you need true performance for complicated stuff (databases, crypto-mining, etc.) then it probably isn't.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Still, with all these corrections I think the problem lies in what's missing from the list, not what's in there.&lt;/p&gt;

&lt;p&gt;First of all if your startup is about selling flip-flops, then by all means go ahead, install Magento and off you go. You'll still be able to ditch it for something more flexible when you actually start to make money and feel the pain of running an over-engineered, yet rigid system. (wink-wink &lt;a href="https://www.zalando.de/"&gt;Zalando&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;If however you want to build something that's a true &lt;a href="https://www.amazon.com/Zero-One-Notes-Startups-Future/dp/0804139296"&gt;Zero-to-One type&lt;/a&gt; startup, you need a system that gives you agility:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Fast to learn.&lt;/li&gt;
&lt;li&gt;Fast to prototype in. &lt;/li&gt;
&lt;li&gt;Straight-forward to harden.&lt;/li&gt;
&lt;li&gt;Enables fast and safe refactoring.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Plus I'd consider these things as nice-to-haves for startups but absolutely must-haves for mature companies:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Maintainable&lt;/li&gt;
&lt;li&gt;Secure&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;And finally two nice-to-haves for the most successful startups, the corporations:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Exciting&lt;/li&gt;
&lt;li&gt;Trustworthy&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Fast to prototype in
&lt;/h3&gt;

&lt;p&gt;Now I have the feeling that Alexander focused way too much on prototyping for which PHP is quite good indeed. Not the best, but certainly decent, probably better than the famously verbose Java is.&lt;/p&gt;

&lt;p&gt;Just to clarify, Java is famous for being verbose but I wouldn't call PHP concise either. It's not a really a criticism, simply a statement. (In comparison Python and Ruby code tend to be significantly shorter and easier to read than equivalent PHP code.)&lt;/p&gt;

&lt;h3&gt;
  
  
  Straight-forward to harden
&lt;/h3&gt;

&lt;p&gt;When it comes to hardening, your only real choice is adding more tests because the type system is just very hard to rely on. You can harden your own code ensuring that you use types everywhere (you'll need at least 7.1 to really do that) and marking each of your files to be type checked strictly, but it's a hassle, error prone and it's tough to get all your dependencies to provide similar safety. Also, if you end up using any of the popular frameworks (Symfony, Laravel, Zend, etc) you're out of luck, as they all -support 5.x still- (Correction: they require PHP 7 lately, but don't enforce strict type checking). And the truth is that 99.9% of all PHP teams will decide to use these tools because of familiarity and the size of their ecosystems.&lt;/p&gt;

&lt;p&gt;If the choices only came down to PHP and Java, I'm sure Java would easily win here. It still suffers from the &lt;a href="https://www.wikiwand.com/en/Null_pointer"&gt;billion dollar mistake&lt;/a&gt;, but at least the compiler will yell at you if you change your API in one file and forgot to update it in another. In PHP you'll just hope it will be caught in a test or during code review, given you have those. &lt;strong&gt;&lt;em&gt;(Spoiler alert!&lt;/em&gt;&lt;/strong&gt; &lt;em&gt;In most start-ups you don't, because you know, they take time and therefore money&lt;/em&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Enables fast and safe refactoring
&lt;/h3&gt;

&lt;p&gt;When it comes to fast and safe refactoring there's hardly anything worse than PHP, so Java would win easily, mainly still due to its type safety and the compiler being able to check your whole application by default. Again Java is probably far from the best choice as some functional and functional-inspired languages will go further in this regard, but I think it should already be decent.&lt;/p&gt;

&lt;h3&gt;
  
  
  Fast to learn
&lt;/h3&gt;

&lt;p&gt;This is the final point in the must-have section for startups, but it can be very important in some cases. Alexander avoids this problem by saying it's cheaper to hire PHP devs and Java devs. While it's probably true, the difference likely not to be comparable to choosing the wrong language and having to rewrite everything later. Yes, as a startup you might want to cut that 20% on IT salary expenses, but you should understand that you're playing with fire. I myself would rather risk running out of money 2-10% earlier then risking years of suffering of wrong choices early on.&lt;/p&gt;

&lt;p&gt;So if we agree with the premise that you can always bring in people already familiar with your stack then Alexander was probably right, but the difference shouldn't make or brake your startup.&lt;/p&gt;

&lt;p&gt;I'd however argue that I'd prefer working with a language that less people know but is very easy to learn. That way you can get the best domain experts bring tremendous value and you never risk of running out of local talents because any engineer you'd get would be able to get productive in a few weeks.&lt;/p&gt;

&lt;p&gt;Now this is where I'm fairly sure both PHP and Java suck, and they actually suck big time. Both these languages try to satisfy everyone, putting all sorts of features into the language and both of these have huge-huge ecosystems which take years and perhaps decades to fully oversee and takes tons and tons of reading to make sure you understand best practices and things to avoid. Not to mention how much terrible advice must be out there for both of these languages... Still, as a beginner searching for good answers must be a nightmare both for Java and PHP.&lt;/p&gt;

&lt;p&gt;In contrast many newer languages try to keep things straight forward. Go is the most obvious example here but Elm and Rust can also simplify many things even if they bring in some concepts which are harder to grasp at first.&lt;/p&gt;

&lt;p&gt;Ecosystems of these new languages are also cleaner and in the case of Go most things you'll use are in the standard library, tested at Google-scale and quality that you can easily bet your company on. The community also lives and breaths the &lt;a href="https://homepage.cs.uri.edu/~thenry/resources/unix_art/ch01s06.html"&gt;Unix-philosophy&lt;/a&gt;, which means popular tools tend to do one thing and do that well. It's definitely not true for PHP and I doubt it would be for Java EE, although I can't really judge that.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; I hinted it before, but to be clear: if you can utilise one of the many open source PHP applications out there then it can be a much larger save than just 2-10% and it might make a lot of sense. Most obvious example is e-commerce, but there are some others as well. In case of e-commerce, you should either just use an existing ready-made service, some marketplace or build on top of &lt;a href="https://magento.com/"&gt;Magento&lt;/a&gt;, &lt;a href="https://thelia.net/"&gt;Thelia&lt;/a&gt; or &lt;a href="https://sylius.com/"&gt;Sylius&lt;/a&gt;. Prestashop might have some use cases too, but if anyone recommended me WooCommerce, OpenCart, ZenCart, Drupal, Joomla or OsCommerce for e-commerce, I'd run away and I'd run far.&lt;/p&gt;

&lt;h3&gt;
  
  
  Maintainable
&lt;/h3&gt;

&lt;p&gt;I spent most of my professional carrier working on huge (&amp;gt;1.000.000 lines) legacy applications trying to clean up the mess my predecessors left behind themselves. Most of the pain came from over-engineered OOP monstrosities. Because of that, I truly appreciate the simplicity of Go and Rust and for me both PHP and Java would score really badly.&lt;/p&gt;

&lt;p&gt;I also enjoy the extra safety functional languages can provide but they can affect how fast a language is to learn, so you'd have to take that into account while assessing them for "fast to learn" and "excitement".&lt;/p&gt;

&lt;h3&gt;
  
  
  Secure
&lt;/h3&gt;

&lt;p&gt;This is a point where I really lack the knowledge to properly assess Java, but PHP does have a pretty bad track record. I have the feeling that Java would fair better, but I'd rather skip this topic saying that there are better languages out there than PHP. In fact, I believe PHP is among the worst.&lt;/p&gt;

&lt;h3&gt;
  
  
  Exciting
&lt;/h3&gt;

&lt;p&gt;Now this is certainly not important for all startups but if you are thinking about something technologically challenging, then you should try to appeal to the best minds available in your area. These people will be able to learn a new language, but they won't learn just any language you throw at them. Not because they can't, but because they don't want to.&lt;/p&gt;

&lt;p&gt;Unfortunately PHP is among the least respected languages out there and this means that the brightest software engineers probably never learned PHP and probably aren't willing to learn it.&lt;/p&gt;

&lt;p&gt;Java is slightly better off here because anyone who got a computer science degree in the last 2 decades have learnt Java at some point and many even stuck with or sticked to it. On the other hand it's also not the most popular language to learn for people outside of the Java community these days.&lt;/p&gt;

&lt;p&gt;On the upside however there are other JVM languages with current momentum (Scala and Kotlin mostly) which claim to provide easy access to anything written in Java, so that could be a safe way forward I think.&lt;/p&gt;

&lt;p&gt;I will admit that this is not a topic I can't fully assess, but I have the feeling Java still wins here.&lt;/p&gt;

&lt;h3&gt;
  
  
  Trustworthy
&lt;/h3&gt;

&lt;p&gt;This is an easy knockout for Java EE. If you want to go public or sell your product to fortune 500s you'll want Microsoft (C#), SAP and Java EE on your portfolio. And that's pretty much a complete list as far as I know.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusions
&lt;/h2&gt;

&lt;p&gt;So I had PHP winning one point easily and another one potentially. There are many points where I admitted I don't necessarily have the Java-knowledge to assess both but in these cases PHP scored pretty bad, forcing me to believe that Java is the better technology to start a green-field project.&lt;/p&gt;

&lt;p&gt;This does not mean that PHP will kill your startup and Java will save it. What this post meant to say is that you should understand the consequences of your choices, understand the risks you make and choose whatever will make you sleep better.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If cutting 2-10% of IT expense is all you want then PHP (or NodeJs) is reasonable.&lt;/li&gt;
&lt;li&gt;If you need to have your blog or e-commerce site available ASAP then PHP is probably your best choice, but you should make a good reason not to use an existing service instead.&lt;/li&gt;
&lt;li&gt;If you want to sell your product to Fortune 500 companies then Java is probably still the keyword to score a deal, although other JVM or .NET languages might also make sense.&lt;/li&gt;
&lt;li&gt;If ensuring you won't find yourself in a situation where you have to rewrite everything then use a statically typed, compiled language. I'd recommend Go but I hear Kotlin might be a reasonable choice as well.&lt;/li&gt;
&lt;li&gt;If you don't need first class support by major cloud providers, but runtime errors can kill your company then consider Rust or Haskell.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Finally, if you really wanted a simple answer to the question "will PHP save your startup?", I'd have to say no. Not unless you're building something on top of an existing PHP application. Will PHP kill your startup though? Probably not, but it's likely to make it less agile than it could be.&lt;/p&gt;

</description>
      <category>php</category>
      <category>java</category>
      <category>healthydebate</category>
    </item>
    <item>
      <title>The danger of detached management</title>
      <dc:creator>Peter Aba</dc:creator>
      <pubDate>Sat, 28 Jul 2018 09:22:01 +0000</pubDate>
      <link>https://dev.to/peteraba/the-danger-of-detached-management-13ah</link>
      <guid>https://dev.to/peteraba/the-danger-of-detached-management-13ah</guid>
      <description>&lt;p&gt;&lt;em&gt;This post first appeared on &lt;a href="https://peteraba.com/blog/the-danger-of-detached-management/"&gt;my blog&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Obviously none of the following have I ever experienced personally, it's more of a thought experience I suppose.&lt;/p&gt;

&lt;p&gt;So let's say you have a software feature team made up of a handful of focused and experienced professionals and perhaps a few juniors just for good measure. Let's also imagine that this is true for both the engineers and the product managers and they together manage to implement a very fruitful culture where things to deliver and their priorities are always clear. Things also get delivered more or less on time and technical dept is also kept under control. Sounds great so far, right?&lt;/p&gt;

&lt;p&gt;To color that picture a bit further let's also imagine that this imaginary team has some process in place to improve their internal processes and discuss pressing issues. For example they might meet regularly for &lt;a href="https://www.wikiwand.com/en/Kaizen"&gt;Kaizen meetings&lt;/a&gt; to keep things generally improving.&lt;/p&gt;

&lt;p&gt;Now let's say that said team also has a lead, but that lead is mostly involved in high level discussions, long term plans and in some cases aligning with other teams on said long term plans and their execution. She has her calendar full of meetings with stakeholders and upper management while she also takes part in the hiring process and of course some other personal tasks.&lt;/p&gt;

&lt;p&gt;It's obvious that she lifts a lot of weight off the teams back, practically enabling them to focus on the product and engineering tasks. I suppose this should still sound great, there's hardly anything to boost team performance more than cutting out distractions. The problems start when she decides not to have one-on-one's with her team members and that since she's not part of the day-to-day work of the team attending standups or the Kaizen might be optional for her. This however can render her practically detached from her team.&lt;/p&gt;

&lt;p&gt;These can effect the team in a few ways.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Hard to get help. Perhaps least importantly if and when there is a problem the team can not solve itself, it is harder to get the lead to weigh in or help because first she's not used to weighing in on team issues and second she might lack some context which is not always easy to properly explain.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Awkward team activities. Team members may also feel somewhat awkward or even anxious around a detached lead as she may be seen as some sort of an outsider without sufficient amount of regular interaction. As consequence this may also poison team activities such as team events in some cases. This is more of a problem for introvert team members probably, but still worth mentioning.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Lack of trust. Lack of touch can also cause a lack of transparency and team members might start wondering what their lead is doing most of her time and whether she has enough insight into the teams' work to be able to properly represent them in long term planning sessions with other managers.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Understanding team performance. For example let's say the &lt;a href="https://www.wikiwand.com/en/OKR"&gt;OKR&lt;/a&gt; says product X will be delivered by the end of the quarter but then some urgent request comes up that pushes the team to deliver product Y first. Or perhaps there's also a dependency on team Z to deliver product X and they're late. Either way at the end of the business quarter product X is not delivered, therefore a detached manager may think that the overall performance of our imaginary team is less than great. Technical improvements throughout the quarter might also easily go unnoticed of course. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Understanding individual performance. Team members might be judged on weird measures like being typically vocal or less vocal during selected meetings attended by the lead used for example. Imagine that being used as a deciding factor for your relative performance compared to the team average. This can of course further lead to team members getting unfair and unhelpful promotion feedback which will inevitably force valuable employees to seek their promotion in the form of a new position at a different company.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Creating legacy systems. Possibly the more important consequence of such unfair feedback is that people who don't quit will typically adjust. When technical greatness is not appreciated,  people will simply focus on product delivery and quality will naturally decline. This on the other hand is the perfect recipe for creating legacy systems that no one wants to touch anymore. When this happens, the lead will have her job failed as hard as possible, no matter how great a job she does doing her day-to-day job.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I imagine most of the above would apply to any delivery team, in or outside of IT, however with software feature teams there's an extra risk: Whether the product delivered is of poor or great quality can be very hard to tell. If the live system is broken every second day, that's a clear sign of course, or in case the UI is not usable it's easy to assume that the code is one big pile of ... spagetthi. However the complexity of even the simplest software system is still more complex than most other products in life and this means even software that does a decent job on the surface might be less than pleasant to work on as an engineer. (That's what we typically call a legacy application.)&lt;/p&gt;

&lt;p&gt;As I see it, a manager has two main choices to gain a better understanding of the overall quality of the product her team produces.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;She can either make sure to be involved in development, check the code produced for key features, be part of standups and main design decisions religiously. This is absolutely doable, I've seen it done multiple times, but definitely takes a lot of time. Problem is that this might render her partially unavailable for important manager discussions and she might also easily become a blocker for the team when she's less available.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;She can also choose to invest instead into understanding how her team members work as a team, join in some of the design decisions and observe how things get handled. Plus she'd still need to make sure to have a personal connection with her team to get better insights of potential problems. If things don't go as they should, she would still have option #1 to try, but if everything is okay, she'd have more time for other important tasks.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I guess being a manager is not easy and one of the toughest thing about it is that sometimes there's very little difference between being great or bad at it.&lt;/p&gt;

</description>
      <category>management</category>
    </item>
    <item>
      <title>Polyglot Tinkering - Moving to Firefox with Python</title>
      <dc:creator>Peter Aba</dc:creator>
      <pubDate>Sun, 13 May 2018 17:20:16 +0000</pubDate>
      <link>https://dev.to/peteraba/polyglot-tinkering---moving-to-firefox-with-python-2ge0</link>
      <guid>https://dev.to/peteraba/polyglot-tinkering---moving-to-firefox-with-python-2ge0</guid>
      <description>&lt;p&gt;This post first appeared &lt;a href="https://peteraba.com/blog/polyglot-tinkering-moving-to-firefox-with-python/"&gt;on my blog&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Firefox?
&lt;/h3&gt;

&lt;p&gt;I started working as a web developer during the spring of 2002, less than a year after IE6 came out. For those who have ever heard about IE6 it should be obvious that this means that I spent a significant amount of my life working around the various quirks of IE and of course that I was at one point in my life a huge &lt;a href="https://www.mozilla.org/en-US/firefox/new/?utm_medium=referral&amp;amp;utm_source=firefox-com"&gt;Firefox&lt;/a&gt; fan. Firefox was amazing at the time but unfortunately it became slower and slower with each iteration and by the time Google Chrome came around most web developers were ready for something much faster. I used a fair number of browsers since but I always found myself going back to Chrome for one reason or another and so did the majority of my colleagues.&lt;/p&gt;

&lt;p&gt;I was a bit sceptical but also excited about &lt;a href="https://www.rust-lang.org/en-US/"&gt;Rust&lt;/a&gt; and &lt;a href="https://servo.org/"&gt;Servo&lt;/a&gt; and I tried out the new Firefox as soon as it came out as stable. I loved its speed and many of its features but I had two major issues with it on Linux:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;For some reason I had no sound after a few days and it never came back.&lt;/li&gt;
&lt;li&gt;LastPass sucked as the copy password feature seemed broken.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;So I again went back to Chrome even though I prefer to de-Googlize myself as much as I can.&lt;/p&gt;

&lt;h3&gt;
  
  
  LastPass?
&lt;/h3&gt;

&lt;p&gt;Okay, so let's fast-forward a few months until I read &lt;a href="https://stories.jotform.com/calling-all-web-developers-heres-why-you-should-be-using-firefox-983f012d4aec"&gt;Calling all web developers: here's why you should be using Firefox&lt;/a&gt; and decided it was time to give Firefox another shot. This time sound was working just fine but LastPass still had issues copying my password. When I opened a page with a password stored the input fields were filled out properly, but I couldn't easily search for a stored password and copy it.&lt;/p&gt;

&lt;p&gt;This is a huge problem for me.&lt;/p&gt;

&lt;p&gt;I hope I don't even have to mention how important password managers are in general but for me having autofill is just not enough. Period. I store tons of passwords and notes which I often have to copy to access various things and opening a detail page in my LastPass Vault is just way too slow to be a viable option.&lt;/p&gt;

&lt;p&gt;So at this point I decided to create my first support ticket with LastPass. Their response was fast, brief and quite disappointing. To quote the relevant bits:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I am sorry to inform you that Firefox browser on Linux does not support binary feature.&lt;br&gt;
Binary feature is required for copy username and copy password.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Well, I guess this would just mean back to Chrome to most people, but I instead decided to come up with a tool to solve my problem. I did not mean to fix everyone's problem nor was I thinking of some fancy project on Github with stars and all. I wanted something quick and dirty, something that's fun for me to write and solves my problem in a way that I'm no longer blocked from using Firefox as my primary browser.&lt;/p&gt;

&lt;h3&gt;
  
  
  Clarifying the project
&lt;/h3&gt;

&lt;p&gt;Here were my requirements:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;I need to be able to access my notes and passwords for use cases other then logging into websites. (For that autofill works fine)&lt;/li&gt;
&lt;li&gt;The solution must be at least as fast as using the LastPass Chrome Extension:

&lt;ol&gt;
&lt;li&gt;Realise I need to enter a password to get my work done&lt;/li&gt;
&lt;li&gt;Open / Go to Chrome&lt;/li&gt;
&lt;li&gt;Open LastPass browser extension&lt;/li&gt;
&lt;li&gt;Search for the record I'm interested in&lt;/li&gt;
&lt;li&gt;Right click on the entry I need&lt;/li&gt;
&lt;li&gt;Copy note or password&lt;/li&gt;
&lt;/ol&gt;


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

&lt;p&gt;My first idea was to create a small desktop application which sits in my system tray and lets me look up passwords as needed. Then I figured that what I'd really want is to have a keyboard shortcut to open this application which would allow me to search instantly. Finally I realised that I'll start with a CLI app and I'll think about how to start it up once it works in a terminal.&lt;/p&gt;

&lt;h3&gt;
  
  
  LastPass CLI
&lt;/h3&gt;

&lt;p&gt;This thought process took about 2-5 minutes and in the meanwhile I found &lt;a href="https://github.com/lastpass/lastpass-cli"&gt;lastpass-cli&lt;/a&gt; which looked like something I could use, except that it required multiple command calls to achive what I wanted.&lt;/p&gt;

&lt;p&gt;I tested out how to solve my problem using my shell (Bash / Zsh):&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;lpass login&lt;/li&gt;
&lt;li&gt;lpass ls | grep "my-favorite-server"&lt;/li&gt;
&lt;li&gt;select the id of the server I want to access (using a mouse)&lt;/li&gt;
&lt;li&gt;lpass show "id-of-my-favorite-server"&lt;/li&gt;
&lt;li&gt;copy the note or password to clipboard (using a mouse)
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;my-favorite-server [id: 1112223334445556667]
Username: root
Password: my-super-safe-password
Hostname: 123.234.432.321:12345
NoteType: Server
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Okay, so it seemed like I can really kind of do what I need by using &lt;code&gt;lpass&lt;/code&gt;, &lt;code&gt;grep&lt;/code&gt; and &lt;code&gt;xclip&lt;/code&gt; but I'll also need to be able to select one of the results of the search if there's more than one. Now I happen to be a reasonably experienced terminal user and &lt;code&gt;bash&lt;/code&gt; coder for someone who's never been paid to be a sysadmin, but to be honest I felt disgusted by just thinking of the amount of script needed for this tool, mostly because manipulating strings is cumbersome in Bash. It is much nicer in &lt;code&gt;zsh&lt;/code&gt; but most of the time I need to stick to &lt;code&gt;bash&lt;/code&gt; and therefore my zsh-foo is quite basic.&lt;/p&gt;

&lt;h3&gt;
  
  
  Finding a tool that fits
&lt;/h3&gt;

&lt;p&gt;Okay, so if not &lt;code&gt;bash&lt;/code&gt; then what? Well, this is such a simple task that could be done in almost any programming language I'm aware of (&lt;code&gt;Elm&lt;/code&gt; being the exception) but at first I only really thought about the ones I use every day to keep things simple. However I didn't happen to like them for this task:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;PHP&lt;/code&gt; feels bloated for wrapping CLI calls plus it's not installed on all my computers&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Go&lt;/code&gt; also feels a bit clumsy for wrapping CLI calls because of it's type safety.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;JavaScript&lt;/code&gt; is not a contender for me because I don't like &lt;code&gt;Node&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Well, out of the above choices I'd choose bash without hesitation in this case but then I remembered that sysadmins tend to love &lt;code&gt;Python&lt;/code&gt;. I never used Python heavily but I was sure that I'd be doing less answer-hunting on stack-overflow than for Bash and that I'd like the end result more and that it is a better fit for the task than my primary languages.&lt;/p&gt;

&lt;h3&gt;
  
  
  Hacking is fun
&lt;/h3&gt;

&lt;p&gt;It took me about an hour to hack together what I needed. I have to admit the resulting code is not something I'll ever be proud of:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The script only works on Linux systems as it is&lt;/li&gt;
&lt;li&gt;I even made a decision during development that I won't create functions, just to keep things simple. (Sorry, not sorry.)&lt;/li&gt;
&lt;li&gt;I'm sure one could have achieved what I did in less than 20 minutes both with Python or Bash / Zsh.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Using Python however proved to be a blast and I think the end result is readable even if it lacks real craftsmanship. Hell, hacking is still fun!&lt;/p&gt;

&lt;p&gt;One of the coolest things about being a programmer is that you get to solve many of your own problems with relative ease. It's especially true if you take the time to wander to programming problems, principles and languages which you don't use every day. Python certainly rocks although I'll probably never work on anything serious using it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Result
&lt;/h3&gt;

&lt;p&gt;If this is an itch you share with me, feel free to use the script I wrote: &lt;a href="https://github.com/peteraba/dotfiles/blob/master/scripts/lps"&gt;https://github.com/peteraba/dotfiles/blob/master/scripts/lps&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To make it really efficient I recommend using a Quake-like terminal like &lt;a href="http://guake.org/"&gt;Guake&lt;/a&gt; so that it's always one key-stroke away.&lt;/p&gt;

&lt;p&gt;With this script my routine to retrieve a random password looks like this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Realise I need to enter a password to get my work done&lt;/li&gt;
&lt;li&gt;Hit F12 to open Guake (unless I'm already in a terminal)&lt;/li&gt;
&lt;li&gt;Type &lt;code&gt;lps my-favorite-server&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Select one of the many results by typing a number and hit &lt;code&gt;Enter&lt;/code&gt; (unless there's only one result)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;At this point the script tells me that the note or password is already copied to my clipboard. This is way faster than using the Chrome Extension saving me at least 1-2 minutes every day. More importantly I can now fully embrace any new browser, the lack of a LastPass extension shouldn't hold me back ever again.&lt;/p&gt;

</description>
      <category>python</category>
      <category>firefox</category>
      <category>lastpass</category>
    </item>
    <item>
      <title>FP public code review (#1)</title>
      <dc:creator>Peter Aba</dc:creator>
      <pubDate>Sat, 13 Jan 2018 17:40:28 +0000</pubDate>
      <link>https://dev.to/peteraba/fp-public-review-1-525m</link>
      <guid>https://dev.to/peteraba/fp-public-review-1-525m</guid>
      <description>&lt;p&gt;Imagine the following: You're a software engineer in a small team of an amazing but small company. One day your lead comes up to you saying that the company is looking for more engineers to hire but the person in charge of the tech part of the process had to leave in a hurry for her home country in the middle of the process. Unfortunately she won't be available in the foreseeable future.&lt;/p&gt;

&lt;p&gt;Originally there were tons of applications but HR and some juniors already filtered out the most obviously weak ones. There's still a handful of applications for you to sort out however. All the applicants solved the same set of problems using some online tool and your job is to check all remaining solutions for one of the problems.&lt;/p&gt;

&lt;p&gt;Since there's only time to invite a limited amount of applicants for an on-site interview, they'd like to have your expert opinion about how well each applicant performed. There will be other factors for sending out the invitation(s) so they need more from you than just selecting the best solution. It would be best if you could describe what each solution does well and how they could be improved, but please make sure to score each from 1 to 10, 10 being a perfect solution.&lt;/p&gt;

&lt;p&gt;All solutions are in F#, but the company is looking for good programmers, not necessarily F# experts. It's okay if they aren't using F#-specific shortcuts although that's okay too. You need to review their solutions for the following problem: (copy-paste from the Sieve &lt;a href="http://exercism.io"&gt;exercism.io&lt;/a&gt; problem)&lt;/p&gt;

&lt;h1&gt;
  
  
  Sieve problem
&lt;/h1&gt;

&lt;p&gt;Use the Sieve of Eratosthenes to find all the primes from 2 up to a given&lt;br&gt;
number.&lt;/p&gt;

&lt;p&gt;The Sieve of Eratosthenes is a simple, ancient algorithm for finding all&lt;br&gt;
prime numbers up to any given limit. It does so by iteratively marking as&lt;br&gt;
composite (i.e. not prime) the multiples of each prime,&lt;br&gt;
starting with the multiples of 2.&lt;/p&gt;

&lt;p&gt;Create your range, starting at two and continuing up to and including the given limit. (i.e. [2, limit])&lt;/p&gt;

&lt;p&gt;The algorithm consists of repeating the following over and over:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;take the next available unmarked number in your list (it is prime)&lt;/li&gt;
&lt;li&gt;mark all the multiples of that number (they are not prime)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Repeat until you have processed each number in your range.&lt;/p&gt;

&lt;p&gt;When the algorithm terminates, all the numbers in the list that have not&lt;br&gt;
been marked are prime.&lt;/p&gt;

&lt;p&gt;The Wikipedia article has a useful graphic that explains the algorithm:&lt;br&gt;
&lt;a href="https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes"&gt;https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Notice that this is a very specific algorithm, and the tests don't check&lt;br&gt;
that you've implemented the algorithm, only that you've come up with the&lt;br&gt;
correct list of primes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Source
&lt;/h3&gt;

&lt;p&gt;Sieve of Eratosthenes at Wikipedia &lt;a href="http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes"&gt;http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Solutions
&lt;/h1&gt;

&lt;p&gt;Here are the solutions you need to rate, review and report back to management and HR. Use the a comment section of this post for communicating with them:&lt;/p&gt;

&lt;h2&gt;
  
  
  Solution #1
&lt;/h2&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight fsharp"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;primesUpTo2&lt;/span&gt; &lt;span class="n"&gt;limit&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;rec&lt;/span&gt; &lt;span class="n"&gt;mark&lt;/span&gt; &lt;span class="n"&gt;st&lt;/span&gt; &lt;span class="n"&gt;acc&lt;/span&gt; &lt;span class="n"&gt;prime&lt;/span&gt; &lt;span class="n"&gt;limit&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;acc'&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;acc&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;prime&lt;/span&gt;
        &lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="n"&gt;acc'&lt;/span&gt; &lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;limit&lt;/span&gt; &lt;span class="k"&gt;with&lt;/span&gt;
        &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="bp"&gt;true&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;st&lt;/span&gt;
        &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="bp"&gt;false&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;mark&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt; &lt;span class="n"&gt;acc'&lt;/span&gt; &lt;span class="n"&gt;st&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;acc'&lt;/span&gt; &lt;span class="n"&gt;prime&lt;/span&gt; &lt;span class="n"&gt;limit&lt;/span&gt;

    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;rec&lt;/span&gt; &lt;span class="n"&gt;iterate&lt;/span&gt; &lt;span class="n"&gt;st&lt;/span&gt; &lt;span class="kt"&gt;list&lt;/span&gt; &lt;span class="n"&gt;limit&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt;
        &lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="kt"&gt;list&lt;/span&gt; &lt;span class="k"&gt;with&lt;/span&gt;
        &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="bp"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;st&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;tail&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt;
            &lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="nn"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;contains&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="n"&gt;st&lt;/span&gt; &lt;span class="k"&gt;with&lt;/span&gt;
            &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="bp"&gt;true&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;iterate&lt;/span&gt; &lt;span class="n"&gt;st&lt;/span&gt; &lt;span class="n"&gt;tail&lt;/span&gt; &lt;span class="n"&gt;limit&lt;/span&gt;
            &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="bp"&gt;false&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt;
                &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;st'&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;mark&lt;/span&gt; &lt;span class="n"&gt;st&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="n"&gt;limit&lt;/span&gt;
                &lt;span class="n"&gt;iterate&lt;/span&gt; &lt;span class="n"&gt;st'&lt;/span&gt; &lt;span class="n"&gt;tail&lt;/span&gt; &lt;span class="n"&gt;limit&lt;/span&gt;

    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="kt"&gt;list&lt;/span&gt; &lt;span class="p"&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="n"&gt;limit&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;nonPrimes&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;iterate&lt;/span&gt; &lt;span class="nn"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;empty&lt;/span&gt; &lt;span class="kt"&gt;list&lt;/span&gt; &lt;span class="n"&gt;limit&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ofList&lt;/span&gt; &lt;span class="kt"&gt;list&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="n"&gt;nonPrimes&lt;/span&gt; &lt;span class="p"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;toList&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Solution #2
&lt;/h2&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight fsharp"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;primesUpTo3&lt;/span&gt; &lt;span class="n"&gt;n&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;sieveStep&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;((&lt;/span&gt;&lt;span class="n"&gt;primes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;composites&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;acc&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="k"&gt;if&lt;/span&gt; &lt;span class="nn"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;contains&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="n"&gt;composites&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt; &lt;span class="n"&gt;acc&lt;/span&gt;
        &lt;span class="k"&gt;else&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;primes&lt;/span&gt;&lt;span class="p"&gt;,&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;i&lt;/span&gt;&lt;span class="p"&gt;..&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ofSeq&lt;/span&gt; &lt;span class="p"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;union&lt;/span&gt; &lt;span class="n"&gt;composites&lt;/span&gt;&lt;span class="p"&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="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;Seq&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fold&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sieveStep&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;([],&lt;/span&gt; &lt;span class="nn"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;empty&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;fst&lt;/span&gt;
    &lt;span class="p"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;Seq&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;rev&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Solution #3
&lt;/h2&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight fsharp"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;primesUpTo1&lt;/span&gt; &lt;span class="n"&gt;limit&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;sq&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;limit&lt;/span&gt; &lt;span class="p"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="p"&gt;|&amp;gt;&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;n&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;n&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="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;int&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;filterMultiples&lt;/span&gt; &lt;span class="n"&gt;possiblePrimes&lt;/span&gt; &lt;span class="n"&gt;prime&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;prime&lt;/span&gt; &lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;sq&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt; &lt;span class="n"&gt;possiblePrimes&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="n"&gt;possiblePrimes&lt;/span&gt; &lt;span class="p"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;List&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;filter&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="p"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="n"&gt;prime&lt;/span&gt; &lt;span class="o"&gt;||&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;prime&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&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;possiblePrimes&lt;/span&gt; &lt;span class="p"&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="n"&gt;limit&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;

    &lt;span class="nn"&gt;List&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fold&lt;/span&gt; &lt;span class="n"&gt;filterMultiples&lt;/span&gt; &lt;span class="n"&gt;possiblePrimes&lt;/span&gt; &lt;span class="n"&gt;possiblePrimes&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Solution #4
&lt;/h2&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight fsharp"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;primesUpTo4&lt;/span&gt;  &lt;span class="n"&gt;n&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;isMultiple&lt;/span&gt; &lt;span class="n"&gt;factor&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;x&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;factor&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;rec&lt;/span&gt; &lt;span class="n"&gt;seiveNextPrime&lt;/span&gt; &lt;span class="n"&gt;primes&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt;
        &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="n"&gt;prime&lt;/span&gt; &lt;span class="p"&gt;::&lt;/span&gt; &lt;span class="n"&gt;tail&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;seiveNextPrime&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prime&lt;/span&gt; &lt;span class="p"&gt;::&lt;/span&gt; &lt;span class="n"&gt;primes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;List&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;filter&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;isMultiple&lt;/span&gt; &lt;span class="n"&gt;prime&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;not&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;tail&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="bp"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;List&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;rev&lt;/span&gt; &lt;span class="n"&gt;primes&lt;/span&gt;
    &lt;span class="n"&gt;seiveNextPrime&lt;/span&gt; &lt;span class="bp"&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="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Solution #5
&lt;/h2&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight fsharp"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="nc"&gt;Candidate&lt;/span&gt;  &lt;span class="p"&gt;=&lt;/span&gt;
    &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="nc"&gt;Unmarked&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;
    &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="nc"&gt;Marked&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;

&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;primesUpTo5&lt;/span&gt; &lt;span class="n"&gt;limit&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;mark&lt;/span&gt; &lt;span class="n"&gt;prime&lt;/span&gt; &lt;span class="n"&gt;range&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt;
        &lt;span class="n"&gt;range&lt;/span&gt; 
        &lt;span class="p"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;List&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;function&lt;/span&gt;
            &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="nc"&gt;Unmarked&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="k"&gt;when&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;prime&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;-&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;Marked&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;c&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;rec&lt;/span&gt; &lt;span class="n"&gt;sieve&lt;/span&gt; &lt;span class="n"&gt;marked&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt;
        &lt;span class="k"&gt;function&lt;/span&gt;
        &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="bp"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;marked&lt;/span&gt; &lt;span class="p"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;Seq&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;rev&lt;/span&gt;
        &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="o"&gt;((&lt;/span&gt;&lt;span class="nc"&gt;Unmarked&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;pp&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;::&lt;/span&gt; &lt;span class="n"&gt;tail&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;sieve&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pp&lt;/span&gt; &lt;span class="p"&gt;::&lt;/span&gt; &lt;span class="n"&gt;marked&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;mark&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="n"&gt;tail&lt;/span&gt;&lt;span class="p"&gt;)&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="n"&gt;tail&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;sieve&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="n"&gt;marked&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;tail&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="n"&gt;limit&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;List&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt; &lt;span class="nc"&gt;Unmarked&lt;/span&gt;
    &lt;span class="p"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;sieve&lt;/span&gt; &lt;span class="bp"&gt;[]&lt;/span&gt;
    &lt;span class="p"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;Seq&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;function&lt;/span&gt;
        &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="nc"&gt;Unmarked&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;-&amp;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="p"&gt;-&amp;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;|&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;Seq&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;filter&lt;/span&gt; &lt;span class="o"&gt;((&amp;lt;)&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;If you like this discussion, let me know and there might be more coming.&lt;/p&gt;

</description>
      <category>fsharp</category>
      <category>functional</category>
      <category>exercismio</category>
      <category>discuss</category>
    </item>
    <item>
      <title>Go is my gateway drug</title>
      <dc:creator>Peter Aba</dc:creator>
      <pubDate>Mon, 08 Jan 2018 12:01:58 +0000</pubDate>
      <link>https://dev.to/peteraba/go-is-my-gateway-drug-5efm</link>
      <guid>https://dev.to/peteraba/go-is-my-gateway-drug-5efm</guid>
      <description>&lt;p&gt;This post first appeared &lt;a href="https://peteraba.com/blog/go-is-my-gateway-drug/"&gt;on my blog&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I've been a long time PHP / JavaScript developer by 2013 when I first started toying with Go. It's been almost 5 years by now and I've been an advocate of the language ever since. I was one of the many programmers who tried it out for the concurency primitives but stayed for it's simplicity. It was with Go that I realised how much nicer life is without inheritance and the rest of the OOP shenenigans. On the other hand Go also gave me a push to experiment with even more languages. It turned out to be my gateway drug to learning programing languages.&lt;/p&gt;

&lt;p&gt;Of course, I played with some languages like Java, Python or Ruby before but honestly they didn't provide me anything that would be that much more than I had before. I was not interested in writing games, desktop or mobile apps at the time, I was happy as webdeveloper. To me Java felt too clumsy, Ruby felt too much magic and Python felt lacking the momentum at the time. (Not to mention the 2.x vs 3.x confusion.) Learning either of these languages felt too much work for the potential gain. With Go it was different, practically a love at first sight. It was so easy to learn and promised (and fulfilled) so much that I couldn't even stop learning more. Once I mastered it though, I realized that my old OOP languages feel verbose and my dynamically typed languages feel fragile. I was however feeling that Python was nicer to read than Go and this made me looking at further languages, mostly new ones like Rust and Elixir.&lt;/p&gt;

&lt;p&gt;There are a few ways to try out new languages and I usually prefer doing a small project in them even if I never actually finish those projects. This past two weeks however I went back to an old favorite: &lt;a href="http://exercism.io"&gt;exercism.io&lt;/a&gt;. What's really nice about this service is that you can check how others solved a particular problem and with a bit of extra effort it's also possible to find or construct a "perfect" solution.&lt;/p&gt;

&lt;p&gt;To showcase what I mean I'll add a few solutions for a simple problem called the Hamming problem throughout the exercism.io. The problem is simply finding the "distance" between two strings meaning the number of characters being different.&lt;/p&gt;

&lt;h3&gt;
  
  
  PHP
&lt;/h3&gt;

&lt;p&gt;Here's my PHP solution from 2015:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;distance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$b&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="nb"&gt;strlen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="nb"&gt;strlen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$b&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;\InvalidArgumentException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'DNA strands must be of equal length.'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nv"&gt;$aSplit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;str_split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$a&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nv"&gt;$bSplit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;str_split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$b&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="nv"&gt;$diff&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;array_diff_assoc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$aSplit&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$bSplit&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;count&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$diff&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;It's actually quite simple, there's just one if for checking the string lengths. On the other hand there are a few strange things about PHP already showing:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Notice how str_split has a '_' character to separate the parts but strlen is written as one word? Typical PHP...&lt;/li&gt;
&lt;li&gt;Notice that array_diff_assoc is a rather specific function. It shows me that there is a very large standard library to learn.&lt;/li&gt;
&lt;li&gt;Throwing an exception is okay. If you're a consumer of this function, you better catch the exception being thrown here.&lt;/li&gt;
&lt;li&gt;The lack of types mean you can always call this function with whatever values you want from &lt;code&gt;null&lt;/code&gt; to any type of &lt;code&gt;object&lt;/code&gt;s, up to you. (Yes, this can be optionally fixed in PHP 7.0+, kind of.)&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  Note 1.
&lt;/h4&gt;

&lt;p&gt;Hopefully no one would try to get everything done in one line, because it can seriously hurt anyone looking at it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;distance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$b&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="nb"&gt;strlen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="nb"&gt;strlen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$b&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;\InvalidArgumentException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'DNA strands must be of equal length.'&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="nb"&gt;count&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;array_diff_assoc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;str_split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$a&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nb"&gt;str_split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$b&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;h4&gt;
  
  
  Note 2.
&lt;/h4&gt;

&lt;p&gt;One could also write the following using PHP 7 making some of the issues go away. Typing is still optional though therefore there are still no general guarantees. Given that it's a scripting language, braking changes aren't necessary obvious before you deploy them unless your test suite has you covered.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class="cd"&gt;/**
 * @throws \InvalidArgumentException
 */&lt;/span&gt;
&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;distance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;string&lt;/span&gt; &lt;span class="nv"&gt;$a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt; &lt;span class="nv"&gt;$b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&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="nb"&gt;strlen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="nb"&gt;strlen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$b&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;\InvalidArgumentException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'DNA strands must be of equal length.'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nv"&gt;$aSplit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;str_split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$a&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nv"&gt;$bSplit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;str_split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$b&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="nv"&gt;$diff&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;array_diff_assoc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$aSplit&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$bSplit&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;count&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$diff&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;h3&gt;
  
  
  Go
&lt;/h3&gt;

&lt;p&gt;My Go solution from 2017:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;hamming&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="s"&gt;"errors"&lt;/span&gt;

&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;testVersion&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;6&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;Distance&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="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&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="kt"&gt;error&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="nb"&gt;len&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="o"&gt;!=&lt;/span&gt; &lt;span class="nb"&gt;len&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="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;errors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;New&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Lengths of the provided strings are not equal."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;aBytes&lt;/span&gt; &lt;span class="o"&gt;:=&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;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;bBytes&lt;/span&gt; &lt;span class="o"&gt;:=&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;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;dist&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;
    &lt;span class="k"&gt;for&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;ch&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;range&lt;/span&gt; &lt;span class="n"&gt;aBytes&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;ch2&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;bBytes&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="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;ch&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;ch2&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;dist&lt;/span&gt; &lt;span class="o"&gt;+=&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;return&lt;/span&gt; &lt;span class="n"&gt;dist&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;OK, what's the takeaway here?&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;This is considerably longer and more complex than the PHP solution.&lt;/li&gt;
&lt;li&gt;On the other hand it requires much less prior knowledge from the user to understand, we don't even use the standard library. (To be fair it could also be avoided in PHP)&lt;/li&gt;
&lt;li&gt;There's no way this solution could be written on one line without breaking readability completely.&lt;/li&gt;
&lt;li&gt;Notice how the strong typing makes it impossible to call this method with weird data and how predictable the returned data is, except that error can also be a &lt;code&gt;nil&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Notice how errors handled by just forcebly returning an error type, "never" throwing something unexpected. (In reality there is a panic which can be raised, but it's usage is different from your typical exceptions)&lt;/li&gt;
&lt;li&gt;Make sure you understand that the error can be &lt;code&gt;nil&lt;/code&gt;. &lt;em&gt;Warning:&lt;/em&gt; There will be dragons!&lt;/li&gt;
&lt;li&gt;It might be strange that the function starts with a capital letter whereas the other identifiers start with a smaller case. This makes the code public / exported in Go.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;em&gt;Note:&lt;/em&gt; I tried to find a more functional or considerably simpler solution but I didn't find any.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;UPDATE:&lt;/em&gt; Benjamin Cable pointed out a few issues with the above code and suggested a better alternative. For issues described check out the comment section, the code is as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;distance&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="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dist&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;err&lt;/span&gt; &lt;span class="kt"&gt;error&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="nb"&gt;len&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="o"&gt;!=&lt;/span&gt; &lt;span class="nb"&gt;len&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="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;dist&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;errors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;New&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"length of provided strings is not equal"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&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="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nb"&gt;len&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;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&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;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&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;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;dist&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="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;dist&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  Python
&lt;/h3&gt;

&lt;p&gt;My Python solution again from 2015:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="s"&gt;"""Python distance exercise solution"""&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;distance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;text_one&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;text_two&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="s"&gt;"""Calculate distance between two strings"""&lt;/span&gt;
    &lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;char1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;char2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;zip&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;text_one&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;text_two&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;char1&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;char2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;count&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Takeaway:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The cyclomatic complexity is a bit larger here than with PHP, even without the error checking, but I do find it easier to read.&lt;/li&gt;
&lt;li&gt;Python's support for tuples and the &lt;code&gt;zip&lt;/code&gt; function makes it kind of functional-like, although the &lt;code&gt;for&lt;/code&gt; loop isn't all that usual in FP.&lt;/li&gt;
&lt;li&gt;There's nothing preventing us from calling this function with strange data.&lt;/li&gt;
&lt;li&gt;There's little we can expect from this function to be returned. If we change the return type to a string, the callers won't know until they get a runtime error.&lt;/li&gt;
&lt;li&gt;We are using the standard library here but &lt;code&gt;zip&lt;/code&gt; feels much less esoteric than &lt;code&gt;array_diff_assoc&lt;/code&gt; was for PHP.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;em&gt;Note:&lt;/em&gt; My Python is roughly on advanced beginner level, Christoph Schindler appears to be more experienced, his solution reads even more functional-like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;distance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sequence&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;other&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sequence&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;other&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nb"&gt;ValueError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'Sequences must be of same length.'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&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="k"&gt;for&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="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;zip&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sequence&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;other&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Additional takeaway:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;By raising a value error we can cause even more havoc on the caller's side.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  F-sharp
&lt;/h3&gt;

&lt;p&gt;and finally here's the same thing I wrote in F# this week having about 2 days worth of experience:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight fsharp"&gt;&lt;code&gt;&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nc"&gt;Hamming&lt;/span&gt;

&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;distance&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;strand1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;strand2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="o"&gt;):&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;option&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt;
    &lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="n"&gt;strand1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Length&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;strand2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Length&lt;/span&gt; &lt;span class="k"&gt;with&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;y&lt;/span&gt; &lt;span class="k"&gt;when&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;y&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;seq1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;seq2&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;List&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ofSeq&lt;/span&gt; &lt;span class="n"&gt;strand1&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;List&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ofSeq&lt;/span&gt; &lt;span class="n"&gt;strand2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nc"&gt;Some&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;List&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fold2&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;acc&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;if&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="k"&gt;then&lt;/span&gt; &lt;span class="n"&gt;acc&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="n"&gt;acc&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="mi"&gt;0&lt;/span&gt; &lt;span class="n"&gt;seq1&lt;/span&gt; &lt;span class="n"&gt;seq2&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="p"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;None&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;What can we take away here?&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;It is slightly longer than the Python solution.&lt;/li&gt;
&lt;li&gt;You may find the &lt;code&gt;match&lt;/code&gt; syntax strange but you can think of it as an &lt;code&gt;if&lt;/code&gt; on steroid for now.&lt;/li&gt;
&lt;li&gt;There's no way you could call this function with wrong types.&lt;/li&gt;
&lt;li&gt;The response is even more obvious than Go's is as the &lt;code&gt;null&lt;/code&gt; part is not a surprise here, it's expressed by the &lt;code&gt;option&lt;/code&gt; type annotation.&lt;/li&gt;
&lt;li&gt;We are also using the standard library here but, much like &lt;code&gt;zip&lt;/code&gt;, &lt;code&gt;List.fold2&lt;/code&gt; and &lt;code&gt;List.ofSeq&lt;/code&gt; also feel much less esoteric than &lt;code&gt;array_diff_assoc&lt;/code&gt; in the PHP solution.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;It is not obvious from the above example but explicit type definitions are optional in F# unless the compiler tells you that you should provide them. Types however aren't optional like they are in PHP and partially in Python and since it's a compiled language there's much less space for mistakes too. Not having to deal with types in the first place can make coding feek much more like a scripting language when compared to C# for example. I only wish the compiler was faster, much faster if possible. (Go's compiler feels about 100x faster.)&lt;/p&gt;

&lt;p&gt;UPDATE: As I mentioned above I just started to get deeper into FP languages and F#, here's a better solution from the comments:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight fsharp"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;distance&lt;/span&gt; &lt;span class="n"&gt;s1&lt;/span&gt; &lt;span class="n"&gt;s2&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; 
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nn"&gt;String&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt; &lt;span class="n"&gt;s1&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;String&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt; &lt;span class="n"&gt;s2&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt; &lt;span class="nc"&gt;None&lt;/span&gt;
  &lt;span class="k"&gt;else&lt;/span&gt;
    &lt;span class="nn"&gt;Seq&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;zip&lt;/span&gt; &lt;span class="n"&gt;s1&lt;/span&gt; &lt;span class="n"&gt;s2&lt;/span&gt;
    &lt;span class="p"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;Seq&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sumBy&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;c2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;c1&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;c2&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;else&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;|&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;Some&lt;/span&gt;

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



&lt;p&gt;It's hard to argue that this is a very elegant solution.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusions
&lt;/h3&gt;

&lt;p&gt;I guess it's no surprise that I find the F# solution the best here, but of course I do not mean to say that F# is the best language out of the four. I don't even think it's fair to say such a thing in general. I also don't think that this example proves in any way that FP is better than OOP. Obviously these examples provide no good insight into how hard these languages are to learn, how usable they are in the wild and many other important aspect of the languages. They do prove however, at least to me, that it's worth learning other languages as not all languages are equal.&lt;/p&gt;

&lt;p&gt;Also &lt;a href="http://exercism.io"&gt;exercism.io&lt;/a&gt; is an awesome dealer.&lt;/p&gt;

</description>
      <category>exercismio</category>
      <category>go</category>
      <category>python</category>
      <category>fsharp</category>
    </item>
  </channel>
</rss>
