<?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: Onorio Catenacci</title>
    <description>The latest articles on DEV Community by Onorio Catenacci (@olddutchcap).</description>
    <link>https://dev.to/olddutchcap</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%2F96329%2Fe9cfce84-8000-4404-8c3f-7cd66c19e58f.jpg</url>
      <title>DEV Community: Onorio Catenacci</title>
      <link>https://dev.to/olddutchcap</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/olddutchcap"/>
    <language>en</language>
    <item>
      <title>A Handy Way To Clear The Terminal In Python</title>
      <dc:creator>Onorio Catenacci</dc:creator>
      <pubDate>Fri, 02 Aug 2024 19:35:38 +0000</pubDate>
      <link>https://dev.to/olddutchcap/a-handy-way-to-clear-the-terminal-in-python-25ge</link>
      <guid>https://dev.to/olddutchcap/a-handy-way-to-clear-the-terminal-in-python-25ge</guid>
      <description>&lt;p&gt;So I have been using the Python REPL quite a bit lately.  I've been using it on Windows and it was really getting quite annoying to me that I couldn't clear the terminal screen.  &lt;/p&gt;

&lt;p&gt;With a little bit of work I was able to hack together this code to allow me to clear the terminal. There were a few small issues that made this non-trivial.&lt;/p&gt;

&lt;h2&gt;
  
  
  Running CLS
&lt;/h2&gt;

&lt;p&gt;Most of the examples I could find on StackOverflow used os.cmd to call either &lt;code&gt;clear&lt;/code&gt; or &lt;code&gt;cls&lt;/code&gt;. Using &lt;code&gt;os.system&lt;/code&gt; is deprecated. I needed to figure out how to run this as a subprocess.  This made it slightly more tricky because cls is an internal command.  That means it's built into the cmd executable.  We can't execute cls directly therefore we need to execute it as part of an invocation of cmd. &lt;/p&gt;

&lt;p&gt;The command line is &lt;code&gt;cmd /c cls&lt;/code&gt;.  The &lt;code&gt;/c&lt;/code&gt; parameter tells the command processor to immediately exit after executing the cls.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;subprocess&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;clear&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;command&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;cmd&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="n"&gt;args&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;/c&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;cls&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="n"&gt;cli&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;command&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;
    &lt;span class="n"&gt;subprocess&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cli&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Making Clear Available Automatically
&lt;/h2&gt;

&lt;p&gt;So while we have the right code now we want it to automatically be available to us every time we fire up a Python REPL clear is available to us.&lt;/p&gt;

&lt;p&gt;It's my understanding that there are multiple ways to stash this code so that Python picks it up automatically.  Here's how I did it.&lt;/p&gt;

&lt;p&gt;I created a new User Level Environment Variable &lt;code&gt;PYTHONSTARTUP&lt;/code&gt; and pointed it to my &lt;code&gt;%USERPROFILE%&lt;/code&gt; directory.  USERPROFILE is the Windows analog of the HOME directory on a *nix machine.  I saved the code in a .pyrc file which I stored into the %PYTHONSTARTUP% directory. &lt;/p&gt;

&lt;p&gt;This is nothing major or earthshaking but it took me a few minutes of work to figure it out so I thought others might like to know about it as well.&lt;/p&gt;

</description>
      <category>python</category>
      <category>cli</category>
    </item>
    <item>
      <title>A Quick Utility Module</title>
      <dc:creator>Onorio Catenacci</dc:creator>
      <pubDate>Tue, 30 Apr 2024 15:36:51 +0000</pubDate>
      <link>https://dev.to/olddutchcap/a-quick-utility-module-54o3</link>
      <guid>https://dev.to/olddutchcap/a-quick-utility-module-54o3</guid>
      <description>&lt;p&gt;I was working on some code with a friend of mine and we came up with what seems a relatively clever way to do a couple of validations.  I'm putting this post here to share this in case it benefits anyone else:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;defmodule Validations do
  @moduledoc """
  This module contains a few validation predicate functions.
  """

  @doc """
  Checks if a string contains only specified characters.  The specified characters are passed in a list. The list can be one or more characters. You could pass an empty list if you wished but that would always return false.

  ## Examples

      iex&amp;gt; Validations.string_contains_only_specified_chars?("abc", ["a", "b", "c"])
      true

      iex&amp;gt; Validations.string_contains_only_specified_chars?("abr", ["a", "b", "c"])
      false
  """

  @spec string_contains_only_specified_chars?(String.t(), [String.t(), ...]) :: boolean
  def string_contains_only_specified_chars?(string, list)
      when is_binary(string) and is_list(list) do
    string
    |&amp;gt; String.graphemes()
    |&amp;gt; Enum.reduce(true, fn letter, acc -&amp;gt; letter in list &amp;amp;&amp;amp; acc end)
  end

  @doc """
  Checks if a string is of a specified length or not.

  ## Examples

      iex&amp;gt; Validations.string_expected_length?("abc", 3)
      true

      iex&amp;gt; Validations.string_expected_length?("abc", 2)
      false
  """
  @spec string_expected_length?(String.t(), integer) :: boolean
  def string_expected_length?(string, length) when is_binary(string) and is_integer(length) do
    String.length(string) == length
  end
end

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

&lt;/div&gt;



&lt;p&gt;Nothing innovative or surprising--just a little something I whipped up that I wanted to share for the potential benefit of others.&lt;/p&gt;

</description>
      <category>elixir</category>
      <category>utility</category>
      <category>validation</category>
    </item>
    <item>
      <title>On The Value Of Listening To Warnings</title>
      <dc:creator>Onorio Catenacci</dc:creator>
      <pubDate>Wed, 31 Jan 2024 16:41:02 +0000</pubDate>
      <link>https://dev.to/olddutchcap/on-the-value-of-listening-to-warnings-2h94</link>
      <guid>https://dev.to/olddutchcap/on-the-value-of-listening-to-warnings-2h94</guid>
      <description>&lt;p&gt;One common mistake I've seen repeatedly over the years is the assumption that compiler warnings (in those languages which provide them) are simply noise that one can safely ignore. It's a bad habit to get into for a few reasons:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;It encourages the sloppy practice of letting warnings go for month after month with no developer investigating the problem the warning is indicating. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It encourages a mentality of &lt;em&gt;it compiles so it's right&lt;/em&gt; which is almost never a good approach to take.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I was recently having a conversation with another developer about one of the most seemingly useless warnings--"unused variable".* Now I'm unsure of the original reason for warning but it's not hard for me to imagine. &lt;/p&gt;

&lt;p&gt;I believe (and may be wrong) that the notion of compiler warnings originates with the C language.  The whole notion of compiler warnings was to flag code that is syntactically correct but may be suspect.  Consider this code fragment:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if(x = 1)
{
  printf("It's 1\n");
}
else
{
  printf("It's not 1\n");
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I'll bet more than one or two of you can spot the problem without trying very hard. But this used to be legal C code. Doing an assignment inside a test that way is almost never a good idea but it was perfectly legal in C. You'd get a warning about it but if you're in the habit of ignoring warnings, you may never bother to check it because "it compiles so it's right."  Now when you look at a code fragment that way what's wrong with it is usually pretty easy to spot.  Let's say that our if test occurred in the middle of a 200 line routine.  Then, maybe not so easily spotted.&lt;/p&gt;

&lt;p&gt;Ok, so that's all well and good but why is it (or would it be) useful to warn about unused variables?  Consider this code fragment:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;int addemup(int n, int m)
{
  int M = 1;
  /* code
     more code
     more code */
  return n + M;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, again, in isolation like this it's probably pretty easy to guess that someone should have written &lt;code&gt;return n + m;&lt;/code&gt; (although that may not be right either). But the code is syntactically correct. Did the developer mean to ignore the parameter? We can't tell from the context.  &lt;/p&gt;

&lt;p&gt;This is why I think warnings about unused variables and/or parameters is a warning a lot of us should pay a lot more attention to.  If you really don't need the parameter, then why is it being passed at all? You may say, "Well, there's a requirement to pass it due to old code that requires it." Consider that an odious code smell. &lt;/p&gt;

&lt;p&gt;Code should be built intentionally, not accidentally. If you've truly got a routine with a parameter that it doesn't need then you're building code accidentally. &lt;/p&gt;

&lt;p&gt;This, by the way, is an example of what I call &lt;em&gt;code that works in spite of itself&lt;/em&gt;. This is when you run across code that makes you scratch your head as you're trying to figure out what the developer was doing and why they took such an odd approach. Did they mean to ignore the parameter passed in? The function is called "addemup" so it seems like it should add its parameters, right?  The code doesn't seem to have any obvious problem but it just looks odd and you may have to spend a lot of time deciphering it. &lt;/p&gt;

&lt;p&gt;Of course most code doesn't start this way; it acquires warts and oddities as it's maintained by multiple developers over the course of time.  &lt;/p&gt;

&lt;p&gt;In summary, not only should you not ignore warnings, if the option exists, treat them as errors so you cannot build your product until the warnings are addressed.  You'll save yourself a lot of work and your code will be easier for others to maintain. &lt;/p&gt;

&lt;h2&gt;
  
  
  Notes
&lt;/h2&gt;

&lt;p&gt;I am unsure if more recent versions of C have promoted this to an error but that seems to be the current behavior.  I cannot find anything definitive either way. &lt;/p&gt;

</description>
      <category>beginners</category>
      <category>programming</category>
    </item>
    <item>
      <title>Creating Repeatable Builds</title>
      <dc:creator>Onorio Catenacci</dc:creator>
      <pubDate>Fri, 12 Jan 2024 17:40:21 +0000</pubDate>
      <link>https://dev.to/olddutchcap/creating-repeatable-builds-5ah7</link>
      <guid>https://dev.to/olddutchcap/creating-repeatable-builds-5ah7</guid>
      <description>&lt;h2&gt;
  
  
  Repeatability
&lt;/h2&gt;

&lt;p&gt;There's a very important concept in building reliable software. It's repeatability. If you work building software for any appreciable amount of time you will run across a situation where a client reports a bug in your software which you cannot recreate. This is what is meant by repeatability.  You want the same behavior regardless of whether it's on your machine or the clients.  &lt;/p&gt;

&lt;p&gt;Another difficult situation is the case of an intermittent bug. The client repeatedly sees an issue but there doesn't seem to be any consistency to when or how it happens. This is also the opposite of repeatability.&lt;/p&gt;

&lt;p&gt;Both of these situations are bad. For one thing they eat up time in hunting down bugs that are especially hard to diagnose. They also make the client less likely to trust you in the future; after all if you can't make your software work, regardless of the actual cause, why should they trust you?&lt;/p&gt;

&lt;h2&gt;
  
  
  A Funny Machine
&lt;/h2&gt;

&lt;p&gt;Let's imagine for a second that you've got a machine that takes four inputs (e. g. threads) and transforms them into something else (e. g. cloth). Further let's imagine that you make some sort of mechanical change to the machine and suddenly it stops working as expected. What's the cause of the problem? While it might be any number of things, the most likely cause is the last change we made. It was working before we made the change and now it isn't so logically the change seems to be the most likely cause of the problem. &lt;/p&gt;

&lt;p&gt;Now let's imagine that we change two of the inputs and we change the machine at the same time. And the machine stops working. Which alteration was it that caused the machine to stop working? The change to the machine or the change to one or the other input? This makes diagnosing the cause of the failure a lot more time-consuming and complex. &lt;/p&gt;

&lt;p&gt;So there are two lessons we might draw from this imaginary scenario: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Try not to change more than one thing at a time&lt;/li&gt;
&lt;li&gt;If you must change more than one thing, try to test after each change.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  All Other Things Being Equal
&lt;/h2&gt;

&lt;p&gt;So how does our imaginary machine relate to the idea of repeatability? In this way: if we create a process that works correctly when we deploy it to a client's machine anything that differs on the client's machine may cause a failure. Hence if we can we want to deploy to a client machine that as closely as possible matches the machine on which the software was built. In other words we want to keep everything "equal" other than the actual software we're deploying.&lt;/p&gt;

&lt;p&gt;How can we achieve this state of "all other things being equal"? Docker is one great way to achieve this.  By using a docker image and being very careful about the software included in the image we can remove differences between our machine and a client's machine. This is one of the strong appeals of using docker in the first place--it helps us to eliminate the "works on my machine" syndrome.  However, there are steps beyond using docker we can take to eliminate any sort of variability.&lt;/p&gt;

&lt;p&gt;When we deploy software we're dealing with at least two things: the code we've written ourselves and its dependencies. We need these dependencies else we'll end up having to build everything from scratch. What developer would bother to rewrite routines to fetch a file from the hard drive? We all use the OS provided routines to do this. But using the OS routines does introduce a dependency. Usually these dependencies don't concern us but any time any software we depend upon changes it's a potential source of a bug. &lt;/p&gt;

&lt;h2&gt;
  
  
  Versioning
&lt;/h2&gt;

&lt;p&gt;If you've ever heard the term DLL Hell, in essence it was a problem with dependency management. When Microsoft's team first designed dynamic link libraries they relied on the name of the assembly alone to test if they had the right library.  Hence if I had a library called mylibrary.dll and another application had a library called mylibrary.dll if I were not careful the application might use the wrong version of the library. There was nothing present in the linker/loader to check the library being loaded to insure it was the correct one. &lt;/p&gt;

&lt;p&gt;Now one answer to this problem is strong versioning. In other words I make sure I identify the version of mylibrary.dll I need and I make sure I update the version any time a change is made. Semantic versioning is a step in this direction. In my code I can add code to test that I'm getting a particular version of a library--helps me to avoid DLL Hell.  Of course if I have version 1.0 of mylibrary.dll and another software package has version 1.0 of mylibrary.dll then I still have a problem.&lt;/p&gt;

&lt;p&gt;There's also the issue of a developer who isn't careful with his/her versioning? What then? He or she makes a change to a library (or a Javascript module etc.) that seems so minor they don't bother to change the version number. How do we account for that? The answer is a &lt;a href="https://en.wikipedia.org/wiki/Hash_function"&gt;hash&lt;/a&gt; of the binary artifact. &lt;/p&gt;

&lt;p&gt;What is a hash? Imagine you had a process to take every byte in a file and reduce them to a single value.  Maybe you'd take the first byte and add it to the second and then take that sum and add it to the third and so forth. &lt;em&gt;(Note: that example is extremely simplified. A real hash function is considerably more complex.)&lt;/em&gt; This is what we call hashing a file. In hashing we're trying to create a value from the file that is &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Totally unique to the contents of the file. &lt;/li&gt;
&lt;li&gt;Not likely to accidentally be the value of a different file (this is called a hash collision). &lt;/li&gt;
&lt;li&gt;Reduces to a value that's not too large. &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The first property is the one we're most interested in.  If I have a file that starts with the bytes 0x10, 0x15, 0xFF, I want the hash derived from the file to be different than the hash derived from a file starting 0x10, 0x16, 0xFF. In this way I can easily programmatically detect that the two files are not the same.  &lt;/p&gt;

&lt;p&gt;By hashing the binary artifact I no longer need to worry about the version information provided by the developer. If even one byte in the file has been altered the hash will be different and I'll know. &lt;/p&gt;

&lt;h2&gt;
  
  
  Great But How Does This Help Me?
&lt;/h2&gt;

&lt;p&gt;This is what the &lt;a href="https://nixos.org"&gt;NixOS&lt;/a&gt; package accomplishes for us. It gives us the infrastructure to build binary artifacts with confidence that all the dependencies (or inputs if you will) are invariant. &lt;/p&gt;

&lt;p&gt;This is along the same lines as mocking when one is creating unit tests. If unit tests depend on potentially variable inputs then when we have a failure we need to check if the failure was caused by changed code or by changed dependencies. Mocking allows us to keep our dependencies unchanged between runs of our tests so we can be confident that if we see a failure it's our code change that's caused it. &lt;/p&gt;

&lt;p&gt;NixOS allows us to take that idea of holding external elements the same and apply it much more rigorously to the entire build process. It allows us to build docker images that use precisely the same shared libraries to insure that if there is some sort of failure we don't have to spend time examining external dependencies. With so many of us deploying docker images to AWS and other cloud services, being able to know that the image on our machine and the image in the cloud is identical is a huge win. &lt;/p&gt;

</description>
      <category>softwareengineering</category>
      <category>nix</category>
    </item>
    <item>
      <title>Proud Moments In Mentoring!</title>
      <dc:creator>Onorio Catenacci</dc:creator>
      <pubDate>Mon, 30 Oct 2023 15:07:29 +0000</pubDate>
      <link>https://dev.to/olddutchcap/proud-moments-in-mentoring-1bim</link>
      <guid>https://dev.to/olddutchcap/proud-moments-in-mentoring-1bim</guid>
      <description>&lt;p&gt;Ok, yeah, I'm bragging a bit.  But it does give me a (possibly undeserved) sense of accomplishment to help other developers step up their coding game.  And I strongly suggest that if you want to step up your coding game, try mentoring others.  As the old saying goes when one teaches, two learn. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://exercism.org/profiles/OnorioCatenacci/testimonials?uuid"&gt;https://exercism.org/profiles/OnorioCatenacci/testimonials?uuid&lt;/a&gt;&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>mentoring</category>
      <category>exercism</category>
    </item>
    <item>
      <title>Searching For Polar Bears In Chicago</title>
      <dc:creator>Onorio Catenacci</dc:creator>
      <pubDate>Fri, 04 Aug 2023 13:51:42 +0000</pubDate>
      <link>https://dev.to/olddutchcap/searching-for-polar-bears-in-chicago-3867</link>
      <guid>https://dev.to/olddutchcap/searching-for-polar-bears-in-chicago-3867</guid>
      <description>&lt;p&gt;This is a post I've been meaning to write for some time.  It's a pretty common scenario.  Someone proposes using some outside of the mainstream language for a project at a company.  IT leadership stiffens up.  "How are we going to find developers for &lt;em&gt;language&lt;/em&gt; &lt;em&gt;x&lt;/em&gt;?  We can find scads of developers for &lt;em&gt;{Java|C#|Javascript Library}&lt;/em&gt; but how will we find people who can code &lt;em&gt;x&lt;/em&gt;?"  I wish sometimes I could be in those meetings. And I sincerely wish I could speak to recruiters who seem to think it's impossible to find developers for anything other than Java or C#.  A couple of thoughts to share:&lt;/p&gt;

&lt;h2&gt;
  
  
  You're Not Looking In The Right Places
&lt;/h2&gt;

&lt;p&gt;Scour LinkedIn for developers with experience in oh, let's pretend it's 2001 and you want developers for Python.  I know things have changed in the last couple of years since the folks doing LLM and other numerical work have found Python but there was a time when Python was considered "niche".  Heck there was a time when Java was a rare skill as hard as people may find that to believe today.  There's some survivorship bias that makes languages like Java, Javascript and C# seem as if they were inevitably destined to win.  &lt;/p&gt;

&lt;p&gt;But, my apologies, I'm digressing.  If you were scouring LinkedIn for Python devs (assuming LinkedIn existed back then), you probably wouldn't find many.  This is not because there weren't Python devs in 2001.  It's because Dice, LinkedIn etc. were not the right places to find these developers at that time.  Today's niche languages will be tomorrow's "every developer in the world wants to learn them so he or she can get a job" language.&lt;/p&gt;

&lt;p&gt;There are now (and were back then) forums, IRC channels (2001), slack channels (today), and conferences where people who liked Python would gather to chat.  That's where one could find Python developers.  And back in 2001 when you found a Python developer chances were that he or she was exceptionally good at their job.  This is exactly because it was hard (then) to get a job coding Python so most developers coding in it were coding in it because they truly cared about building good software and they considered that the best way to do it.&lt;/p&gt;

&lt;p&gt;My point is if you're looking for people coding non-mainstream langauges you'll have to do a bit more work than just searching LinkedIn.  Find them where they congregate.  If you're not sure where they congregate ask someone in the community.  It's not usually that hard to find people advocating for a particular language and they're usually more than happy to help recruiters find the right spot to find developers.&lt;/p&gt;

&lt;h2&gt;
  
  
  They're Teaching Javascript/Java/C# In Bootcamps
&lt;/h2&gt;

&lt;p&gt;This is very true and if you're looking for an endless supply of junior developers to learn their trade on your codebase you're in luck!  Don't get me wrong; I've met lots of folks from bootcamps that were very capable and could certainly hold their own against any developer in the shop.  But, honestly, they stood out to me exactly because they were so capable.&lt;/p&gt;

&lt;p&gt;And, again, don't get me wrong; most folks from bootcamps will grow into good developers.  I've seen that happen too.  But be honest--do you want them learning why it's not a great idea to use inheritance as opposed to composition on your codebase?  Do you want them learning that making calls to a database inside a loop is a recipe for very poor performance?  &lt;/p&gt;

&lt;p&gt;My point is while there's certainly safety in sticking with the herd, you're never going to build a world-changing IT team by swimming in other team's wakes.  And don't you really want to build an IT team that people will be beating down the door to work for?  I can remember a time when working at Google was incredibly prestigious.  Isn't that how you want people to view working for your IT team? &lt;/p&gt;

</description>
      <category>career</category>
      <category>discuss</category>
    </item>
    <item>
      <title>Calling A Tail A Leg</title>
      <dc:creator>Onorio Catenacci</dc:creator>
      <pubDate>Mon, 13 Feb 2023 21:46:41 +0000</pubDate>
      <link>https://dev.to/olddutchcap/calling-a-tail-a-leg-52fi</link>
      <guid>https://dev.to/olddutchcap/calling-a-tail-a-leg-52fi</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;How many legs does a dog have if you call the tail a leg?&lt;br&gt;
Four. Calling a tail a leg doesn’t make it a leg.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;-- Attributed to John Hulbert and Abraham Lincoln&lt;/p&gt;

&lt;p&gt;I've seen a few things lately about functional programming in C#.  This reminds me of the days in the early 90's when people confidently proclaimed that you could certainly code OOP in Visual BASIC.  My response to them then is closely related to my response to people saying you can code FP in C#; "calling C# functional doesn't make it functional." &lt;/p&gt;

&lt;p&gt;So why isn't C# functional and why can't it ever be?  One very simple reason: default immutability.  This assertion requires a bit of explanation. I need to peel back some abstractions but I trust it will be worth your while to follow me on this.&lt;/p&gt;

&lt;h3&gt;
  
  
  What Is Mutability and Immutability?
&lt;/h3&gt;

&lt;p&gt;Consider the simple pseudocode &lt;code&gt;x = 1&lt;/code&gt;; the actual programming language is somewhat immaterial at this point.  Abstractly what I'm telling the compiler to do is to mark some memory location with the name &lt;em&gt;x&lt;/em&gt; and then put the value  &lt;em&gt;1&lt;/em&gt; in to that memory location.  As a developer I normally do not need to know where &lt;code&gt;x&lt;/code&gt; actually lives in memory. &lt;/p&gt;

&lt;p&gt;Now, let's say that I need to add one to x. There are a few ways I can do that.  First I could read the value at the memory location identified by x and add 1 to that value and then store it back to the original memory location.  That's referred to as "destructive assignment" and it's a trait that most (maybe all?) imperative languages share.  I change the value &lt;em&gt;in place&lt;/em&gt;; this is what mutability actually is.  Or I could read the value stored at x, add 1 to it and then write it to a different memory location.  I trust you can see why this might be slightly confusing though; if I write x to a different location then am I still talking about x?  &lt;/p&gt;

&lt;p&gt;Now why do I care about changing a value in place versus changing it and writing it to a different memory location? Because of multiple threads of execution.  &lt;/p&gt;

&lt;p&gt;Consider this scenario.  I initialize x to 0.  I then run two threads against my current memory state.  The first thread adds 1 to x.  The second thread tests if x is greater than 0 and then runs logic (call it &lt;code&gt;l&lt;/code&gt;) based on that. Now I cannot determine in advance which thread is going to run first.  If thread one runs first then &lt;code&gt;l&lt;/code&gt; will be run.  If thread two runs first then &lt;code&gt;l&lt;/code&gt; will not be run.  I cannot determine exactly what will happen because what will happen depends on which thread runs first.&lt;/p&gt;

&lt;p&gt;On the other hand if I initialize x to 0 (immutable) and then it cannot be changed, then this is trivial.  The first thread adds 1 to x but stores the result in some other memory location. The second thread always runs &lt;code&gt;l&lt;/code&gt;. &lt;/p&gt;

&lt;h3&gt;
  
  
  What Does Mutability Have To Do With Functional?
&lt;/h3&gt;

&lt;p&gt;Impure functional languages (e. g. F# or Scala) usually make values immutable by default and a developer has to make a special effort to make a value mutable.  That is, making a value mutable must be intentional in these languages; it can't happen by accident or ignorance. Pure functional languages (e. g. Haskell) do not allow mutable values at all.  C#, which is an imperative language, defaults to all values being mutable and if you want an immutable value you must indicate it.  Again, an immutable value is something that has to be intentional in C#; it cannot happen accidentally.&lt;/p&gt;

&lt;p&gt;So does this mean that it's impossible to write functional code in C#?  Nope.  It does mean that writing functional has to rely on developer discipline.  Developers have to put "const" on pretty much every quantity. &lt;/p&gt;

&lt;h3&gt;
  
  
  Ok, So Why Is Const Everywhere An Issue?
&lt;/h3&gt;

&lt;p&gt;So let's imagine you've got a crew of very experienced and disciplined developers who indeed do slap a const on every quantity that should be treated as immutable. Even when they do put "const" on every quantity there are still two big holes:&lt;/p&gt;

&lt;p&gt;1.) They cannot control the mutability or immutability of quantities used by 3rd party libraries.&lt;/p&gt;

&lt;p&gt;2.) They cannot control code constructed by the compiler. &lt;/p&gt;

&lt;p&gt;And even if you're willing to live with those holes, how much extra effort do you think that insuring const is used correctly everywhere will add to a C# project?  How much extra testing effort will be added to insure that everything behaves as expected?  And remember that you cannot control the behavior of third party libraries so you'll need to be very careful about data being sent to and received from third-party libraries.  &lt;/p&gt;

&lt;p&gt;You can call a tail a leg but that doesn't make it one.  You can tell yourself that C# supports functional programming but that doesn't make it a functional programming language.  &lt;/p&gt;

&lt;p&gt;By the way, I'm not trying to disparage C#.  It's a fine language and lots of good software is written in it.  But if you want the advantages (and yes the drawbacks) of writing in the functional paradigm you're far better off to choose a language that actually supports functional programming.  &lt;/p&gt;

</description>
      <category>productivity</category>
      <category>ui</category>
    </item>
    <item>
      <title>Git Force Push Current Branch Only</title>
      <dc:creator>Onorio Catenacci</dc:creator>
      <pubDate>Thu, 18 Aug 2022 20:38:12 +0000</pubDate>
      <link>https://dev.to/olddutchcap/git-force-push-current-branch-only-2na5</link>
      <guid>https://dev.to/olddutchcap/git-force-push-current-branch-only-2na5</guid>
      <description>&lt;p&gt;So recently I found out there's a good reason to use a particular syntax for force pushing a branch to the backend.  &lt;/p&gt;

&lt;p&gt;I was doing this for a force push:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;git push -f&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Why would I force push a branch?  Because I often end up squashing lots of small commits on the branch into a single commit to make the commit history easier to read.  When I do that I need to force push to overwrite the existing history. Mind you I'm only doing this on &lt;em&gt;my own branches&lt;/em&gt;.  &lt;/p&gt;

&lt;p&gt;However, I found out much to my distress that if you've got multiple references to your backend (that is multiple branches tracking to origin) they &lt;em&gt;all&lt;/em&gt; get force pushed when you do -f.  If you're curious about this it's &lt;a href="https://git-scm.com/docs/git-push#Documentation/git-push.txt---force:~:text=Note%20that%20%2D%2Dforce,above%20for%20details."&gt;here&lt;/a&gt; in the git documentation.&lt;/p&gt;

&lt;p&gt;There is an alternative that works just fine if you're only meaning to force push your current branch.  What you can do is this:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;git push origin +&amp;lt;branch&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This will only force push the named branch.  However since I need to do this fairly often (as I say after I squash all the commits on a branch I force push so that instead of having 12 commits on a PR, I've got one) I want a git alias to make this easier for me.  And so I came up with this:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;fp = "!p() { CURRENT_BRANCH=$(git branch --show-current); git push origin +$CURRENT_BRANCH; }; p&lt;br&gt;
&lt;/code&gt;&lt;br&gt;
(I'm indebted to Phil Haack for demonstrating this technique of using a shell function in a git alias to allow for trickier stuff!) &lt;/p&gt;

&lt;p&gt;First I get the current branch name into the CURRENT_BRANCH environment variable.  Next I create the git push command substituting the CURRENT_BRANCH name.  Finally the shell function is invoked.  &lt;/p&gt;

&lt;p&gt;This does a force push but only on the current branch so I don't have to worry about inadvertently forcing other branches to the backend.&lt;/p&gt;

</description>
      <category>git</category>
      <category>alias</category>
    </item>
    <item>
      <title>Three Ways To Share Values Between Elixir Modules</title>
      <dc:creator>Onorio Catenacci</dc:creator>
      <pubDate>Thu, 21 Jul 2022 19:44:50 +0000</pubDate>
      <link>https://dev.to/olddutchcap/two-kinds-of-elixir-constants-5gad</link>
      <guid>https://dev.to/olddutchcap/two-kinds-of-elixir-constants-5gad</guid>
      <description>&lt;p&gt;I find that as I get older I find myself trying to remember coding techniques and idioms that shouldn't be hard to remember but sometimes are anyway.  This is one of those cases--the module attributes took me a bit of effort to work out so I thought I'd write it down.  I'm sharing it here so others might benefit from it as well.  &lt;/p&gt;

&lt;h2&gt;
  
  
  What Do I Mean By Constant?
&lt;/h2&gt;

&lt;p&gt;First it feels appropriate to say that when I say constant I have a definite technical meaning in mind.  In a mathematical sense a constant like &lt;strong&gt;pi&lt;/strong&gt; or &lt;strong&gt;e&lt;/strong&gt; is simply a value that's fixed on the number line.  In the sense that software developers use the word "constant" we usually mean something which is an extension of the notion of a mathematical constant--a fixed value.  It could be a number or a string or even a more complex data structure; the point is that in the course of the normal execution of the binary it won't change.&lt;/p&gt;

&lt;p&gt;Here I'm using the term constant to name a value that needs to be referenced in two or more modules in Elixir which none of them will change.  The value will be defined in one module and then read from others. There are two reasons to do this approach: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;It makes the code more readable&lt;/li&gt;
&lt;li&gt;It keeps the developer from repeating his/her self.
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Both of those are good reasons for using this approach.  I'm going to examine them a little bit before I discuss the coding techniques specifically.  &lt;/p&gt;

&lt;h3&gt;
  
  
  More Readable Code
&lt;/h3&gt;

&lt;p&gt;While a compiler and/or interpreter doesn't care about the difference between code using literals and code using symbolic names, developers very much care about this.  If I have code that reads like this:&lt;/p&gt;

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

def is_odd_number?(number), do: rem(number,2) != 0 #Version 1


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

&lt;/div&gt;

&lt;p&gt;vs.&lt;/p&gt;

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

def f(n), do: !(rem(n,2) == 0)                   #Version 2


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

&lt;/div&gt;

&lt;p&gt;which one conveys the intent of the coder better?  Now you might say "Hey no one names their functions &lt;em&gt;f&lt;/em&gt; and no one names their arguments &lt;em&gt;n&lt;/em&gt;" and I wish I could say you're correct.  But I have run across code like this in practice and it's hard to decipher--well for a human being to decipher at any rate.  The compiler doesn't care either way. The point is that using descriptive names (as opposed to bare literals) is a great technique for making your code more readable.&lt;br&gt;&lt;br&gt;
Constants, in this sense, are a form of a descriptive name for a quantity. &lt;/p&gt;

&lt;p&gt;You may even have to read your own code in six months and you'll be glad you took the extra time to make it easier to understand.&lt;/p&gt;

&lt;h3&gt;
  
  
  Keeps the Developer From Repeating
&lt;/h3&gt;

&lt;p&gt;It's become a mantra chanted over and over by developers who don't know much but they do know that repeating &lt;em&gt;anything&lt;/em&gt; in code is a bad idea.  Except it isn't always a bad idea. The trick is to know when it's ok to repeat things and when it isn't.&lt;/p&gt;

&lt;p&gt;Part of distinguishing between one case and the other is to understand why repetition is a bad thing in the first place.  The problem is that if I duplicate code and said code needs to be fixed later there's a good chance I won't find all the duplications and fix them too.  And that's assuming I'm working on my own code.  It's even more likely to be a problem when someone else will be maintaining your code. They're more likely to miss spots where the code needs to be fixed. &lt;/p&gt;

&lt;p&gt;So the next time you're tempted to copy/paste a bit of code think of your future self (or perhaps the poor person who will maintain your code) and do a bit of refactoring so you don't need to repeat the code.&lt;/p&gt;

&lt;p&gt;Now, there are times when repeating code actually simplifies things.  Part of the issue with removing duplication is that it introduces coupling.  As long as your coupling is clean and simple (in the decomplected sense of "simple") you're fine. Shared definitions--numerical constants, strings that signify names, etc.--definitely fall under this rubric.  &lt;/p&gt;

&lt;p&gt;However code under maintenance tends to get a lot of "this is almost what I need but not exactly".  This is part of the reason people tend to copy/paste code in the first place.  So the admonition to avoid repeating code is not an absolute one and you should apply your judgement.  Is the place where you're thinking of copy/pasting likely to change frequently?  Are the changes likely to differ from changes to the original code?  Then by all means copy/paste. On the other hand, if it's not likely to change frequently then you're better off to reference the single defintion from the other places in your code.  An example of something which may change but is not likely to change often is a company name.  It's possible for a company to change its name but it's not likely to happen very frequently.  If you've hard-coded that name 50 places in your code that's 50 places you have to find and fix.  If you hard code it in one place and then reference the constant in other code then you only need to fix it in one place.&lt;/p&gt;

&lt;p&gt;Partially the decision about what should be repeated and what shouldn't comes down to cohesion; that is to say, how much does the code in some particular block of code all serve one function.  If a piece of code is highly cohesive (e. g. a function to calculate the area of a circle) vs a lower cohesion function (e. g. calculate the area of a circle, print the circle in three colors and then return the current date) then it's better not to repeat the code.  Our judgement about copying and pasting code should be inversely proportional to the strength of the cohesion of the code. &lt;/p&gt;

&lt;p&gt;Like many ideas in engineering the notion of "don't repeat yourself" is not one that can be applied without thought or judgement.&lt;/p&gt;

&lt;h2&gt;
  
  
  Constants In Elixir
&lt;/h2&gt;

&lt;p&gt;Now having said all that let's talk about a couple of ways to deal with values shared between modules in Elixir.  You can register an attribute in one module and then reference that attibute from the other modules or you can create a (for lack of a better name) constant function--that is a function that takes no argument and simply hands back a constant value.  If someone knows the right name for this sort of function please post it in the comments for me! For sake of illustration I'll pretend I need a Pi constant in my code.&lt;/p&gt;

&lt;p&gt;Consider the following code:&lt;/p&gt;

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

defmodule MyMath do
   Module.register_attribute(__MODULE__, :pi, persist: true)
   @pi 3.141592653

   def pi, do: 3.141592653
   # this could also be: 
   # def pi, do: @pi
end


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

&lt;/div&gt;

&lt;p&gt;and now there are two ways for me to fetch the value of Pi in other modules:&lt;/p&gt;

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

defmodule My.Other.Module.That.Needs.To.Know.Pi do
   defp get_pi do # module attribute approach
      [pi] = MyMath.__info__(:attributes)[:pi]
      pi
   end

   def circle_area(radius) do
      MyMath.pi() * radius * radius #constant function approach
   end

   # or
   def circle_area_alternate(radius) do
      get_pi() * radius * radius
   end
end


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

&lt;/div&gt;

&lt;p&gt;Both of these approaches will work.  The attributes approach is really not recommended for a constant shared between modules.  It's more recommended for metadata about a module--author, last revision date etc.  The more recommended way to do this (although I will grant that it looks a bit odd) is a constant function. &lt;/p&gt;

&lt;p&gt;EDIT:&lt;/p&gt;

&lt;p&gt;After I originally posted this article it was pointed out to me by several smart Elixir developers that there's a third way to share values between modules. I wish I could take credit for coming up with it but as far as I know that credit belongs to Paul Schoenfelder who's a super-smart developer! &lt;/p&gt;

&lt;p&gt;The trick is to define the value to be shared in a using macro in the source module.  Like this:&lt;/p&gt;

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

defmodule MyMath do
 defmacro __using__(_) do
    quote do
       @pi 3.141592653
    end
end


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

&lt;/div&gt;

&lt;p&gt;Then you can simply use the module in a different module and the using macro is run and the value becomes available. Like so:&lt;/p&gt;

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

defmodule My.Other.Module.That.Needs.To.Know.Pi do
   use MyMath

   def circle_area(radius) do
      @pi * radius * radius #"using" macro approach
   end
end


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

&lt;/div&gt;

&lt;p&gt;The main idea here is that if you're using the same named value in multiple modules, you want to avoid &lt;em&gt;defining&lt;/em&gt; it more than once.  Defining the value in several different modules is an excellent way to insure that someone will miss changing the value somewhere in maintenance and that can lead to some really odd, difficult to reproduce bugs.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://livebook.dev/run?url=https%3A%2F%2Fgist.github.com%2FOnorioCatenacci%2F05ea0c5deca075598d53751312c3a790" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flivebook.dev%2Fbadge%2Fv1%2Fblue.svg" alt="Run in Livebook"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And you can run this via ReplIt too:&lt;br&gt;
&lt;a href="https://replit.com/@OnorioCatenacc1/Shared-Values-Between-Modules" rel="noopener noreferrer"&gt;Shared Values Between Modules&lt;/a&gt;&lt;/p&gt;

</description>
      <category>elixir</category>
    </item>
    <item>
      <title>Just In Case</title>
      <dc:creator>Onorio Catenacci</dc:creator>
      <pubDate>Mon, 13 Jun 2022 13:06:46 +0000</pubDate>
      <link>https://dev.to/olddutchcap/just-in-case-4ple</link>
      <guid>https://dev.to/olddutchcap/just-in-case-4ple</guid>
      <description>&lt;p&gt;Recently I was working on some Elixir code and I ran into something which sort of surprised me although I guess it shouldn't have.  I was typing code something like this:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;alternate-value = 4&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;and iex responded with this:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;** (CompileError) iex:8: cannot invoke remote function :erlang.-/2 inside a match&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;I thought to myself, "who's trying to subtract?" but then it occurred to me what was actually happening.  And so I thought I might write this up for the sake of helping to reinforce the lesson for me as well as maybe to help some beginners understand a basic property of Elixir.&lt;/p&gt;

&lt;h2&gt;
  
  
  Let's Get Down To Cases
&lt;/h2&gt;

&lt;p&gt;For sake of this discussion there are four ways of casing variable names that we're interested in.  &lt;em&gt;Casing&lt;/em&gt; meaning the mixture of upper and lower case letters in a variable name and what that conveys. &lt;/p&gt;

&lt;h4&gt;
  
  
  PascalCase
&lt;/h4&gt;

&lt;p&gt;There's &lt;code&gt;PascalCase&lt;/code&gt; which seems to have been the preferred casing of the Pascal programming language.  I'm not sure of that and I've honestly never bothered to check because it isn't important.  &lt;/p&gt;

&lt;p&gt;If you PascalCase a variable in Elixir something odd happens:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;iex(3)&amp;gt; PascalCase = 1&lt;br&gt;
** (MatchError) no match of right hand side value: 1&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;What's going on here?  Well by default in Elixir any name starting with an uppercase letter is an atom.  In fact if we do this:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;iex(3)&amp;gt; is_atom(PascalCase)&lt;br&gt;
true&lt;br&gt;
&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Yep, PascalCase is an atom.  And because PascalCase is an atom the only thing it will match is itself. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;iex(8)&amp;gt; PascalCase = PascalCase&lt;br&gt;
PascalCase&lt;br&gt;
iex(9)&amp;gt; PascalCase == PascalCase&lt;br&gt;
true&lt;br&gt;
&lt;/code&gt;&lt;br&gt;
Hence &lt;code&gt;PascalCase = 1&lt;/code&gt; is attempting to pattern match 1 to the atom PascalCase and it fails because the only thing that matches an atom is itself.  Not to short-circuit the suspense but pattern matching is an important topic in Elixir and I'm not going to treat it here. &lt;/p&gt;

&lt;h4&gt;
  
  
  camelCase
&lt;/h4&gt;

&lt;p&gt;The second type of casing for variable names is camelCase.  In case you don't get the developers' (weak) attempt at humor here, the capital letter in the middle is supposed to resemble a camel's hump.  Hence the fact that no developer is going to be booked into the Improv in our lifetime.&lt;/p&gt;

&lt;p&gt;As far as I know, Elixir has no issue whatever with camelCase but it isn't standard Elixir idiom.  This works:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;iex(1)&amp;gt; camelCase = 1&lt;br&gt;
1&lt;br&gt;
&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;However your colleagues may scratch their heads a bit at the funny casing you're using.  Most of these casings are intended to allow us to use multi-word variable names without it all reading like alowercasesentencewhichcanbeveryhardtoread. &lt;/p&gt;

&lt;h4&gt;
  
  
  snake_case
&lt;/h4&gt;

&lt;p&gt;Again, I think this name comes from a subtle attempt at humor.  We developers are nothing if we're not a lot of frustrated comedians.  &lt;/p&gt;

&lt;p&gt;I once heard the "Baby Boom" generation referred to as an example of the "python swallowing a pig" model.  If you visualize this rather gruesome (for the pig) scenario then you can probably figure out why it's called "snake_case".&lt;/p&gt;

&lt;p&gt;snake_case is the preferred casing of variables in Elixir so try to get yourself in the habit of using it--except in module names where Pascal case is the rule.&lt;/p&gt;

&lt;h4&gt;
  
  
  kebab-case
&lt;/h4&gt;

&lt;p&gt;As far as I know this casing style comes from Javascript and if you try to use it in Elixir (as my very first example showed) you'll get a very odd error.  It may bear with a word of explanation.&lt;/p&gt;

&lt;p&gt;Consider this code:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;iex(8)&amp;gt; kebab-case = 1&lt;br&gt;
** (CompileError) iex:8: cannot invoke remote function :erlang.-/2 inside a match&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Now if you've come from most other languages that looks as if you're assigning the value of 1 to the name kebab-case.  But that would be incorrect in Elixir (well, as far as I know in Elixir and any other BEAM based language).  This is not assignment; it's actually pattern matching.  &lt;/p&gt;

&lt;p&gt;I won't belabor the point because far better writers than me have spent a bit of time explaining pattern matching.  Suffice it to say that when you write &lt;code&gt;kebab-case = 1&lt;/code&gt; you're not doing assignment; you're actually pattern matching. And because Elixir code is ultimately translated into the bytecode of the BEAM virtual machine, when it sees the minus sign in your variable name it thinks you're attempting subtraction.  &lt;/p&gt;

&lt;p&gt;A word about that message: &lt;code&gt;:erlang.-/2&lt;/code&gt; is the BEAM's way of uniquely identifying a function.  In Elixir an uppercase letter at the start of a symbol name signifies an atom; however you can also signify an atom with a leading colon.  Hence &lt;code&gt;:erlang&lt;/code&gt; is the identifier for the Erlang module. &lt;code&gt;-/2&lt;/code&gt; is the function name.  It means the minus function taking two arguments.  &lt;/p&gt;

&lt;p&gt;So the message is essentially telling you that the beam thinks you've tried to invoke the subtraction function in a pattern match and that invoking a function in a pattern match is not allowed. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;EDIT:&lt;/strong&gt; It was pointed out to me that kebab-case doesn't come from Javascript. In fact as far as I can tell it's actually a coding standard in HTML and CSS.  The point that it won't work in Elixir still stands though. &lt;/p&gt;

</description>
      <category>elixir</category>
      <category>beginners</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Using Ack To Search Elixir Code</title>
      <dc:creator>Onorio Catenacci</dc:creator>
      <pubDate>Fri, 27 May 2022 16:03:21 +0000</pubDate>
      <link>https://dev.to/olddutchcap/using-ack-to-search-elixir-code-2e6g</link>
      <guid>https://dev.to/olddutchcap/using-ack-to-search-elixir-code-2e6g</guid>
      <description>&lt;p&gt;I've been a fan of &lt;a href="https://beyondgrep.com"&gt;ack&lt;/a&gt; for quite some time.  Somehow (and I'm not quite sure how) once or twice it's found stuff in source code that VSCode simply misses (likely I was searching wrong with VSCode).  And there are a few things I've found that make it even more effective in searching Elixir code that I thought I'd share.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Do I Configure Ack?
&lt;/h2&gt;

&lt;p&gt;First, how to get ack?  If you're on a Mac then simply use Homebrew to install it: &lt;code&gt;brew install ack&lt;/code&gt;. For those on Windows there's a Chocolatey NuGet package &lt;a href="https://community.chocolatey.org/packages/ack"&gt;here&lt;/a&gt;. If neither of those are an option for you there are installation instructions on the homepage.&lt;/p&gt;

&lt;p&gt;Secondly how should you configure ack for optimum use with Elixir?  I think the easiest way to set things up is to create an &lt;code&gt;.ackrc&lt;/code&gt; file in your home directory.  So a &lt;code&gt;~/.ackrc file&lt;/code&gt;.  This is mine:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;--type=elixir&lt;br&gt;
--smart-case&lt;br&gt;
--ignore-dir=deps&lt;br&gt;
--pager=less -R -F&lt;br&gt;
&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;In order, this is what this &lt;code&gt;.ackrc&lt;/code&gt; does:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;It tells ack to assume I'm searching elixir files (&lt;code&gt;--type=elixir&lt;/code&gt;).  Ack is smart enough to ignore .git directories and other temporary files when it's searching for text.  This tells ack that I want to search only through Elixir files by default.&lt;/li&gt;
&lt;li&gt;Smart case tells ack to search case-insensitive unless I have an upper case letter in my search string. Obviously Elixir is case-sensitive so this is very helpful. &lt;/li&gt;
&lt;li&gt;Ignore directory (&lt;code&gt;--ignore-dir&lt;/code&gt;) tells ack not to search in a given directory and below.  Since I don't usually want to see stuff that's brought in via Hex packages I ignore everything in any of the deps directory by default.&lt;/li&gt;
&lt;li&gt;Use &lt;a href="https://en.wikipedia.org/wiki/Less_(Unix)"&gt;less&lt;/a&gt; for the pager.  Less is a very neat tool that allows you to scroll forwards and backward through text output to the terminal one screenful at a time.  So by specifying less for my pager the ack output is sent out one page at a time and I can scroll forward and backward through it as I need to.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If you want to use ack without these settings (assuming you've added them to an &lt;code&gt;.ackrc&lt;/code&gt; on your machine) you can simply pass the &lt;code&gt;--noenv&lt;/code&gt; switch to ack on the command line and any settings in your &lt;code&gt;.ackrc&lt;/code&gt; will be ignored.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Do I Actually Search?
&lt;/h2&gt;

&lt;p&gt;Open a terminal and then change to the root directory of the source code you want to search (e. g. &lt;code&gt;~/git/myelixirapp&lt;/code&gt;).  Then it's &lt;code&gt;ack stringtosearchfor&lt;/code&gt; (e. g. &lt;code&gt;ack defmodule&lt;/code&gt;).  If you want to search for a string containing spaces you need to enclose the string in double quotes (e. g. &lt;code&gt;ack "defmodule MyGreatModule do"&lt;/code&gt;). &lt;/p&gt;

&lt;p&gt;One very interesting option for ack is to tell it to search within a given range of code.  For instance if I'm looking for a function called "reverse_string_and_json_encode" then I can use a few parameters to ack on the command line to help me quickly narrow my search.  By using this command line: &lt;code&gt;ack --range-start 'def reverse_string_and_json_encode do' --range-end 'end'&lt;/code&gt; I can find the exact definition of the function whereever it's defined.  Two important details about range-start and range-end:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Range-start and range-end both support regular expressions.  For example, if I weren't quite sure of the name of the function I could also pass &lt;code&gt;--range-start 'def reverse\w+'&lt;/code&gt; and &lt;code&gt;--range-end 'end'&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;You use single quotes (not double quotes) around the strings you use with range-start and range-end.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Are There Other Options?
&lt;/h2&gt;

&lt;p&gt;If you don't care to use ack (or you have some sort of aversion to it), ack actually lists several good alternatives on their home page (under More Tools → Other grep-like tools). I won't bother to repeat them here. &lt;/p&gt;

&lt;h2&gt;
  
  
  What Else?
&lt;/h2&gt;

&lt;p&gt;If you spot something I've got wrong, please let me know!  One reason I even bother to write this up is that I know of no method faster to find something I've gotten wrong than to share it with nerds.  &lt;/p&gt;

</description>
      <category>ack</category>
      <category>elixir</category>
      <category>tooling</category>
    </item>
    <item>
      <title>i = i + 1</title>
      <dc:creator>Onorio Catenacci</dc:creator>
      <pubDate>Mon, 02 May 2022 20:05:07 +0000</pubDate>
      <link>https://dev.to/olddutchcap/i-i-1-4c1n</link>
      <guid>https://dev.to/olddutchcap/i-i-1-4c1n</guid>
      <description>&lt;p&gt;My father ran a job shop over in Fraser, Michigan.  In this job shop he had some computer numerical control (CNC) machines.  These were machines that had been purchased from a Swiss firm and although they worked pretty well, like any machine they needed occasional maintenance. And my father, like any smart business man, was loath to spend money he didn't need to spend so he'd try to figure out problems with the CNC by himself before contacting the vendor's paid  and expensive tech support service. &lt;/p&gt;

&lt;p&gt;He had in his shop one person who fancied himself a bit knowledgeable on the subject of computers and so he volunteered to take a look at the problem and see if he could solve it.  I gather from what my dad told me afterward that this machine had its instructions coded in something akin to BASIC.  This employee studied the instructions and finally thought he'd found the issue.  He pointed to the source on a line reading something like &lt;code&gt;i = i + 1&lt;/code&gt; and told my father that must be the problem because there was no way that could be correct.  &lt;/p&gt;

&lt;p&gt;My father related this to me and I, of course, informed him that wasn't meant to be read as an algebraic statement; it's meant to be read as an instruction.  &lt;em&gt;Take the value in i, add one to it and then store that value back into the memory location where i is.&lt;/em&gt;  &lt;/p&gt;

&lt;p&gt;Now having said all that I can certainly understand why my dad's employee thought it must be the problem.  Algrebraically the statement would be nonsense.  Most of us who write software for a living have gotten so accustomed to this idiom (or the C/C++/C#/Java idiom of &lt;code&gt;i++;&lt;/code&gt;) that it doesn't give us a moment's pause to see it any more. &lt;/p&gt;

&lt;h2&gt;
  
  
  Why Do We Accept This As Normal?
&lt;/h2&gt;

&lt;p&gt;So to my mind the question naturally arises--when so many of us (and indeed the inventors of most programming languages of note) have a good background in mathematics, why do we accept this sort of abberation of expression as being perfectly normal and needed? &lt;/p&gt;

&lt;p&gt;At one point given limited memory it likely made a lot of sense to allow this pattern that I've heard referred to as "destructive assignment".  &lt;em&gt;Since I'll use that term a few more times from here on out I'll refer to it as &lt;strong&gt;DA&lt;/strong&gt;&lt;/em&gt;. When you've only got 64Kb of memory then conserving memory is a major engineering concern.  The alternative (writing the value to a different memory location and binding it to another name) would quickly become a problem in a tight memory situation. But unless someone is doing embedded software development I'd think the issue of tight memory constraints is no longer a main consideration in how we write software. &lt;/p&gt;

&lt;p&gt;Also not everyone does accept it as normal.  There are a few programming languages which distinguish assignment from equality testing.  Pascal uses &lt;code&gt;:=&lt;/code&gt; for assignment and &lt;code&gt;=&lt;/code&gt; for equality testing.  C and languages derived from it use &lt;code&gt;=&lt;/code&gt; for assignment and &lt;code&gt;==&lt;/code&gt; for equality testing (a situation that has caused some very tricky bugs in C code over the years).  &lt;code&gt;i := i + 1&lt;/code&gt; is a very visible way to show we're not trying to assert equality. &lt;/p&gt;

&lt;p&gt;Even more to the point DA does contradict our understanding of mathematics.  If I have an equation &lt;code&gt;4 = x + 2&lt;/code&gt; there's only one value that will make that statement true.  While I don't know what &lt;code&gt;x&lt;/code&gt; is (let's pretend that the answer isn't trivial to arrive at) it's an  &lt;em&gt;unknown&lt;/em&gt; value not a variable.  It doesn't vary at all. In that sense calling something which supports DA a "variable" is actually more correct than we may initially realize.  &lt;/p&gt;

&lt;h2&gt;
  
  
  Modeling Reality?
&lt;/h2&gt;

&lt;p&gt;The people I know who are the biggest proponents for OOP usually tell me they prefer it because it allows them to code in a way that mirrors reality.  That's an excellent goal for sure. We certainly want to create software that closely mirrors the problem domain we're tackling. And it's true, that is a benefit of OOP.  But in what reality can an unknown take on arbitrary values?  For any algebraic equation you can name (or at least any I can think of) there's a limited set of values which make the equation true.  &lt;/p&gt;

&lt;p&gt;In fairness I am conflating two ideas.  OOP isn't the same as imperative programming; DA is a feature of the imperative programming paradigm.  That said though, so much OOP is so closely aligned with imperative programming that they often seem synonomous. And pretty much anytime someone codes a loop in any imperative language they code a loop counter (or their colleagues give them grief).  Absent newer approaches (like LINQ which, coincidentally, is modelled on the functional programming paradigm) if you code a loop that needs to execute a definite number of times without a loop counter all you're going to do is cause a lot of head-scratching and perhaps anger among your colleagues. &lt;/p&gt;

&lt;p&gt;Now having done both functional and imperative programming I can tell you that there are good and bad aspects to both paradigms.  But one thing that is a big accidental complexity in the imperative paradigm (at least to my mind) is DA.  If a developer uses DA carefully and intentionally then it's no problem.  But all of us get under deadline pressure and carefully checking things is one of the first things we jettison.  We assume everything will proceed on the happy path. &lt;/p&gt;

&lt;p&gt;And there's another very important accidental complexity associated with DA. Most developers working in software these days will not be aware of all the issues that manual memory management caused for developers in the past.  And part of the problem with manual memory management was DA.  In the days of manual memory management it was a common practice to store memory addresses in memory (C's pointers). When I can easily overwrite a memory address with another one and not only does the compiler not warn me--it is actually expected behavior--the potential for buffer overruns and other hard to trace bugs is greatly increased. &lt;/p&gt;

&lt;p&gt;And even if you are very careful to insure you don't do DA unless it's absolutely justified your colleagues may need to interact with the software artifacts you provide and they may not be as careful as you are in insuring they only use DA when absolutely needed.  I mean why should we rely on software developer discipline when we can push the issue to the compiler where it really belongs?  Let the compiler check us so we don't have to worry about having missed something. &lt;/p&gt;

&lt;h2&gt;
  
  
  It's Past Time To Move On From Destructive Assignment
&lt;/h2&gt;

&lt;p&gt;There's a whole class of errors which can be laid right at the feet of DA.  One can make off-by-one errors occur in functional languages (which lack destructive assignment). It is, however, considerably more difficult to have it occur due to the fact that DA simply isn't allowed and the compiler will raise an error if you try to do so.  In fact running a loop for a fixed number of times actually becomes slightly more work in the functional paradigm. Off-by-one errors are sadly quite common in languages that allow DA. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/Tony_Hoare#Apologies_and_retractions"&gt;C. A. R. Hoare once refered to nulls as his "Billion Dollar Mistake"&lt;/a&gt;.  And, no doubt nulls and null checking seem to have added far more complexity than they've removed.  But DA is also responsible for a lot of accidental complexity and there's not really a good reason to allow it going forward.  We can't fix all the legacy code in the world that relies on this but we can learn better ways of coding to remove this accidental complexity. &lt;/p&gt;

</description>
      <category>functional</category>
      <category>programming</category>
    </item>
  </channel>
</rss>
