<?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: derek lawless</title>
    <description>The latest articles on DEV Community by derek lawless (@dereklawless).</description>
    <link>https://dev.to/dereklawless</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%2F233460%2F209802f8-6be0-4951-ade9-856193cd52d4.jpg</url>
      <title>DEV Community: derek lawless</title>
      <link>https://dev.to/dereklawless</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/dereklawless"/>
    <language>en</language>
    <item>
      <title>Downloading Lambda layer versions using the AWS CLI</title>
      <dc:creator>derek lawless</dc:creator>
      <pubDate>Thu, 16 Jun 2022 00:00:00 +0000</pubDate>
      <link>https://dev.to/dereklawless/downloading-lambda-layer-versions-using-the-aws-cli-2h0l</link>
      <guid>https://dev.to/dereklawless/downloading-lambda-layer-versions-using-the-aws-cli-2h0l</guid>
      <description>&lt;p&gt;The packaged .zip for a &lt;a href="https://docs.aws.amazon.com/lambda/latest/dg/configuration-layers.html"&gt;Lambda layer&lt;/a&gt; can be downloaded using the AWS console (appropriate IAM permissions notwithstanding) - as long as you have access to the host AWS account of course.&lt;/p&gt;

&lt;p&gt;If the Lambda layer originates in a &lt;em&gt;different AWS account&lt;/em&gt; you don't have console access to, &lt;strong&gt;you will need to use the AWS CLI&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;Why would you want or need to do this though?&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;As with any third party dependency it makes sense to examine it rather than simply trusting it to be benign in nature&lt;/li&gt;
&lt;li&gt;You want to override the layer's behaviour in a specific way (i.e. by merging a later layer) and need to examine its implementation&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Fortunately, the &lt;code&gt;aws lambda&lt;/code&gt; CLI provides two useful options - one for downloading a layer version by name, the other by its &lt;a href="https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html"&gt;ARN&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Downloading a Lambda layer version by name
&lt;/h2&gt;

&lt;p&gt;To download version 99 of a Lambda layer called &lt;code&gt;acme-corp-lambda-layer&lt;/code&gt; using its name, use the &lt;code&gt;get-layer-version&lt;/code&gt; option:&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="nv"&gt;URL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;aws lambda get-layer-version &lt;span class="nt"&gt;--layer-name&lt;/span&gt; ars:aws:lambda:&lt;span class="nv"&gt;$AWS_REGION&lt;/span&gt;:&lt;span class="nv"&gt;$AWS_ACME_CORP_ACCOUNT&lt;/span&gt;:layer:acme-corp-lambda-layer &lt;span class="nt"&gt;--version-number&lt;/span&gt;:99 &lt;span class="nt"&gt;--query&lt;/span&gt; Content.Location &lt;span class="nt"&gt;--output&lt;/span&gt; text&lt;span class="si"&gt;)&lt;/span&gt;

curl &lt;span class="nv"&gt;$URL&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; acme-corp-lambda-layer.zip
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Downloading a Lambda layer version by ARN
&lt;/h2&gt;

&lt;p&gt;If you want to download version 99 of of the layer using its ARN instead, use &lt;code&gt;get-layer-version-by-arn&lt;/code&gt;:&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="nv"&gt;URL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;aws lambda get-layer-version-by-arn &lt;span class="nt"&gt;--arn&lt;/span&gt; arn:aws:lambda:&lt;span class="nv"&gt;$AWS_REGION&lt;/span&gt;:&lt;span class="nv"&gt;$AWS_ACME_CORP_ACCOUNT&lt;/span&gt;:layer:my-lambda-layer:99 &lt;span class="nt"&gt;--query&lt;/span&gt; Content.Location &lt;span class="nt"&gt;--output&lt;/span&gt; text&lt;span class="si"&gt;)&lt;/span&gt;

curl &lt;span class="nv"&gt;$URL&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; acme-corp-lambda-layer.zip
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>aws</category>
      <category>lambda</category>
    </item>
    <item>
      <title>Conditionally tagging resources in CloudFormation</title>
      <dc:creator>derek lawless</dc:creator>
      <pubDate>Wed, 27 Apr 2022 00:00:00 +0000</pubDate>
      <link>https://dev.to/dereklawless/conditionally-tagging-resources-in-cloudformation-165o</link>
      <guid>https://dev.to/dereklawless/conditionally-tagging-resources-in-cloudformation-165o</guid>
      <description>&lt;p&gt;While tagging resources in CloudFormation is straightforward, &lt;em&gt;conditionally tagging&lt;/em&gt; them is a little non-obvious and requires use of &lt;a href="https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/conditions-section-structure.html"&gt;conditions&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Use case: tagging a release version
&lt;/h2&gt;

&lt;p&gt;I wanted the ability to conditionally tag a Secrets Manager secret with a release version when the secret was deployed into production. For lower environments, I didn't care / want to specify a release version.&lt;/p&gt;

&lt;p&gt;First, we define a parameter that will contain the release version:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;Parameters&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;ReleaseVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;Type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;String&lt;/span&gt;
        &lt;span class="na"&gt;Description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;The release version e.g. 1.2.3&lt;/span&gt;
        &lt;span class="na"&gt;Default&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, we define a condition to easily check whether a non-default value was provided for the parameter:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;Conditions&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;HasNoReleaseVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="kt"&gt;!Equals&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;!Ref&lt;/span&gt; &lt;span class="nv"&gt;ReleaseVersion&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;'&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, we tie it all together on the resource by conditionally setting the &lt;code&gt;release&lt;/code&gt; tag depending on the evaluation of &lt;code&gt;HasNoReleaseVersion&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;Resources&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;MySecret&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;Properties&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;Tags&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
                &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;Fn::If:&lt;/span&gt;
                    &lt;span class="s"&gt;- HasNoReleaseVersion&lt;/span&gt;
                    &lt;span class="s"&gt;- !Ref AWS::NoValue&lt;/span&gt;
                    &lt;span class="s"&gt;- Key&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="s"&gt;release&lt;/span&gt;
                    &lt;span class="s"&gt;- Value&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;!Ref&lt;/span&gt; &lt;span class="s"&gt;ReleaseVersion&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;AWS::NoValue&lt;/code&gt; &lt;a href="https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/pseudo-parameter-reference.html"&gt;pseudo parameter&lt;/a&gt; will ensure the tag is not created unless a non-default value for the release version was provided.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>cloudformation</category>
    </item>
    <item>
      <title>The unknown Type in TypeScript</title>
      <dc:creator>derek lawless</dc:creator>
      <pubDate>Wed, 21 Apr 2021 00:00:00 +0000</pubDate>
      <link>https://dev.to/dereklawless/the-unknown-type-in-typescript-lj1</link>
      <guid>https://dev.to/dereklawless/the-unknown-type-in-typescript-lj1</guid>
      <description>&lt;p&gt;Introduced in &lt;a href="https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-0.html#new-unknown-top-type"&gt;TypeScript 3.0&lt;/a&gt;, the &lt;code&gt;unknown&lt;/code&gt; type exists to provide a type-safe counterpart to the &lt;code&gt;any&lt;/code&gt; type. To understand why this was considered a necessary or desirable addition to TypeScript, we need to revisit &lt;code&gt;any&lt;/code&gt; and why its use can be problematic. &lt;/p&gt;

&lt;h2&gt;
  
  
  The &lt;code&gt;any&lt;/code&gt; type
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;any&lt;/code&gt; type has been in TypeScript since its initial release and represents all possible &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures"&gt;JavaScript values&lt;/a&gt; (making it a &lt;a href="https://en.wikipedia.org/wiki/Top_type"&gt;top type&lt;/a&gt; of the type system).&lt;/p&gt;

&lt;p&gt;&lt;code&gt;any&lt;/code&gt; can be problematic because of its flexibility - it allows typing to be circumvented:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// TypeScript&lt;/span&gt;

&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Any value can be assigned to an 'any' type:&lt;/span&gt;
&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;value&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="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Hello world&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;
&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;
&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;now&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Symbol&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="c1"&gt;// ...&lt;/span&gt;

&lt;span class="c1"&gt;// No check on use:&lt;/span&gt;
&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bar&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;baz&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="o"&gt;~~~&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="nx"&gt;endraw&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;While&lt;/span&gt; &lt;span class="nx"&gt;convenient&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="nx"&gt;raw&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`any`&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="nx"&gt;endraw&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;undoubtedly&lt;/span&gt; &lt;span class="nx"&gt;increases&lt;/span&gt; &lt;span class="nx"&gt;the&lt;/span&gt; &lt;span class="nx"&gt;risk&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;errors&lt;/span&gt; &lt;span class="nx"&gt;or&lt;/span&gt; &lt;span class="nx"&gt;unexpected&lt;/span&gt; &lt;span class="nx"&gt;behaviour&lt;/span&gt; &lt;span class="nx"&gt;sneaking&lt;/span&gt; &lt;span class="nx"&gt;into&lt;/span&gt; &lt;span class="nx"&gt;code&lt;/span&gt; &lt;span class="nx"&gt;simply&lt;/span&gt; &lt;span class="nx"&gt;by&lt;/span&gt; &lt;span class="nx"&gt;negating&lt;/span&gt; &lt;span class="nx"&gt;one&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;the&lt;/span&gt; &lt;span class="nx"&gt;primary&lt;/span&gt; &lt;span class="nx"&gt;benefits&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;using&lt;/span&gt; &lt;span class="nx"&gt;TypeScript&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nx"&gt;the&lt;/span&gt; &lt;span class="nx"&gt;first&lt;/span&gt; &lt;span class="nx"&gt;instance&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;strong&lt;/span&gt; &lt;span class="nx"&gt;typing&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;

&lt;span class="err"&gt;##&lt;/span&gt; &lt;span class="nx"&gt;The&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="nx"&gt;raw&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`unknown`&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="nx"&gt;endraw&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt;
&lt;span class="nx"&gt;The&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="nx"&gt;raw&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`unknown`&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="nx"&gt;endraw&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="nx"&gt;less&lt;/span&gt; &lt;span class="nx"&gt;permissive&lt;/span&gt; &lt;span class="nx"&gt;than&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="nx"&gt;raw&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`any`&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="nx"&gt;endraw&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="p"&gt;}.&lt;/span&gt; &lt;span class="nx"&gt;While&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="nx"&gt;assignable&lt;/span&gt; &lt;span class="nx"&gt;an&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="nx"&gt;raw&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`unknown`&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="nx"&gt;endraw&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;can&lt;/span&gt; &lt;span class="nx"&gt;only&lt;/span&gt; &lt;span class="nx"&gt;be&lt;/span&gt; &lt;span class="nx"&gt;assigned&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt; &lt;span class="nx"&gt;itself&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;or&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="nx"&gt;raw&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`any`&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="nx"&gt;endraw&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="p"&gt;}).&lt;/span&gt;

&lt;span class="nx"&gt;Revisiting&lt;/span&gt; &lt;span class="nx"&gt;the&lt;/span&gt; &lt;span class="nx"&gt;previous&lt;/span&gt; &lt;span class="nx"&gt;example&lt;/span&gt;&lt;span class="p"&gt;:{&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="nx"&gt;raw&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="o"&gt;~~~&lt;/span&gt;&lt;span class="nx"&gt;typescript&lt;/span&gt;
&lt;span class="c1"&gt;// TypeScript&lt;/span&gt;

&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;unknown&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Any value can be assigned to an 'unknown' type:&lt;/span&gt;
&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;value&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="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Hello world&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;
&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;
&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;now&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Symbol&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="c1"&gt;// ...&lt;/span&gt;

&lt;span class="c1"&gt;// An 'unknown' type can be assigned to 'any' or 'unknown':&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;toAny&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;toUnknown&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;unknown&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Assignments to other types will fail:&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;toBoolean&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="o"&gt;~~~&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="nx"&gt;endraw&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="err"&gt;###&lt;/span&gt; &lt;span class="nx"&gt;Narrowing&lt;/span&gt; &lt;span class="nx"&gt;and&lt;/span&gt; &lt;span class="nx"&gt;asserting&lt;/span&gt;
&lt;span class="nx"&gt;Operations&lt;/span&gt; &lt;span class="nx"&gt;cannot&lt;/span&gt; &lt;span class="nx"&gt;be&lt;/span&gt; &lt;span class="nx"&gt;performed&lt;/span&gt; &lt;span class="nx"&gt;on&lt;/span&gt; &lt;span class="nx"&gt;an&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="nx"&gt;raw&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`unknown`&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="nx"&gt;endraw&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;without&lt;/span&gt; &lt;span class="nx"&gt;first&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;narrowing&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="nx"&gt;https&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="c1"&gt;//www.typescriptlang.org/docs/handbook/2/narrowing.html) to a more specific type or asserting:{% raw %}&lt;/span&gt;

&lt;span class="o"&gt;~~~&lt;/span&gt;&lt;span class="nx"&gt;typescript&lt;/span&gt;
&lt;span class="c1"&gt;// TypeScript&lt;/span&gt;

&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;unknown&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Operations including the following will error:&lt;/span&gt;
&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bar&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;baz&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="o"&gt;~~~&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="nx"&gt;endraw&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;One&lt;/span&gt; &lt;span class="nx"&gt;method&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;narrowing&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="kd"&gt;with&lt;/span&gt; &lt;span class="nx"&gt;the&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="nx"&gt;raw&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`typeof`&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="nx"&gt;endraw&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nl"&gt;operator&lt;/span&gt;&lt;span class="p"&gt;:{&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="nx"&gt;raw&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="o"&gt;~~~&lt;/span&gt;&lt;span class="nx"&gt;typescript&lt;/span&gt;
&lt;span class="c1"&gt;// TypeScript&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;unknown&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;hello world&lt;/span&gt;&lt;span class="dl"&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="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;string&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="c1"&gt;// Narrowed to a string type, can safely call 'toUpperCase()'&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toUpperCase&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="o"&gt;%&lt;/span&gt; &lt;span class="nx"&gt;endraw&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;Types&lt;/span&gt; &lt;span class="nx"&gt;can&lt;/span&gt; &lt;span class="nx"&gt;be&lt;/span&gt; &lt;span class="nx"&gt;asserted&lt;/span&gt; &lt;span class="nx"&gt;using&lt;/span&gt; &lt;span class="nx"&gt;the&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="nx"&gt;raw&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`as`&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="nx"&gt;endraw&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nl"&gt;operator&lt;/span&gt;&lt;span class="p"&gt;:{&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="nx"&gt;raw&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="o"&gt;~~~&lt;/span&gt;&lt;span class="nx"&gt;typescript&lt;/span&gt;
&lt;span class="c1"&gt;// TypeScript&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;value1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;unknown&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;hello world&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;value2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;unknown&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;value1&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;toUpperCase&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt; &lt;span class="c1"&gt;// Ok&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;value2&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;toUpperCase&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt; &lt;span class="c1"&gt;// Error&lt;/span&gt;
&lt;span class="o"&gt;~~~&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="nx"&gt;endraw&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="err"&gt;🔔&lt;/span&gt; &lt;span class="nx"&gt;Type&lt;/span&gt; &lt;span class="nx"&gt;assertions&lt;/span&gt; &lt;span class="nx"&gt;should&lt;/span&gt; &lt;span class="nx"&gt;be&lt;/span&gt; &lt;span class="nx"&gt;used&lt;/span&gt; &lt;span class="kd"&gt;with&lt;/span&gt; &lt;span class="nx"&gt;caution&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;they&lt;/span&gt; &lt;span class="nx"&gt;may&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nx"&gt;expected&lt;/span&gt; &lt;span class="nx"&gt;run&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;time&lt;/span&gt; &lt;span class="nx"&gt;issues&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;

&lt;span class="err"&gt;###&lt;/span&gt; &lt;span class="nx"&gt;Unions&lt;/span&gt; &lt;span class="nx"&gt;and&lt;/span&gt; &lt;span class="nx"&gt;intersections&lt;/span&gt;
&lt;span class="nx"&gt;In&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;union&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="nx"&gt;https&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="c1"&gt;//www.typescriptlang.org/docs/handbook/2/everyday-types.html#union-types), an {% raw %}`unknown` absorbs everything else (the exception to this rule is a union with `any`).&lt;/span&gt;

&lt;span class="nx"&gt;With&lt;/span&gt; &lt;span class="nx"&gt;an&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;intersection&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="nx"&gt;https&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="c1"&gt;//www.typescriptlang.org/docs/handbook/2/objects.html#intersection-types), the converse applies - that is, other types will subsume the `unknown`.&lt;/span&gt;

&lt;span class="o"&gt;~~~&lt;/span&gt;&lt;span class="nx"&gt;typescript&lt;/span&gt;
&lt;span class="c1"&gt;// TypeScript&lt;/span&gt;

&lt;span class="c1"&gt;// Unions:&lt;/span&gt;
&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;union1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;unknown&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;union2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;unknown&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;union3&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;unknown&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;union4&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;unknown&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;union5&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;unknown&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;union6&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;unknown&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;unionN&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;unknown&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// any&lt;/span&gt;

&lt;span class="c1"&gt;// Intersections:&lt;/span&gt;
&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;intersection1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;unknown&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;intersection2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;unknown&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;intersection3&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;unknown&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;intersection4&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;unknown&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;intersection5&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;unknown&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;intersection6&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;unknown&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// never&lt;/span&gt;
&lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;intersectionN&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;unknown&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// any&lt;/span&gt;
&lt;span class="o"&gt;~~~&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="nx"&gt;endraw&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="err"&gt;##&lt;/span&gt; &lt;span class="nx"&gt;When&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt; &lt;span class="nx"&gt;use&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="nx"&gt;raw&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`unknown`&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="nx"&gt;endraw&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nx"&gt;Wherever&lt;/span&gt; &lt;span class="nx"&gt;possible&lt;/span&gt; &lt;span class="nx"&gt;specify&lt;/span&gt; &lt;span class="nx"&gt;an&lt;/span&gt; &lt;span class="nx"&gt;explicit&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;and&lt;/span&gt; &lt;span class="nx"&gt;avoid&lt;/span&gt; &lt;span class="nx"&gt;using&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="nx"&gt;raw&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`any`&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="nx"&gt;endraw&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;or&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="nx"&gt;raw&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`unknown`&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="nx"&gt;endraw&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="p"&gt;}.&lt;/span&gt; &lt;span class="nx"&gt;Explicitly&lt;/span&gt; &lt;span class="nx"&gt;specifying&lt;/span&gt; &lt;span class="nx"&gt;types&lt;/span&gt; &lt;span class="nx"&gt;allows&lt;/span&gt; &lt;span class="nx"&gt;you&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt; &lt;span class="nx"&gt;take&lt;/span&gt; &lt;span class="nx"&gt;advantage&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;TypeScript&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;s compile-time checking, provides a more explicit contract (something especially important for library writers to consider), and should result in fewer run-time issues.

Where this is not possible, prefer {% raw %}`unknown` over `any` as its characteristics require more deliberate and thoughtful use.
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
      <category>typescript</category>
    </item>
    <item>
      <title>Nemawashi</title>
      <dc:creator>derek lawless</dc:creator>
      <pubDate>Thu, 21 Jan 2021 00:00:00 +0000</pubDate>
      <link>https://dev.to/dereklawless/nemawashi-1i42</link>
      <guid>https://dev.to/dereklawless/nemawashi-1i42</guid>
      <description>&lt;p&gt;Literally translating as "to go around the roots", &lt;a href="https://en.wikipedia.org/wiki/Nemawashi"&gt;Nemawashi&lt;/a&gt; (根回し) historically described the farming activity of transplanting a tree from one location to another. Before transplanting, the tree's roots are dug around and soil from the new location is introduced. This allows the tree to acclimate to its new environment prior to being moved, increasing its chances of survival.&lt;/p&gt;

&lt;p&gt;In modern times, Nemawashi describes a process of laying the foundation for a proposal by first seeking consensus inside and outside the team informally - allowing others to give their opinions and contribute - before formally presenting the proposal. This increases the probability of the proposal being accepted and ultimately executed upon. &lt;/p&gt;

&lt;p&gt;Although widespread in Japanese business, Nemawashi is perhaps most recognisable outside Japan as one of the 13 pillars of the &lt;a href="https://www.toyotauk.com/how-we-manufacture/glossary.html"&gt;Toyota Production System&lt;/a&gt; (from which &lt;a href="https://www.lean.org/WhatsLean/"&gt;Lean&lt;/a&gt; was partly derived).&lt;/p&gt;

&lt;h2&gt;
  
  
  Nemawashi and software development
&lt;/h2&gt;

&lt;p&gt;Conversation about Nemawashi typically centres around the application of Lean to classical business activities and manufacturing. However, it's also a technique that software development teams can make effective use of.&lt;/p&gt;

&lt;h3&gt;
  
  
  Getting buy-in
&lt;/h3&gt;

&lt;p&gt;Consider a significant architectural change to an existing software system e.g. moving from a monolithic architecture to a microservices-based one.&lt;/p&gt;

&lt;p&gt;An architect can dictate a design to the development team, handing it off to be implemented according to her vision or she can practice Nemawashi.&lt;/p&gt;

&lt;p&gt;Nemawashi does not mean the architecture will be compromised as a result of design by committee, quite the opposite. By allowing the development team to examine the proposed new architecture in detail before architecture sign-off and provide their inputs and insights, buy-in amongst team members will be increased.&lt;/p&gt;

&lt;p&gt;On a software development project of any complexity having a development team operating beyond the role of reluctant implementor can be a critical factor in maximising the probability of success.&lt;/p&gt;

&lt;h3&gt;
  
  
  Building consensus
&lt;/h3&gt;

&lt;p&gt;Proposals may be organisationally or politically sensitive for a variety of reasons.&lt;/p&gt;

&lt;p&gt;A proposal to move from manual infrastructure management on a project to &lt;a href="https://en.wikipedia.org/wiki/Infrastructure_as_code"&gt;Infrastructure as Code&lt;/a&gt; (IaC) might be viewed with a mix of suspicion, concern, and derision by an existing infrastructure team. Athough there may be an element of self-preservation on the part of the infrastructure team, their views should not be dismissed as entirely unfounded. &lt;/p&gt;

&lt;p&gt;Here, Nemawashi can be leveraged to build consensus with the infrastructure team - acclimating them to the proposal through positive engagement, assuaging their concerns, being open to feedback, and so on.&lt;/p&gt;

&lt;h3&gt;
  
  
  The goal
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;The goal is to see your proposal succeed.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Nemawashi provides a method for achieving this, recognising that by building consensus and offering inclusivity the art of persuasion is made easier. &lt;/p&gt;

&lt;p&gt;Nemawashi is somewhat orthogonal to the model of traditional software team 'leadership', where forcefulness is viewed as a positive attribute and celebrated. (There can be little doubt this is partly because the software development industry is wholly under-representative of society.)&lt;/p&gt;

&lt;p&gt;As development teams diversify - bringing new perspectives, approaches, and viewpoints - methods such as Nemawashi may become more prevalent and, I believe, recognised as a key attribute of high-performance software development teams.&lt;/p&gt;

</description>
      <category>career</category>
      <category>leadership</category>
      <category>softwaredevelopment</category>
      <category>teams</category>
    </item>
    <item>
      <title>Binary Search</title>
      <dc:creator>derek lawless</dc:creator>
      <pubDate>Sat, 21 Nov 2020 00:00:00 +0000</pubDate>
      <link>https://dev.to/dereklawless/binary-search-12gf</link>
      <guid>https://dev.to/dereklawless/binary-search-12gf</guid>
      <description>&lt;p&gt;Liquid syntax error: 'raw' tag was never closed&lt;/p&gt;
</description>
      <category>algorithms</category>
      <category>datastructures</category>
    </item>
    <item>
      <title>Sieve of Eratosthenes</title>
      <dc:creator>derek lawless</dc:creator>
      <pubDate>Sat, 07 Nov 2020 00:00:00 +0000</pubDate>
      <link>https://dev.to/dereklawless/sieve-of-eratosthenes-4ng</link>
      <guid>https://dev.to/dereklawless/sieve-of-eratosthenes-4ng</guid>
      <description>&lt;p&gt;Liquid syntax error: 'raw' tag was never closed&lt;/p&gt;
</description>
      <category>algorithms</category>
      <category>datastructures</category>
    </item>
    <item>
      <title>Fallacies of Distributed Computing: 8. The network is homogeneous</title>
      <dc:creator>derek lawless</dc:creator>
      <pubDate>Tue, 30 Jun 2020 00:00:00 +0000</pubDate>
      <link>https://dev.to/dereklawless/fallacies-of-distributed-computing-8-the-network-is-homogeneous-4af4</link>
      <guid>https://dev.to/dereklawless/fallacies-of-distributed-computing-8-the-network-is-homogeneous-4af4</guid>
      <description>&lt;p&gt;&lt;a href="https://web.archive.org/web/20171107014323/http://blog.fogcreek.com/eight-fallacies-of-distributed-computing-tech-talk/"&gt;The fallacies of distributed computing&lt;/a&gt; are a set of assertions describing false assumptions made about distributed systems. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/L._Peter_Deutsch"&gt;L. Peter Deutsch&lt;/a&gt; drafted the first 7 fallacies in 1994, with the 8&lt;sup&gt;th&lt;/sup&gt; added by &lt;a href="https://en.wikipedia.org/wiki/James_Gosling"&gt;James Gosling&lt;/a&gt; in 1997.&lt;/p&gt;

&lt;p&gt;The 8 fallacies are:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://dereklawless.ie/fallacies-of-distributed-computing-1-the-network-is-reliable"&gt;The network is reliable&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dereklawless.ie/fallacies-of-distributed-computing-2-latency-is-zero"&gt;Latency is zero&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dereklawless.ie/fallacies-of-distributed-computing-3-bandwidth-is-infinite"&gt;Bandwidth is infinite&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dereklawless.ie/fallacies-of-distributed-computing-4-the-network-is-secure"&gt;The network is secure&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dereklawless.ie/fallacies-of-distributed-computing-5-topology-doesnt-change"&gt;Topology doesn't change&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dereklawless.ie/fallacies-of-distributed-computing-6-there-is-one-administrator"&gt;There is one administrator&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dereklawless.ie/fallacies-of-distributed-computing-7-transport-cost-is-zero"&gt;Transport cost is zero&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dereklawless.ie/fallacies-of-distributed-computing-8-the-network-is-homogeneous"&gt;The network is homogeneous&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  8. The network is homogeneous
&lt;/h2&gt;

&lt;h3&gt;
  
  
  The problem
&lt;/h3&gt;

&lt;p&gt;Networks typically must support a wide variety of connected clients -- from desktop-class machines to mobile and IoT devices. These devices and the applications running on them may not be interoperable and a variety of standards-based and proprietary protocols and data formats may be in use.&lt;/p&gt;

&lt;p&gt;The network is not homogenous, it is heterogenous.&lt;/p&gt;

&lt;h3&gt;
  
  
  Solutions
&lt;/h3&gt;

&lt;p&gt;Interoperability is key.&lt;/p&gt;

&lt;p&gt;Where possible, avoid applications that use proprietary protocols in favour of those leveraging standards-based ones. Favour data formats that enable interoperability e.g. JSON or XML over binary formats (&lt;a href="https://dereklawless.ie/fallacies-of-distributed-computing-7-transport-cost-is-zero"&gt;fallacy 7&lt;/a&gt; aside) and architectures such as REST or web services, particularly when integrating with third-party services.&lt;/p&gt;

</description>
      <category>distributedcomputing</category>
    </item>
    <item>
      <title>Fallacies of Distributed Computing: 7. Transport cost is zero</title>
      <dc:creator>derek lawless</dc:creator>
      <pubDate>Mon, 29 Jun 2020 00:00:00 +0000</pubDate>
      <link>https://dev.to/dereklawless/fallacies-of-distributed-computing-7-transport-cost-is-zero-82b</link>
      <guid>https://dev.to/dereklawless/fallacies-of-distributed-computing-7-transport-cost-is-zero-82b</guid>
      <description>&lt;p&gt;&lt;a href="https://web.archive.org/web/20171107014323/http://blog.fogcreek.com/eight-fallacies-of-distributed-computing-tech-talk/"&gt;The fallacies of distributed computing&lt;/a&gt; are a set of assertions describing false assumptions made about distributed systems. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/L._Peter_Deutsch"&gt;L. Peter Deutsch&lt;/a&gt; drafted the first 7 fallacies in 1994, with the 8&lt;sup&gt;th&lt;/sup&gt; added by &lt;a href="https://en.wikipedia.org/wiki/James_Gosling"&gt;James Gosling&lt;/a&gt; in 1997.&lt;/p&gt;

&lt;p&gt;The 8 fallacies are:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://dereklawless.ie/fallacies-of-distributed-computing-1-the-network-is-reliable"&gt;The network is reliable&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dereklawless.ie/fallacies-of-distributed-computing-2-latency-is-zero"&gt;Latency is zero&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dereklawless.ie/fallacies-of-distributed-computing-3-bandwidth-is-infinite"&gt;Bandwidth is infinite&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dereklawless.ie/fallacies-of-distributed-computing-4-the-network-is-secure"&gt;The network is secure&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dereklawless.ie/fallacies-of-distributed-computing-5-topology-doesnt-change"&gt;Topology doesn't change&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dereklawless.ie/fallacies-of-distributed-computing-6-there-is-one-administrator"&gt;There is one administrator&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dereklawless.ie/fallacies-of-distributed-computing-7-transport-cost-is-zero"&gt;Transport cost is zero&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dereklawless.ie/fallacies-of-distributed-computing-8-the-network-is-homogeneous"&gt;The network is homogeneous&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  7. Transport cost is zero
&lt;/h2&gt;

&lt;h3&gt;
  
  
  The problem
&lt;/h3&gt;

&lt;p&gt;Whereas the &lt;a href="https://dereklawless.ie/fallacies-of-distributed-computing-2-latency-is-zero"&gt;second fallacy&lt;/a&gt; relates to the time taken to transport data over a network, the seventh fallacy relates to the resources required to do so.&lt;/p&gt;

&lt;h4&gt;
  
  
  Marshalling
&lt;/h4&gt;

&lt;p&gt;There is a resource (and resultant latency) cost in marshalling data between the application layer (&lt;a href="https://en.wikipedia.org/wiki/OSI_model#Layer_7:_Application_Layer"&gt;Layer 7&lt;/a&gt; on the OSI Reference Model) and transport layer (&lt;a href="https://en.wikipedia.org/wiki/OSI_model#Layer_4:_Transport_Layer"&gt;Layer 4&lt;/a&gt;) in order to send it over the network. While this may be an abstract concern where a system is deployed on own hardware, in a cloud computing context where resource utilisation equals money, it can be a more concrete concern.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Computing time costs money.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  Infrastructure
&lt;/h4&gt;

&lt;p&gt;The infrastructure used to set up and run the system will incur initial and ongoing costs -- for on-premises systems these may include the cost of physical hardware such as servers, switches, and routers to the salaries of the network operators who will hopefully manage everything.&lt;/p&gt;

&lt;p&gt;For cloud computing, while physical hardware costs will of course not be a factor of concern, you will pay a premium for the resources you utilise.&lt;/p&gt;

&lt;h3&gt;
  
  
  Solutions
&lt;/h3&gt;

&lt;p&gt;While the cost of infrastructure is mostly outside your control, optimising its use is within your domain. Reducing the time spent marshalling data between Layers 7 and 4 may be significant, depending on the functionality provided by the system. For example, the cost of transport for systems providing audio and video streaming, telephony, or realtime collaboration features can be brought closer to zero by leveraging an optimised data format e.g. &lt;a href="https://developers.google.com/protocol-buffers"&gt;protocol buffers&lt;/a&gt; vs. opting for JSON or XML.&lt;/p&gt;

</description>
      <category>distributedcomputing</category>
    </item>
    <item>
      <title>Fallacies of Distributed Computing: 6. There is one administrator</title>
      <dc:creator>derek lawless</dc:creator>
      <pubDate>Thu, 25 Jun 2020 00:00:00 +0000</pubDate>
      <link>https://dev.to/dereklawless/fallacies-of-distributed-computing-6-there-is-one-administrator-4hne</link>
      <guid>https://dev.to/dereklawless/fallacies-of-distributed-computing-6-there-is-one-administrator-4hne</guid>
      <description>&lt;p&gt;&lt;a href="https://web.archive.org/web/20171107014323/http://blog.fogcreek.com/eight-fallacies-of-distributed-computing-tech-talk/"&gt;The fallacies of distributed computing&lt;/a&gt; are a set of assertions describing false assumptions made about distributed systems. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/L._Peter_Deutsch"&gt;L. Peter Deutsch&lt;/a&gt; drafted the first 7 fallacies in 1994, with the 8&lt;sup&gt;th&lt;/sup&gt; added by &lt;a href="https://en.wikipedia.org/wiki/James_Gosling"&gt;James Gosling&lt;/a&gt; in 1997.&lt;/p&gt;

&lt;p&gt;The 8 fallacies are:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://dereklawless.ie/fallacies-of-distributed-computing-1-the-network-is-reliable"&gt;The network is reliable&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dereklawless.ie/fallacies-of-distributed-computing-2-latency-is-zero"&gt;Latency is zero&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dereklawless.ie/fallacies-of-distributed-computing-3-bandwidth-is-infinite"&gt;Bandwidth is infinite&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dereklawless.ie/fallacies-of-distributed-computing-4-the-network-is-secure"&gt;The network is secure&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dereklawless.ie/fallacies-of-distributed-computing-5-topology-doesnt-change"&gt;Topology doesn't change&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dereklawless.ie/fallacies-of-distributed-computing-6-there-is-one-administrator"&gt;There is one administrator&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dereklawless.ie/fallacies-of-distributed-computing-7-transport-cost-is-zero"&gt;Transport cost is zero&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dereklawless.ie/fallacies-of-distributed-computing-8-the-network-is-homogeneous"&gt;The network is homogeneous&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  6. There is one administrator
&lt;/h2&gt;

&lt;h3&gt;
  
  
  The problem
&lt;/h3&gt;

&lt;p&gt;If your system is self-contained and deployed into environments you fully control and manage there may indeed be only one administrator.&lt;/p&gt;

&lt;p&gt;However, it is more likely that any non-trivial system will depend on one or more in-house or third-party services for its operation and be deployed into environments you do not completely control or that differ from each other in any number of ways e.g. operating system and/or application framework versions, security patching policies, UAC, shared resources, firewall rules, etc. &lt;/p&gt;

&lt;p&gt;Multiple in-house teams may be involved to deploy and support the system, with each operating outside the processes governing that system's development. Third-party services -- their availability, compatibility, and development cadence -- will typically exist outside your control. &lt;/p&gt;

&lt;h3&gt;
  
  
  Solutions
&lt;/h3&gt;

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

&lt;p&gt;Where possible, automate the provisioning and configuration of the environments into which deployments are made.  &lt;a href="https://en.wikipedia.org/wiki/Infrastructure_as_code"&gt;Infrastructure as Code&lt;/a&gt; (or IaC) is a core element of DevOps, with infrastructure modelled in code (or DSL-as-template form) -- versus manually managed -- and are governed by the same quality processes as application source code e.g. revisioned using source control, unit tested, etc. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Ideally, regard IaC as a core competency -- that is, embed DevOps capabilities in your development teams.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  Logging and monitoring
&lt;/h4&gt;

&lt;p&gt;Diagnosing issues can be non-trivial at the best of times and particularly complex for distributed systems. To gain better visibility into the behaviour of a distributed system ensure that centralised logging, metrics, and tracing (the &lt;a href="https://www.oreilly.com/library/view/distributed-systems-observability/9781492033431/ch04.html"&gt;Three Pillars of Observability&lt;/a&gt;) have been considered as key aspects of the system's design.&lt;/p&gt;

&lt;h4&gt;
  
  
  Decoupling
&lt;/h4&gt;

&lt;p&gt;Ensuring appopriate decoupling between system components allows for greater resiliency in the event of either planned (system upgrades) or unplanned (service failure) downtime. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Introducing queuing (with appropriate retry policies, exponential backoff, and DLQs) is one method of achieving decoupling.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>distributedcomputing</category>
    </item>
    <item>
      <title>Queues</title>
      <dc:creator>derek lawless</dc:creator>
      <pubDate>Wed, 03 Jun 2020 00:00:00 +0000</pubDate>
      <link>https://dev.to/dereklawless/queues-8mf</link>
      <guid>https://dev.to/dereklawless/queues-8mf</guid>
      <description>&lt;p&gt;Liquid syntax error: 'raw' tag was never closed&lt;/p&gt;
</description>
      <category>algorithms</category>
      <category>datastructures</category>
    </item>
    <item>
      <title>Stacks</title>
      <dc:creator>derek lawless</dc:creator>
      <pubDate>Thu, 28 May 2020 00:00:00 +0000</pubDate>
      <link>https://dev.to/dereklawless/stacks-21h2</link>
      <guid>https://dev.to/dereklawless/stacks-21h2</guid>
      <description>&lt;p&gt;Liquid syntax error: 'raw' tag was never closed&lt;/p&gt;
</description>
      <category>algorithms</category>
      <category>datastructures</category>
    </item>
    <item>
      <title>Linked Lists, revisited</title>
      <dc:creator>derek lawless</dc:creator>
      <pubDate>Tue, 26 May 2020 00:00:00 +0000</pubDate>
      <link>https://dev.to/dereklawless/linked-lists-revisited-5e74</link>
      <guid>https://dev.to/dereklawless/linked-lists-revisited-5e74</guid>
      <description>&lt;p&gt;Liquid syntax error: 'raw' tag was never closed&lt;/p&gt;
</description>
      <category>algorithms</category>
      <category>datastructures</category>
    </item>
  </channel>
</rss>
