<?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: Mike Samuel</title>
    <description>The latest articles on DEV Community by Mike Samuel (@mikesamuel).</description>
    <link>https://dev.to/mikesamuel</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%2F157271%2Fa0ec88ed-18c5-410f-899a-992cfd45d14b.jpeg</url>
      <title>DEV Community: Mike Samuel</title>
      <link>https://dev.to/mikesamuel</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mikesamuel"/>
    <language>en</language>
    <item>
      <title>A web security story from 2008: silently securing JSON.parse</title>
      <dc:creator>Mike Samuel</dc:creator>
      <pubDate>Thu, 06 Apr 2023 18:58:41 +0000</pubDate>
      <link>https://dev.to/mikesamuel/2008-silently-securing-jsonparse-5cbb</link>
      <guid>https://dev.to/mikesamuel/2008-silently-securing-jsonparse-5cbb</guid>
      <description>&lt;p&gt;My 8 year old is doing a report for school on cyber security so I thought I'd dig up an old report for a break-the-web level security vulnerability that we silently fixed and which, as far as I know, has never been disclosed.&lt;/p&gt;

&lt;p&gt;Back in 2008, &lt;em&gt;JSON.parse&lt;/em&gt; was not part of the JavaScript language.  It was a separate library downloaded from json.org that &lt;a href="https://github.com/douglascrockford/JSON-js/blob/8da84c40419b33609cc1d0100395dca01a33b503/json2.js#L547-L552" rel="noopener noreferrer"&gt;used JavaScript &lt;code&gt;eval&lt;/code&gt; to unpack data&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// In the third stage we use the eval function to compile the text into a&lt;/span&gt;
&lt;span class="c1"&gt;// JavaScript structure. The "{" operator is subject to a syntactic ambiguity&lt;/span&gt;
&lt;span class="c1"&gt;// in JavaScript: it can begin a block or an object literal. We wrap the text&lt;/span&gt;
&lt;span class="c1"&gt;// in parens to eliminate the ambiguity.&lt;/span&gt;

                &lt;span class="nx"&gt;j&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;eval&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;text&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;)&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That code from a modern version of &lt;code&gt;json2.js&lt;/code&gt; wraps the JSON source text in parentheses, because &lt;code&gt;{}&lt;/code&gt; is a statement block in JavaScript but &lt;code&gt;({})&lt;/code&gt; is an object constructor.&lt;/p&gt;

&lt;p&gt;But a side-effect of using &lt;code&gt;eval&lt;/code&gt; is that, if the source text is something like &lt;code&gt;doVeryBadThings()&lt;/code&gt; then the JavaScript engine will happily do those very bad things, a classic &lt;a href="https://en.wikipedia.org/wiki/Arbitrary_code_execution" rel="noopener noreferrer"&gt;arbitrary code execution vulnerability&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;In computer security, arbitrary code execution (ACE) is an attacker's ability to run any commands or code of the attacker's choice on a target machine or in a target process.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Luckily, &lt;code&gt;json2.js&lt;/code&gt; did a bunch of regular expression checks to make sure that &lt;code&gt;text&lt;/code&gt; contained valid JSON, allowing commands that construct a value but not more powerful commands.&lt;/p&gt;

&lt;p&gt;Unluckily, JSON is not a &lt;em&gt;subset&lt;/em&gt; of JavaScript in the semantic sense.  There are important differences.&lt;/p&gt;

&lt;p&gt;To understand those differences, let's begin at the end with &lt;a href="http://archives.ecma-international.org/2008/TC39/tc39-2008-055.pdf" rel="noopener noreferrer"&gt;a change to the JavaScript language definition&lt;/a&gt; that I argued for based on this research.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi0ss4ch4yzc02x091ks7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi0ss4ch4yzc02x091ks7.png" alt="Screenshot of draft EcmaScript 3.1 specification quoted below" width="800" height="222"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here's the changed specification text.  It mirrors some explanatory text from Unicode §6.2.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;7.1 Unicode Format-Control Characters&lt;/strong&gt;&lt;br&gt;
The Unicode format-control characters (i.e., the characters in category “Cf” in the Unicode Character Database such as LEFT-TO-RIGHT MARK or RIGHT-TO-LEFT MARK) are control codes used to control the formatting of a range of text in the absence of higher-level protocols for this (such as mark-up languages).&lt;br&gt;
It is useful to allow these in source text to facilitate editing and display.&lt;br&gt;
The format control characters maybe used in identifiers, within comments, and within string literals and regular expression literals.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And to the right of that is some deleted specification text.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;7/2/2008 &lt;strong&gt;Deleted&lt;/strong&gt;: anywhere in the source text of an ECMAScript program. These characters are removed from the source text before applying the lexical grammar. Since these characters are removed before processing string and regular expression literals, one must use a Unicode escape sequence (see 7.6) to include a Unicode format-control character inside a string or regular expression literal&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;JavaScript allows these control flow characters, known as &lt;em&gt;[Cf]&lt;/em&gt;, in identifiers because they're important for proper presentation of identifiers, especially those in cursive writing systems like عنصر in the Perso-Arabic alphabet.  But they're a bit of a blind spot for many developers.&lt;/p&gt;

&lt;p&gt;They were "removed from the source text &lt;strong&gt;before&lt;/strong&gt; applying the lexical grammar."  That means before the JavaScript parser has broken the source code into tokens, so&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;before it pairs quotation marks (&lt;code&gt;"&lt;/code&gt;) that start and end quoted string values, and&lt;/li&gt;
&lt;li&gt;before it pairs delimiters like &lt;code&gt;/*&lt;/code&gt; and &lt;code&gt;*/&lt;/code&gt; or groups sequences like &lt;code&gt;//&lt;/code&gt; and &lt;code&gt;+=&lt;/code&gt; that have no analogue in JSON.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;JSON's specification does not have an equivalent clause.  json.org simply says:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A string is a sequence of zero or more Unicode characters, wrapped in double quotes, using backslash escapes.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I realized that, by putting a &lt;em&gt;[Cf]&lt;/em&gt; character between a backslash and a quote character I could get JavaScript's &lt;code&gt;eval&lt;/code&gt; to find a different end of string than the JSON grammar would as expressed in the regular expressions that vet the JSON text.  And that would allow me to sneak code into a JSON string that &lt;code&gt;eval&lt;/code&gt; would execute.&lt;/p&gt;

&lt;p&gt;I sent an email to the JSON maintainer, Douglas Crockford, with a &lt;a href="https://www.malwarebytes.com/glossary/proof-of-concept" rel="noopener noreferrer"&gt;proof of concept&lt;/a&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl8bctk6aj5lrjt2a9h1b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl8bctk6aj5lrjt2a9h1b.png" alt="Email to Douglas Crockford dated Mar 14 2008 / transcript below" width="800" height="621"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Transcript:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;From Mike Samuel&lt;br&gt;
to Douglas, Kevin&lt;/p&gt;

&lt;p&gt;On firefox 2, the below alerts "hello world" after "created string about to parse" using a version of &lt;a href="http://www.JSON.org/json2.js" rel="noopener noreferrer"&gt;http://www.JSON.org/json2.js&lt;/a&gt; downloaded earlier today.&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;json2.js&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;body&lt;/span&gt; &lt;span class="na"&gt;onload=&lt;/span&gt;&lt;span class="s"&gt;"
  var s = '&amp;amp;quot;\\\u200D\\&amp;amp;quot;, alert(\'hello world\') //&amp;amp;quot;\n';
  alert('created string about to parse');
  JSON.parse(s);
"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;From Douglas Crockford&lt;br&gt;
to me&lt;/p&gt;

&lt;p&gt;I don't understand what is happening here.&lt;br&gt;
Can you please explain the attack to me?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I didn't do a good job explaining it the first time though, but here is my second attempt:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F32bwx0o4rr2xo66m1bip.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F32bwx0o4rr2xo66m1bip.png" alt="Email quoted below" width="800" height="521"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The proof of concept was, where &lt;code&gt;|&lt;/code&gt; stands in for Unicode's &lt;em&gt;zero-width joiner&lt;/em&gt; character (U+200D):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\|\"&lt;/span&gt;&lt;span class="s2"&gt;, alert('hello world') //"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So a valid JSON parser would see just a single quoted string that contained two escaped characters, one of which was an escaped quote.  And the regular expressions that json2.js used to approximate had the same interpretation.&lt;/p&gt;

&lt;p&gt;So json2.js's security checks let that string through to JavaScript's &lt;code&gt;eval&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;But JavaScript's tokenizer saw something different because the control character is stripped out &lt;strong&gt;before tokenization&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;alert&lt;/span&gt;&lt;span class="p"&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="c1"&gt;//"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There, the two backslashes (which previously had a &lt;em&gt;[Cf]&lt;/em&gt; character between them) combine to form one escaped backslash.&lt;br&gt;
The previously escaped double quote now ends the string.  As the email explains (with bullets added for clarity):&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Firefox sees ...&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;a string literal containing only a backslash followed by&lt;/li&gt;
&lt;li&gt;a comma followed by&lt;/li&gt;
&lt;li&gt;a call to &lt;code&gt;alert&lt;/code&gt; followed by&lt;/li&gt;
&lt;li&gt;a line comment.&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;

&lt;p&gt;(That line comment hides the final double quote, so that &lt;code&gt;eval&lt;/code&gt; doesn't stop with a syntax error.)&lt;/p&gt;

&lt;p&gt;Douglas realized he needed to change the regular expression used by json2.js.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhkse1lkcd92q64oir8an.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhkse1lkcd92q64oir8an.png" alt="Email quoted below" width="800" height="511"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;So I think I have to do the same search for restricted characters that I do for ADsafe:&lt;/p&gt;


&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;cx&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;[\u&lt;/span&gt;&lt;span class="sr"&gt;0000-&lt;/span&gt;&lt;span class="se"&gt;\u&lt;/span&gt;&lt;span class="sr"&gt;001f&lt;/span&gt;&lt;span class="se"&gt;\u&lt;/span&gt;&lt;span class="sr"&gt;007f-&lt;/span&gt;&lt;span class="se"&gt;\u&lt;/span&gt;&lt;span class="sr"&gt;009f&lt;/span&gt;&lt;span class="se"&gt;\u&lt;/span&gt;&lt;span class="sr"&gt;00ad&lt;/span&gt;&lt;span class="se"&gt;\u&lt;/span&gt;&lt;span class="sr"&gt;0600-&lt;/span&gt;&lt;span class="se"&gt;\u&lt;/span&gt;&lt;span class="sr"&gt;0604&lt;/span&gt;&lt;span class="se"&gt;\u&lt;/span&gt;&lt;span class="sr"&gt;070f&lt;/span&gt;&lt;span class="se"&gt;\u&lt;/span&gt;&lt;span class="sr"&gt;17b4&lt;/span&gt;&lt;span class="se"&gt;\u&lt;/span&gt;&lt;span class="sr"&gt;17b5&lt;/span&gt;&lt;span class="se"&gt;\u&lt;/span&gt;&lt;span class="sr"&gt;200c-&lt;/span&gt;&lt;span class="se"&gt;\u&lt;/span&gt;&lt;span class="sr"&gt;200f&lt;/span&gt;&lt;span class="se"&gt;\u&lt;/span&gt;&lt;span class="sr"&gt;2028-&lt;/span&gt;&lt;span class="se"&gt;\u&lt;/span&gt;&lt;span class="sr"&gt;202f&lt;/span&gt;&lt;span class="se"&gt;\u&lt;/span&gt;&lt;span class="sr"&gt;2060-&lt;/span&gt;&lt;span class="se"&gt;\u&lt;/span&gt;&lt;span class="sr"&gt;206f&lt;/span&gt;&lt;span class="se"&gt;\u&lt;/span&gt;&lt;span class="sr"&gt;feff&lt;/span&gt;&lt;span class="se"&gt;\u&lt;/span&gt;&lt;span class="sr"&gt;fff0-&lt;/span&gt;&lt;span class="se"&gt;\u&lt;/span&gt;&lt;span class="sr"&gt;ffff&lt;/span&gt;&lt;span class="se"&gt;]&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;Bother.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;(Bother, indeed.)&lt;/p&gt;

&lt;p&gt;But then he realized that we didn't want attackers to be able to &lt;a href="https://www.theregister.com/2005/07/01/reverse_engineering_patches/" rel="noopener noreferrer"&gt;reverse engineer the vulnerability&lt;/a&gt; from that targeted change, so he unilaterally changed the definition of JSON on the fly.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If I put &lt;code&gt;cx&lt;/code&gt; in json.js and announce them[sic] problem, it will be giving a pretty clear signal to the miscreants about how to exploit but. But if instead, the fix is that I replace the regexp&lt;/p&gt;


&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="err"&gt;\\&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;with one that only matches &lt;code&gt;\&lt;/code&gt; followed by a printable ASCII character, then the the text will be rejected. My fix will be less informative.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So that's how an arbitrary code execution that affected almost all of the JavaScript code using JSON in 2008 was silently closed with, afaik, no-one the wiser.&lt;/p&gt;

</description>
      <category>cybersecurity</category>
      <category>security</category>
      <category>javascript</category>
      <category>webdev</category>
    </item>
    <item>
      <title>An alternative to "Distinguishing an Interpreter from a Compiler"</title>
      <dc:creator>Mike Samuel</dc:creator>
      <pubDate>Fri, 24 Mar 2023 20:15:40 +0000</pubDate>
      <link>https://dev.to/mikesamuel/thoughts-on-distinguishing-an-interpreter-from-a-compiler-8bb</link>
      <guid>https://dev.to/mikesamuel/thoughts-on-distinguishing-an-interpreter-from-a-compiler-8bb</guid>
      <description>&lt;p&gt;This is a response to &lt;a href="https://tratt.net/laurie/blog/2023/distinguishing_an_interpreter_from_a_compiler.html"&gt;Distinguishing an Interpreter from a Compiler&lt;/a&gt; in which I propose a capture-the-flag approach to distinguishing between compilers and interpreters.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;any language can be implemented as an interpreter or a compiler&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Laurence Tratt notes as he tries to define crisply what the difference is.  And he quotes Mario Wolcko's observation.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;For example, suppose the source program reads a number and then has a loop whose trip count is this number. The time it takes to compile this program will be independent of the number, in contrast to the time it takes to interpret the program.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This gets at the heart of the difference between &lt;em&gt;static&lt;/em&gt; (considering all possible runs of a program) and &lt;em&gt;dynamic&lt;/em&gt; (focused on one run of a program with known inputs) analysis.&lt;/p&gt;

&lt;p&gt;Tratt defines &lt;em&gt;compilation&lt;/em&gt; in terms of partially evaluating program elements; trading off work before runtime for work done at runtime.  And this ahead of time work can be amortized over many program runs or a single run on a large input.  This he boils this down to some big-O notation tests; crisp and mathematical.&lt;/p&gt;

&lt;p&gt;I dislike tying compilation to performance though; I'm skeptical of focusing on one goal, because compilers, imho, can improve programs along multiple dimensions.&lt;/p&gt;

&lt;p&gt;So I'm going to try to broaden this definition to account for other kinds of improvements which means I can't lean on the nice big-O related math and need a different technique.&lt;/p&gt;

&lt;p&gt;But first, let's get out of the way things that won't help us put a toolchain on the compiled/interpreted spectrum.&lt;/p&gt;

&lt;h2&gt;
  
  
  Semantics should not differ between compiler and interpreter
&lt;/h2&gt;

&lt;p&gt;When writing a compiler for a language that previously only had an interpreter available, one tries to preserve the semantics of programs.&lt;/p&gt;

&lt;p&gt;So we can't rely on obvious differences in semantics.  That said, many PLs have reflective affordances and underspecified behaviour that often will differ.  I'll show some ways to abuse introspection and debugging to test my definition.&lt;/p&gt;

&lt;h2&gt;
  
  
  Performance is more an indicator of toolchain maturity, not whether compilation happened
&lt;/h2&gt;

&lt;p&gt;In 2004, when Gmail launched, JavaScript engines were relatively immature.  Gmail relied heavily on a JavaScript compiler to reduce the network bandwidth required to load what was then the single largest JavaScript program, and to make Gmail perform acceptably.&lt;/p&gt;

&lt;p&gt;Today, un-pre-compiled JavaScript easily out-performs 2004's pre-compiled websites, because modern interpreters (albeit ones with just-in-time compilers) are much better than the JScript 5 engine used in IE6.  Google and Mozilla invested an enormous amount of engineering in their engines.&lt;/p&gt;

&lt;h2&gt;
  
  
  So what does a good compiler do?
&lt;/h2&gt;

&lt;p&gt;A well compiled program &lt;em&gt;needs less&lt;/em&gt; to do the same job.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;less time or&lt;/li&gt;
&lt;li&gt;fewer system resources or&lt;/li&gt;
&lt;li&gt;fewer instructions or&lt;/li&gt;
&lt;li&gt;a smaller runtime or&lt;/li&gt;
&lt;li&gt;less risk of leaking private information or&lt;/li&gt;
&lt;li&gt;less of something else 🤷&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;and it does that based on considering what all possible runs of the program need and removing things they don't.&lt;/p&gt;

&lt;p&gt;Maybe they don't need to perform that expensive operation inside a loop, and instead it can be done once outside.&lt;/p&gt;

&lt;p&gt;Maybe they can replace that loop with a single vectorized instruction.&lt;/p&gt;

&lt;p&gt;Maybe they don't need that function at all.  It's in a library that other programs may use but not this one.&lt;/p&gt;

&lt;p&gt;I propose that a tool-chain is compiler-y to the degree it lowers the requirements for a program to run.&lt;/p&gt;

&lt;h2&gt;
  
  
  A practical test for compilation
&lt;/h2&gt;

&lt;p&gt;How does this awfully fuzzy definition let us distinguish between a program that is running after having been compiled, and one where the interpreter is considering instructions for the first time upon reaching them?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/Capture_the_flag_%28cybersecurity%29"&gt;Capture the flag&lt;/a&gt; (CTF) contests are a long tradition in computer security:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;an exercise in which "flags" are secretly hidden in purposefully-vulnerable programs&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If we can embed flags in a program that, per the program's semantics, shouldn't be needed, and then skilled flag-capturers fail to find them, that's a strong signal that a compiler identified them as unnecessary and got to them first.&lt;/p&gt;

&lt;p&gt;Below I work through some programs in various languages doing roughly the same for each:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;I write a program that mentions a string value, &lt;code&gt;"FLAG"&lt;/code&gt; but whose semantics do not depend on it.&lt;/li&gt;
&lt;li&gt;I run the tool-chain for the program.&lt;/li&gt;
&lt;li&gt;I try to find the value "FLAG" somewhere in an intermediate representation or at runtime in the program.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;(Caveat: I'm not particularly good at capture the flag.  I was always better at writing the challenges, but I know the basics, so please bear with me)&lt;/p&gt;

&lt;h2&gt;
  
  
  Capture the flag against a C compiler
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#define PRINT_FLAG 0
&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;argc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;char&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;flag&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"FLAG"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;PRINT_FLAG&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"%s&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;flag&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;other&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"OTHER"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"%s&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;other&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can see that the level of compilation, the &lt;code&gt;-O&lt;/code&gt; flag to &lt;code&gt;gcc&lt;/code&gt; matters.&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;$ &lt;/span&gt;gcc &lt;span class="nt"&gt;-O0&lt;/span&gt; ctf.c
&lt;span class="nv"&gt;$ &lt;/span&gt;./a.out
OTHER
&lt;span class="nv"&gt;$ &lt;/span&gt;strings &lt;span class="nt"&gt;-a&lt;/span&gt; ./a.out
FLAG
OTHER
&lt;span class="nv"&gt;$ &lt;/span&gt;gcc &lt;span class="nt"&gt;-O1&lt;/span&gt; ctf.c
&lt;span class="nv"&gt;$ &lt;/span&gt;./a.out
OTHER
&lt;span class="nv"&gt;$ &lt;/span&gt;strings &lt;span class="nt"&gt;-a&lt;/span&gt; ./a.out
OTHER
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I compiled the above C program two ways and each time it had the same behaviour, but looking in the binary with &lt;a href="https://linux.die.net/man/1/strings"&gt;&lt;code&gt;strings&lt;/code&gt;&lt;/a&gt; showed that, when doing any kind of optimizations (&lt;code&gt;-O1&lt;/code&gt; or higher), the binary has the string "OTHER" which is needed, but does not have the string "FLAG" which is not.&lt;/p&gt;

&lt;p&gt;By embedding a secret, and looking at the program from the outside, we can distinguish between a run of &lt;code&gt;gcc -O0&lt;/code&gt; that intentionally does no optimizations and one which does.  (That may seem surprising.  More on that below)&lt;/p&gt;

&lt;h2&gt;
  
  
  Capture the flag against a JavaScript engine with and without pre-compilation
&lt;/h2&gt;

&lt;p&gt;We can use a debugger to get a sense of what is available.  If a program is pre-compiled, the debugger simply won't have access to flags that were removed.  For example, running the C progam above over GDB will simply skip over &lt;code&gt;char* flag  = "FLAG";&lt;/code&gt; as if it never existed.&lt;/p&gt;

&lt;p&gt;Here's our sample JS:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
  &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;createClosure&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;flag&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;FLAG&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="c1"&gt;// Technically, this function closes over flag.&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;closure&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;createClosure&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It calls a function to create a closure that closes over &lt;code&gt;var flag&lt;/code&gt; but which never uses it.  Since this is in a &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; tag, the &lt;code&gt;var closure&lt;/code&gt; is attached to the &lt;code&gt;window&lt;/code&gt; object so this whole program isn't a no-op.&lt;/p&gt;

&lt;p&gt;If I run this program through &lt;a href="https://closure-compiler.appspot.com/home#code%3D%252F%252F%2520%253D%253DClosureCompiler%253D%253D%250A%252F%252F%2520%2540compilation_level%2520SIMPLE_OPTIMIZATIONS%250A%252F%252F%2520%2540output_file_name%2520default.js%250A%252F%252F%2520%2540formatting%2520pretty_print%250A%252F%252F%2520%253D%253D%252FClosureCompiler%253D%253D%250A%250A%250Afunction%2520createClosure()%2520%257B%250A%2520%2520%2520%2520var%2520flag%2520%253D%2520%2522FLAG%2522%253B%250A%2520%2520%2520%2520%252F%252F%2520Technically%252C%2520this%2520function%2520closes%2520over%2520flag.%250A%2520%2520%2520%2520return%2520()%2520%253D%253E%2520undefined%253B%250A%257D%250A%250Avar%2520closure%2520%253D%2520createClosure()%253B%250A"&gt;ClosureCompiler&lt;/a&gt;, a JS code minifier, I get&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--1QRAnDP4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/84kgpsbz0ah8a5n52dl7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--1QRAnDP4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/84kgpsbz0ah8a5n52dl7.png" alt="Output from running the program (sans script tag) through Google's closure compiler with simple optimizations which shows that the  raw `var flag` endraw  line is removed from the output" width="880" height="270"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Note that the "compiled code" on the right-hand-side is similar but lacks comments and the line &lt;code&gt;var flag = 'FLAG'&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Note: that this is not technically a semantics preserving transformation because it affects the semantics of calling &lt;code&gt;createClosure.toString()&lt;/code&gt;; stringifying a JS function value dumps its source code.  See the &lt;a href="https://github.com/tc39/proposal-function-implementation-hiding"&gt;"hide source" directive proposal&lt;/a&gt; for more details.  This requirement does not prevent a compiling JS engine from ignoring the instruction though.&lt;/p&gt;

&lt;p&gt;If I load that same HTML uncompiled in Chrome's debugger, I can see that Chrome does not eliminate the unneeded &lt;code&gt;flag&lt;/code&gt; variable.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---6emMhvo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9kg46lgct6jrtgtzo9xh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---6emMhvo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9kg46lgct6jrtgtzo9xh.png" alt="That HTML script loaded into Chrome's builtin step debugger.  Focus is on the line  raw `var flag = 'FLAG'` endraw " width="880" height="358"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The flag variable is available to the debugger which helpfully tells me that it's executing that line.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--X7BqsJLO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/y6bh72wuyc6uoif6j6ao.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--X7BqsJLO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/y6bh72wuyc6uoif6j6ao.png" alt="The same step debugger view after control has stepped to the next line." width="880" height="364"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can see after I step to the next line, the debugger shows next to the previous line that the value "FLAG" was bound to the name &lt;em&gt;flag&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;So V8 is not compiling out things that &lt;code&gt;gcc -O1&lt;/code&gt; does.  V8 (Chrome's JS engine) does a lot of other just in time compilation, but not this particular one.  It may be that V8 does fewer optimizations, specifically when you invoke the debugger, but that is still a choice to be less compiled when being interactively debugged.  Quite possibly, V8 runs this interpreted because it is not a performance hotspot.&lt;/p&gt;

&lt;p&gt;So our definition based on needing less also works when compilation is an optional step for a toolchain.&lt;/p&gt;

&lt;h2&gt;
  
  
  Capture the flag against Python
&lt;/h2&gt;

&lt;p&gt;Is Python compiled?  CPython spits out &lt;code&gt;.pyc&lt;/code&gt; files for each &lt;code&gt;.py&lt;/code&gt; fail it loads, so it seems like this is an example of compilation at load time.&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="nn"&gt;dis&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;f&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="n"&gt;flag&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;'INITIAL_VALUE'&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;flag&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;'FLAG'&lt;/span&gt;
    &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'%s'&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;flag&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;dis&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dis&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This program has a function that assigns a value to a local variable, then does not assign the &lt;code&gt;'FLAG'&lt;/code&gt; string to that variable, before printing the value stored in that variable.&lt;/p&gt;

&lt;p&gt;The function is needed because another module could load this module and call the function so it can't be entirely eliminated.&lt;/p&gt;

&lt;p&gt;And we can use Python's internal disassembler (module &lt;code&gt;dis&lt;/code&gt;) to look at that function.&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;$ &lt;/span&gt;python3 ctf.py
  3           0 RESUME                   0

  4           2 LOAD_CONST               1 &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'INITIAL_VALUE'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
              4 STORE_FAST               0 &lt;span class="o"&gt;(&lt;/span&gt;flag&lt;span class="o"&gt;)&lt;/span&gt;

  5           6 NOP

  7           8 LOAD_GLOBAL              1 &lt;span class="o"&gt;(&lt;/span&gt;NULL + print&lt;span class="o"&gt;)&lt;/span&gt;
             20 LOAD_CONST               4 &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'%s'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
             22 LOAD_FAST                0 &lt;span class="o"&gt;(&lt;/span&gt;flag&lt;span class="o"&gt;)&lt;/span&gt;
             24 BINARY_OP                6 &lt;span class="o"&gt;(&lt;/span&gt;%&lt;span class="o"&gt;)&lt;/span&gt;
             28 PRECALL                  1
             32 CALL                     1
             42 POP_TOP
             44 LOAD_CONST               0 &lt;span class="o"&gt;(&lt;/span&gt;None&lt;span class="o"&gt;)&lt;/span&gt;
             46 RETURN_VALUE
&lt;span class="nv"&gt;$ &lt;/span&gt;python3 &lt;span class="nt"&gt;-m&lt;/span&gt; py_compile /tmp/ctf.py
&lt;span class="nv"&gt;$ &lt;/span&gt;strings /tmp/__pycache__/ctf.cpython-311.pyc
INITIAL_VALUEF
FLAGz
print&lt;span class="o"&gt;)&lt;/span&gt;
flags
ctf.py
disr
&amp;lt;module&amp;gt;r
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So I ran the program.  Notice the &lt;code&gt;6 NOP&lt;/code&gt; instruction.  That's where I would expect a &lt;code&gt;LOAD CONST ... ('FLAG')&lt;/code&gt; if it had not compiled out the second assignment.&lt;br&gt;
It looks like Python's internal compilation removes branches like &lt;code&gt;if False:&lt;/code&gt;; &lt;code&gt;python3&lt;/code&gt; wins the capture the flag.&lt;/p&gt;

&lt;p&gt;Then I asked &lt;code&gt;python3&lt;/code&gt; to generate a &lt;code&gt;.pyc&lt;/code&gt; file with &lt;code&gt;python -m py_compile&lt;/code&gt;.  The strings in that file &lt;strong&gt;do&lt;/strong&gt; contain &lt;code&gt;FLAGz&lt;/code&gt;.  &lt;a href="https://peps.python.org/pep-3147/"&gt;PEP-3147&lt;/a&gt; notes that with &lt;code&gt;.pyc&lt;/code&gt; files, "the compilation phase can be bypassed."  Perhaps it's the case that not all of the CPython compiler's transformations are reflected in the &lt;code&gt;pyc&lt;/code&gt; file.  I'm not sure whether that qualifies as a capture the flag win or not.&lt;/p&gt;
&lt;h2&gt;
  
  
  Capture the flag against Java
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Ctf&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt; &lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;flag&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"INITIAL"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;flag&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"FLAG"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;err&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;flag&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Our code here is similar to our Python example: we initialize a variable, then because of &lt;code&gt;if (false)&lt;/code&gt; we don't change it to &lt;code&gt;"FLAG"&lt;/code&gt;.  Finally we print it, so that we need the initial value but not the one we want to capture.&lt;/p&gt;

&lt;p&gt;If I compile and disassemble the &lt;code&gt;.class&lt;/code&gt; file, I see that Java wins.&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;$ &lt;/span&gt;javac Ctf.java
&lt;span class="nv"&gt;$ &lt;/span&gt;javap &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="nt"&gt;-constants&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; Ctf
Compiled from &lt;span class="s2"&gt;"Ctf.java"&lt;/span&gt;
public class Ctf &lt;span class="o"&gt;{&lt;/span&gt;
  public Ctf&lt;span class="o"&gt;()&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    Code:
       0: aload_0
       1: invokespecial &lt;span class="c"&gt;#1                  // Method java/lang/Object."&amp;lt;init&amp;gt;":()V&lt;/span&gt;
       4: &lt;span class="k"&gt;return

  &lt;/span&gt;public static void main&lt;span class="o"&gt;(&lt;/span&gt;java.lang.String...&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    Code:
       0: ldc           &lt;span class="c"&gt;#7                  // String INITIAL&lt;/span&gt;
       2: astore_1
       3: getstatic     &lt;span class="c"&gt;#9                  // Field java/lang/System.err:Ljava/io/PrintStream;&lt;/span&gt;
       6: aload_1
       7: invokevirtual &lt;span class="c"&gt;#15                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V&lt;/span&gt;
      10: &lt;span class="k"&gt;return&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;strings Ctf.class
java/lang/Object
&amp;lt;init&amp;gt;
INITIAL
java/lang/System
Ljava/io/PrintStream&lt;span class="p"&gt;;&lt;/span&gt;
java/io/PrintStream
println
&lt;span class="o"&gt;(&lt;/span&gt;Ljava/lang/String&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;V
Code
LineNumberTable
main
&lt;span class="o"&gt;([&lt;/span&gt;Ljava/lang/String&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;V
SourceFile
Ctf.java
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;.class&lt;/code&gt; file does not contain instructions to fetch (&lt;code&gt;ldc&lt;/code&gt; aka load constant) any second value from the class's constant pool, and &lt;code&gt;strings&lt;/code&gt; shows that the constant pool contains &lt;code&gt;"INITIAL"&lt;/code&gt; but not &lt;code&gt;"FLAG"&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The Java tool-chain wins the capture the flag, without even getting into its second just-in-time compilation phase.&lt;/p&gt;

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

&lt;p&gt;A compiler is a &lt;em&gt;needs reduction machine&lt;/em&gt;, a program transformation that allows a program to &lt;strong&gt;do the same with less&lt;/strong&gt;; a tool-chain is compiler-y to the degree it lowers the requirements for a program to run.&lt;/p&gt;

&lt;p&gt;This definition seems vaguer than Tratt's big-O notation based definition, but recognizes that some compilers aim to provide benefits other than runtime performance.&lt;/p&gt;

&lt;p&gt;It may seem vague but it is testable.  By understanding the goals of a compiler, we can adversarially test whether it achieves those goals.&lt;/p&gt;

&lt;p&gt;To show that, I took one example of &lt;em&gt;less&lt;/em&gt;, it doesn't need a string value that appears in the program source but which doesn't affect the program's semantics, and showed how to test whether something is or is not compiled by playing capture the flag against these toolchains:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;gcc -O0&lt;/code&gt;, C in "just generate instructions no fancy stuff" mode&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;gcc -O1&lt;/code&gt; through &lt;code&gt;-O3&lt;/code&gt;, C with optimizations&lt;/li&gt;
&lt;li&gt;JavaScript pre-compiled using a code minifier&lt;/li&gt;
&lt;li&gt;JavaScript not pre-compiled&lt;/li&gt;
&lt;li&gt;Python running in CPython3 with its load-time compilation and its cached source files&lt;/li&gt;
&lt;li&gt;Java compiled via &lt;code&gt;javac&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And I outlined a number of techniques for testing whether a tool-chain compiles according to this definition:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Using the UNIX &lt;code&gt;strings&lt;/code&gt; tool to look at tool-chain artifacts, like the &lt;code&gt;a.out&lt;/code&gt; executable built by &lt;code&gt;gcc&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Using a debugger to see if instructions that initialize an unneeded variable are executed&lt;/li&gt;
&lt;li&gt;Using disassemblers like &lt;code&gt;javap&lt;/code&gt; and Python's in-program &lt;code&gt;dis&lt;/code&gt; module to look for instructions and static value storage&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The results above largely mirror programmer's understandings of their toolchains.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Java is compiled ahead of time, just not to a platform-specific instruction set.&lt;/li&gt;
&lt;li&gt;Python compiles at module load time in a similar way.&lt;/li&gt;
&lt;li&gt;JavaScript can be pre-compiled to simpler JavaScript if you so wish.  Modern JavaScript engines do a lot of binary instruction generation internally, but it's not a tool-chain centred around compilation at the end of the day.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There are some surprises.  &lt;code&gt;gcc -O0&lt;/code&gt; fails the capture-the-flag, so according to this definition is not compiled.  This is a flaw.  In this case &lt;code&gt;gcc&lt;/code&gt; removes the need for a large runtime, so still falls into the "does the same with less" paradigm but this CTF exercise does not capture that.&lt;/p&gt;

</description>
      <category>compilers</category>
      <category>discuss</category>
    </item>
    <item>
      <title>Boolean coercion pitfalls (with examples)</title>
      <dc:creator>Mike Samuel</dc:creator>
      <pubDate>Mon, 27 Feb 2023 19:50:02 +0000</pubDate>
      <link>https://dev.to/mikesamuel/boolean-coercion-pitfalls-with-examples-505k</link>
      <guid>https://dev.to/mikesamuel/boolean-coercion-pitfalls-with-examples-505k</guid>
      <description>&lt;p&gt;It's not uncommon for programming language designers to let people write conditions where the type is not boolean, by automatically coercing non-boolean, but truthy values:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;    &lt;span class="err"&gt;┏━━━━━━━━━&lt;/span&gt; &lt;span class="n"&gt;not&lt;/span&gt; &lt;span class="n"&gt;boolean&lt;/span&gt;
    &lt;span class="err"&gt;▼&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
    &lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;        &lt;span class="err"&gt;▲&lt;/span&gt;
         &lt;span class="err"&gt;┗━━━━&lt;/span&gt; &lt;span class="n"&gt;known&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;be&lt;/span&gt; &lt;span class="n"&gt;usable&lt;/span&gt; &lt;span class="n"&gt;here&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This lets developers run &lt;code&gt;body&lt;/code&gt; only if &lt;code&gt;x&lt;/code&gt; is a kind of value that you can do things with.&lt;/p&gt;

&lt;p&gt;It's tempting, as a language designer, when you see developers writing the same kinds of test conditions over and over to want to simplify things.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="gd"&gt;-if (pointer != null) { ... }
&lt;/span&gt;&lt;span class="gi"&gt;+if (pointer) { ... }
&lt;/span&gt;&lt;span class="gd"&gt;-if (!myList.empty) { ... }
&lt;/span&gt;&lt;span class="gi"&gt;+if (myList) { ... }
&lt;/span&gt;&lt;span class="gd"&gt;-if (result.isSuccess) { ... }
&lt;/span&gt;&lt;span class="gi"&gt;+if (result) { ... }
&lt;/span&gt;&lt;span class="gd"&gt;-if (inputText != "") { ... }
&lt;/span&gt;&lt;span class="gi"&gt;+if (inputText) { ... }
&lt;/span&gt;&lt;span class="gd"&gt;-if (count != 0) { ... }
&lt;/span&gt;&lt;span class="gi"&gt;+if (count) { ... }
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;All else being equal, a language that encourages shorter code is better.&lt;/p&gt;

&lt;p&gt;But, the &lt;a href="https://en.wikipedia.org/wiki/Principle_of_least_astonishment" rel="noopener noreferrer"&gt;principle of least surprise&lt;/a&gt; says we ought craft semantics that have a clear meaning, even when developers are fuzzy on the precise semantics of a phrase.&lt;/p&gt;

&lt;p&gt;Below are examples of different ways that silent conversion, specifically of &lt;code&gt;if&lt;/code&gt; and loop condition results to boolean values, can violate that principle.&lt;/p&gt;




&lt;p&gt;Special "nothing here" values like &lt;code&gt;NULL&lt;/code&gt; are exactly the kind of things we might want to filter out.  So maybe these two should be equivalent.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// For any pointer, p&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;         &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// In C++, for example, NULL is falsey, &lt;/span&gt;
&lt;span class="c1"&gt;// and all other pointer values are truthy.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But it's easy to confuse containers with their content.  Developers may be surprised when the container and content coerce to different truth values.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// What if we're pointing to a boolean.&lt;/span&gt;
&lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kt"&gt;bool&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;
    &lt;span class="s"&gt;"a non-null pointer to false is truthy&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In languages that don't have &lt;em&gt;null&lt;/em&gt; pointers, &lt;em&gt;Option&lt;/em&gt; and &lt;em&gt;Result&lt;/em&gt; types often serve a similar function: a box of zero or one value.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ocaml"&gt;&lt;code&gt;&lt;span class="c"&gt;(* This is not actually valid OCaml
 * since OCaml doesn't do coercion. 
 *
 * But imagine Some _ is truthy and
 *             None   is falsey
 *)&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Some&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;false&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt;
  &lt;span class="o"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note that Swift allows its optional types in a condition but only via a &lt;em&gt;binding condition&lt;/em&gt; which makes it clear that the container is what is being checked.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Swift&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Bool&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;

&lt;span class="c1"&gt;// When x is not `nil`, unpacks it into b&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"b is &lt;/span&gt;&lt;span class="se"&gt;\(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="se"&gt;)&lt;/span&gt;&lt;span class="s"&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;// if x { ... }   // Does not type-check&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;Consider programs that work with data languages like JSON and YAML that use &lt;a href="https://hitchdev.com/strictyaml/why/syntax-typing-bad/" rel="noopener noreferrer"&gt;syntax typing&lt;/a&gt;; the textual value determines its type.&lt;br&gt;
For example, YAML, a common configuration language, treats many un-quoted strings as &lt;a href="https://yaml.org/type/bool.html" rel="noopener noreferrer"&gt;booleans&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;

&lt;pre class="highlight plaintext"&gt;&lt;code&gt;y|Y|yes|Yes|YES|n|N|no|No|NO
|true|True|TRUE|false|False|FALSE
|on|On|ON|off|Off|OFF
&lt;/code&gt;&lt;/pre&gt;

&lt;/blockquote&gt;

&lt;p&gt;Developers who work with these languages are used to thinking of words as having truth values.&lt;/p&gt;

&lt;p&gt;There's potential for confusion when a programming language assigns different boolean valence to a string value than the language of the string's content.&lt;/p&gt;

&lt;p&gt;This happens in many programming languages: &lt;code&gt;if (someContainer)&lt;/code&gt; executes the body if &lt;code&gt;someContainer&lt;/code&gt; is not empty.&lt;/p&gt;

&lt;p&gt;For example, &lt;a href="https://docs.python.org/3/library/stdtypes.html#truth-value-testing" rel="noopener noreferrer"&gt;Python&lt;/a&gt; says:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Any object can be tested for truth value, for use in an &lt;code&gt;if&lt;/code&gt; or &lt;code&gt;while&lt;/code&gt; condition, or …&lt;/p&gt;

&lt;p&gt;By default, an object is considered true unless … Here are most of the built-in objects considered false:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;…&lt;/li&gt;
&lt;li&gt;empty sequences and collections: &lt;code&gt;''&lt;/code&gt;, &lt;code&gt;()&lt;/code&gt;, &lt;code&gt;[]&lt;/code&gt;, &lt;code&gt;{}&lt;/code&gt;, &lt;code&gt;set()&lt;/code&gt;, &lt;code&gt;range(0)&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;So Python treats the string &lt;code&gt;''&lt;/code&gt; as falsey but others are truthy, including strings like &lt;code&gt;'false'&lt;/code&gt; and &lt;code&gt;'no'&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Here's some JavaScript, which has similar string truthiness.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Unpack a value in a data language&lt;/span&gt;
&lt;span class="c1"&gt;// that the program does not control.&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;request&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="s2"&gt;`
  {
    "deleteAccount": "no",
    "userConfirmationCheckbox": "off"
  }
  `&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// But we forgot to convert those fields&lt;/span&gt;
&lt;span class="c1"&gt;// to booleans using the request language's&lt;/span&gt;
&lt;span class="c1"&gt;// conventions.&lt;/span&gt;
&lt;span class="c1"&gt;// So JavaScript's conventions prevail.&lt;/span&gt;
&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;deleteAccount&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
    &lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;userConfirmationCheckbox&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;performIrreversibleDelete&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A programming language should support developers in checking assumptions about values that come from outside the program.  Assigning arbitrary truthiness to string values makes it harder to find and check these assumptions.&lt;/p&gt;




&lt;p&gt;It's easy to confuse a zero-argument function with its result.&lt;br&gt;
When first-class function values have a boolean sense, this can lead to confusion.&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="c1"&gt;# Python
&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Animal&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;is_goldfish_compatible&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&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;True&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Goldfish&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Animal&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;pass&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Dog&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Animal&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;pass&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Cat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Animal&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c1"&gt;# overrides a predicate from SuperType
&lt;/span&gt;    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;is_goldfish_compatible&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&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;False&lt;/span&gt;

&lt;span class="n"&gt;goldfish&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Goldfish&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;cat&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Cat&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;dog&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Dog&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;play_together&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;%r plays with %r&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;animal&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;dog&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cat&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;animal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;is_goldfish_compatible&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="c1"&gt;#                           ▲
&lt;/span&gt;        &lt;span class="c1"&gt;# Pay attention here ━━━━━━━┛
&lt;/span&gt;        &lt;span class="nf"&gt;play_together&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;animal&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;goldfish&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It's easy to confuse the method call:&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="n"&gt;animal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;is_goldfish_compatible&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;with a read of a &lt;a href="https://docs.python.org/3/library/stdtypes.html#methods" rel="noopener noreferrer"&gt;&lt;em&gt;bound&lt;/em&gt; method&lt;/a&gt;:&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="n"&gt;animal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;is_goldfish_compatible&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Especially since other classes define similarly named &lt;code&gt;is_&lt;/code&gt;&lt;em&gt;*&lt;/em&gt; &lt;a href="https://docs.python.org/3/library/ipaddress.html#ipaddress.IPv4Address.is_multicast" rel="noopener noreferrer"&gt;boolean attributes&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/Unit_type" rel="noopener noreferrer"&gt;&lt;code&gt;Unit&lt;/code&gt; and &lt;code&gt;void&lt;/code&gt;&lt;/a&gt; are common names for special values produced by functions that are meant to be called for their side effect.&lt;/p&gt;

&lt;p&gt;They make for clearer code.  If a function's author doesn't intend to provide a value to the caller, they can simply not &lt;code&gt;return&lt;/code&gt; anything.&lt;/p&gt;

&lt;p&gt;These special values should probably not be silently treated as having a boolean valence, but in some languages they are.&lt;/p&gt;

&lt;p&gt;This JavaScript is fine.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// A lambda that returns true&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;shouldDoTheVeryImportantThing&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kc"&gt;true&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="nf"&gt;shouldDoTheVeryImportantThing&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;doIt&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That lambda returns &lt;code&gt;true&lt;/code&gt; when called, but maybe I'm debugging the program, so I add some logging.  I need a block to put a logging statement in, so I wrap it in &lt;code&gt;{...}&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;shouldDoTheVeryImportantThing&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Called should...&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kc"&gt;true&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="nf"&gt;shouldDoTheVeryImportantThing&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;doIt&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When I added a block around the lambda body, I forgot to add a &lt;code&gt;return&lt;/code&gt; before the &lt;code&gt;true&lt;/code&gt;. Now it returns the special &lt;em&gt;void&lt;/em&gt;-like value &lt;code&gt;undefined&lt;/code&gt;, which coerces to &lt;code&gt;false&lt;/code&gt; in a condition.&lt;/p&gt;

&lt;p&gt;The second version logs, but silently fails to call &lt;code&gt;doIt()&lt;/code&gt;.&lt;/p&gt;




&lt;p&gt;Automatic coercion results from a genuine desire by language designers to help developers craft more succinct and readable programs.&lt;/p&gt;

&lt;p&gt;But when the semantics are not carefully tailored, this can lead to confusion.&lt;/p&gt;

&lt;p&gt;Be especially careful around:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;generic boxes and collections-of-one that might wrap booleans, including pointer types, &lt;em&gt;Option&lt;/em&gt; and &lt;em&gt;Result&lt;/em&gt; types,&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://wiki.c2.com/?StringlyTyped" rel="noopener noreferrer"&gt;catch-all types&lt;/a&gt; like &lt;code&gt;string&lt;/code&gt; and &lt;code&gt;byte[]&lt;/code&gt; that may layer semantics in another language which is at odds with the coerced semantics,&lt;/li&gt;
&lt;li&gt;producers of values like first-class function values, &lt;a href="https://en.wikipedia.org/wiki/Thunk" rel="noopener noreferrer"&gt;thunks&lt;/a&gt;, and &lt;a href="https://en.wikipedia.org/wiki/Futures_and_promises" rel="noopener noreferrer"&gt;promises&lt;/a&gt; which might have a different boolean valence from the value they produce, and&lt;/li&gt;
&lt;li&gt;special placeholder values like &lt;code&gt;void&lt;/code&gt; or &lt;code&gt;undefined&lt;/code&gt; which, when coerced to booleans silently, mask a failure to account for a missing value.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Before designing coercion semantics, maybe ask yourself, could a proposed coercion semantics mask missing steps that the author should have performed?&lt;/p&gt;

&lt;p&gt;Might a different mechanism (like Swift's binding condition above) suffice?&lt;/p&gt;

&lt;p&gt;Maybe you think that the rules you've chosen are obvious and that developers will have them clearly in mind when reading &amp;amp; writing conditions.  "&lt;a href="https://discourse.julialang.org/t/on-the-arbitrariness-of-truth-iness/81381" rel="noopener noreferrer"&gt;On the arbitrariness of truthi(ness)&lt;/a&gt;" explains how different PL designers, who probably each thought that their notions of truthiness were clear, came to very different decisions.&lt;/p&gt;

&lt;p&gt;Thanks for reading and happy language designing.&lt;/p&gt;

</description>
      <category>languages</category>
      <category>programming</category>
      <category>coercion</category>
      <category>boolean</category>
    </item>
    <item>
      <title>Hygiene is not just for macros</title>
      <dc:creator>Mike Samuel</dc:creator>
      <pubDate>Thu, 09 Feb 2023 19:13:11 +0000</pubDate>
      <link>https://dev.to/mikesamuel/hygiene-is-not-just-for-macros-1409</link>
      <guid>https://dev.to/mikesamuel/hygiene-is-not-just-for-macros-1409</guid>
      <description>&lt;p&gt;JavaScript has no macro system but has some surprising variable scoping problems.  Why?&lt;br&gt;
What is macro hygiene and how is it a lens through which we can understand these problems and how to avoid them in future language designs?&lt;/p&gt;



&lt;p&gt;Quick, what does this JavaScript do?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;thrown&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="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;assigned in block&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="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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;In catch:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;);&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Afterwards:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We &lt;code&gt;throw&lt;/code&gt; a string, which is caught and stored as &lt;code&gt;e&lt;/code&gt; in &lt;code&gt;catch (e)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Then, there's an &lt;code&gt;if&lt;/code&gt; that declares another &lt;code&gt;var e&lt;/code&gt; and initializes it to &lt;code&gt;'assigned in block'&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;So what gets logged?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;In catch: assigned in block
Afterwards: undefined
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In JavaScript, &lt;code&gt;var&lt;/code&gt; declarations are &lt;a href="https://developer.mozilla.org/en-US/docs/Glossary/Hoisting"&gt;&lt;em&gt;hoisted&lt;/em&gt;&lt;/a&gt;.  Every &lt;code&gt;var&lt;/code&gt; declaration is effectively pulled to the top of the containing &lt;code&gt;function&lt;/code&gt; or module.&lt;/p&gt;

&lt;p&gt;So the above is equivalent to&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// ◀━━━━━━━━━━━━━━━━━━━━━━━━━━┓&lt;/span&gt;
&lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;                        &lt;span class="c1"&gt;//      ┃&lt;/span&gt;
  &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;thrown&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;            &lt;span class="c1"&gt;//      ┃&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;                &lt;span class="c1"&gt;//      ┃&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;                &lt;span class="c1"&gt;//      ┃&lt;/span&gt;
    &lt;span class="nx"&gt;e&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;assigned in block&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// var ━┛&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;In catch:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;);&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Afterwards:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;var e&lt;/code&gt; is &lt;em&gt;hoisted&lt;/em&gt; to the top.&lt;/p&gt;

&lt;p&gt;Makes sense.  &lt;code&gt;var&lt;/code&gt; declarations are not &lt;em&gt;block scoped&lt;/em&gt;; it doesn't only affect the &lt;code&gt;{&lt;/code&gt;…&lt;code&gt;}&lt;/code&gt; block that it appears in.  (In JavaScript, if you want block scoping you use &lt;code&gt;let&lt;/code&gt; or &lt;code&gt;const&lt;/code&gt; declarations instead)&lt;/p&gt;

&lt;p&gt;But notice also that the &lt;code&gt;e = 'assigned in block'&lt;/code&gt; was left behind.  Moving the initializer would cause problems; what if it was a complex expression, and in a less predictable &lt;code&gt;if&lt;/code&gt; statement?  We might execute code out of order or that we shouldn't have executed at all.&lt;/p&gt;

&lt;p&gt;But because &lt;code&gt;catch (e)&lt;/code&gt; introduces &lt;strong&gt;another&lt;/strong&gt; variable &lt;code&gt;e&lt;/code&gt;, the &lt;code&gt;e = 'assigned in block'&lt;/code&gt; assigns a different variable than was intended.&lt;br&gt;
Then when &lt;code&gt;console.log('In catch', e)&lt;/code&gt; happens, instead of logging &lt;code&gt;'thrown'&lt;/code&gt;, it logs the &lt;code&gt;'assigned in block'&lt;/code&gt; value.&lt;/p&gt;

&lt;p&gt;Finally, since the &lt;code&gt;var e&lt;/code&gt; was never actually assigned, the last line logs &lt;code&gt;Afterwards: undefined&lt;/code&gt;. &lt;/p&gt;



&lt;p&gt;Why did this happen?&lt;br&gt;
Could it have been avoided?&lt;/p&gt;

&lt;p&gt;The above program is not a good program, but it's actual meaning is likely to surprise even people who have made an effort to learn JavaScript's rules.&lt;/p&gt;

&lt;p&gt;The problem here is that the JavaScript language treats names as text.  This problem shows up often in languages with macro systems, ways of generating parts of the program by running code while a program is compiling or loading.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/Hygienic_macro"&gt;The &lt;em&gt;Hygienic macro&lt;/em&gt; wikipedia page&lt;/a&gt; notes (emphasis added):&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Hygienic macros are macros whose expansion is guaranteed not to cause the &lt;strong&gt;accidental capture of identifiers&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;What happened above seems very similar.  The identifier &lt;code&gt;e&lt;/code&gt; in &lt;code&gt;e = 'assigned in block'&lt;/code&gt; was &lt;strong&gt;accidentally captured&lt;/strong&gt; by the declaration in &lt;code&gt;catch (e)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;A typical way of dealing with this in languages with macros is to have a &lt;em&gt;name resolution&lt;/em&gt; step where textual identifiers are matched up with declarations to remove ambiguity.  After that happens, it's safe to move uses of names around and introduce new declarations; you won't accidentally break the relationship between declarations and uses that are apparent in the source code.&lt;/p&gt;

&lt;p&gt;For our code above, that renaming stage might add serial numbers to variable declarations.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;thrown&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="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e_0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;e_1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;assigned in block&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="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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;In catch:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;);&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Afterwards:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we've replaced the different textual names like &lt;code&gt;e&lt;/code&gt; with &lt;em&gt;abstract names&lt;/em&gt; like &lt;code&gt;e_0&lt;/code&gt; to make them unambiguous.&lt;/p&gt;

&lt;p&gt;Then we can hoist declarations to the appropriate place, taking care that, when we split &lt;code&gt;var e_1 = ...&lt;/code&gt;, to use &lt;code&gt;e_1&lt;/code&gt; in both the original position and the hoisted position.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;e_1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// ◀━━━━━━━━━━━━━━━━━━━━━━━━━━┓&lt;/span&gt;
&lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;                          &lt;span class="c1"&gt;//      ┃&lt;/span&gt;
  &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;thrown&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;              &lt;span class="c1"&gt;//      ┃&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e_0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;                &lt;span class="c1"&gt;//      ┃&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;                  &lt;span class="c1"&gt;//      ┃&lt;/span&gt;
    &lt;span class="nx"&gt;e_1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;assigned in block&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// var ━┛&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;In catch:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;);&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Afterwards:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now that our declarations are unambiguous, and in their final places, we can resolve references by matching the remaining textual names with declarations.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;e_1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// ◀━━━━━━━━━━━━━━━━━━━━━━━━━━━┓&lt;/span&gt;
&lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;                            &lt;span class="c1"&gt;//     ┃&lt;/span&gt;
  &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;thrown&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;                &lt;span class="c1"&gt;//     ┃&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e_0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="c1"&gt;// ◀━━━━━━━━━━━━━━━━━━┓ ┃&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;                    &lt;span class="c1"&gt;//   ┃ ┃&lt;/span&gt;
    &lt;span class="nx"&gt;e_1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;assigned in block&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;   &lt;span class="c1"&gt;//   ┃ ┃&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;                              &lt;span class="c1"&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;In catch:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;e_0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// ◀━┛ ┃&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;                                &lt;span class="c1"&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Afterwards:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;e_1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// ◀━━━┛&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This modified program outputs the below, which is probably closer what the original author&lt;sup&gt;†&lt;/sup&gt; meant and what a code reviewer would expect it to do.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;In catch: thrown
Afterwards: assigned in block
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;† - &lt;small&gt;if the author wasn't intentionally writing silly programs to make a point.&lt;/small&gt;&lt;/p&gt;




&lt;p&gt;So why wasn't JavaScript designed that way?&lt;/p&gt;

&lt;p&gt;Well, JavaScript was famously &lt;a href="https://thenewstack.io/brendan-eich-on-creating-javascript-in-10-days-and-what-hed-do-differently-today/"&gt;created in 10 days&lt;/a&gt; so there was not much time to think through &lt;code&gt;var&lt;/code&gt; hoisting corner-cases.&lt;/p&gt;

&lt;p&gt;But also, the language re-used certain abstractions.  JavaScript &lt;em&gt;Objects&lt;/em&gt; are bags of named properties that inherit names from a prototype.  &lt;em&gt;Objects&lt;/em&gt; are re-used to represent &lt;a href="https://262.ecma-international.org/13.0/#sec-environment-records"&gt;&lt;em&gt;environment records&lt;/em&gt;&lt;/a&gt;, bags of named variables that inherit names from an outer record.&lt;/p&gt;




&lt;p&gt;But is there anything about that re-use that prevents the kind of hygiene that came in handy above?&lt;/p&gt;

&lt;p&gt;Let's consider a case where JavaScript blurs the distinction between environment records and Objects.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;property of o&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="kd"&gt;with&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;o&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;initial value for var x&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="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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;o.x after with:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;o&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Some readers may not be familiar with JavaScript's &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/with"&gt;deprecated &lt;code&gt;with&lt;/code&gt; statement&lt;/a&gt;.  It brings an object's properties into scope, so that instead of saying &lt;code&gt;o.x&lt;/code&gt;, within &lt;code&gt;with (o)&lt;/code&gt; you can just say &lt;code&gt;x&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Here, we create an object with a property named &lt;code&gt;x&lt;/code&gt; and we use &lt;code&gt;with&lt;/code&gt; to bring its properties into scope.  Inside that scope, we have a &lt;code&gt;var&lt;/code&gt; declaration of the same textual name.&lt;/p&gt;

&lt;p&gt;So what happens?  If you're using JS engine that supports &lt;code&gt;with&lt;/code&gt; (it runs in non-strict mode), then you get:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;o.x after with: initial value for var x
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To see why this happens, consider that program with the &lt;code&gt;var x&lt;/code&gt; hoisted.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// ◀━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;property of o&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;  &lt;span class="c1"&gt;//      ┃&lt;/span&gt;
&lt;span class="kd"&gt;with&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;o&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;                       &lt;span class="c1"&gt;//      ┃&lt;/span&gt;
  &lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;initial value for var x&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// var ━┛&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;o.x after when:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;o&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, it's clear that &lt;code&gt;x = ...&lt;/code&gt; assigns to &lt;code&gt;o.x&lt;/code&gt; because of the &lt;code&gt;with (o)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;So this is another identifier capture problem; the &lt;code&gt;with (o)&lt;/code&gt; captured the identifier &lt;code&gt;x&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Could we fix this with our resolution phase?&lt;/p&gt;

&lt;p&gt;It's definitely complicated by &lt;code&gt;with&lt;/code&gt;.  &lt;code&gt;with&lt;/code&gt; is a dynamic construct.  We don't know which names &lt;code&gt;with&lt;/code&gt; brings into scope until we know which properties &lt;code&gt;o&lt;/code&gt; has which we might not know until we run the program.&lt;/p&gt;

&lt;p&gt;Consider a slightly more involved use of &lt;code&gt;with&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="cm"&gt;/* initially empty object */&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;global   x&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;global   y&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;with&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;o&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Repeatedly log x and y, add a property to o.&lt;/span&gt;
  &lt;span class="c1"&gt;// Some of these property names are the same as the&lt;/span&gt;
  &lt;span class="c1"&gt;// variables defined outside.&lt;/span&gt;
  &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;propertyName&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;x&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;y&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;z&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="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="s2"&gt;`x=&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;, y=&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;, o=&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;o&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;o&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;propertyName&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`property &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;propertyName&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That program outputs the below.  Note that references to &lt;code&gt;${x}&lt;/code&gt; and &lt;code&gt;${y}&lt;/code&gt; depend on which properties we've added to &lt;code&gt;o&lt;/code&gt;; how they resolve changes from one iteration of the loop to the next.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;x=global   x, y=global   y, o={}
x=property x, y=global   y, o={"x":"property x"}
x=property x, y=property y, o={"x":"property x","y":"property y"}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Could JavaScript have been created with hygienic &lt;code&gt;var&lt;/code&gt; and the &lt;code&gt;with&lt;/code&gt; statement?&lt;/p&gt;

&lt;p&gt;It turns out, yes.&lt;/p&gt;

&lt;p&gt;Any time a &lt;a href="https://wiki.c2.com/?FreeVariable"&gt;&lt;em&gt;free&lt;/em&gt;&lt;/a&gt; name appears in a &lt;code&gt;with&lt;/code&gt;, you have to rewrite it to either lookup from the object or resolve.&lt;/p&gt;

&lt;p&gt;So the program above is equivalent to the one below.  But the program below has unambiguous names, and still exhibits dynamic🤔 scoping:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;o_0&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="cm"&gt;/* initially empty object */&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;x_1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;global   x&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;y_2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;global   y&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;// with erased to a block&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;withed_object_3&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;o_0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;readName_4&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;propertyName_5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;readFree_6&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;propertyName_5&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nx"&gt;withed_object_3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;withed_object_3&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;propertyName_5&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;readFree_6&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;propertyName_4&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;x&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;y&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;z&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="nx"&gt;readName_4&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;console&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;globalThis&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="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="s2"&gt;`x=&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;
        &lt;span class="nx"&gt;readName_4&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;x&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;x_1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;, y=&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;
        &lt;span class="nx"&gt;readName_4&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;y&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;y_2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;, o=&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;
        &lt;span class="nx"&gt;readName_4&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;JSON&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;globalThis&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
          &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;readName_4&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;o&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;o_0&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;readName_4&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;o&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;o_0&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="nx"&gt;propertyName_4&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
      &lt;span class="s2"&gt;`property &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;propertyName_4&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This doesn't look pretty, but that's because we've moved &lt;code&gt;with&lt;/code&gt; machinery from the JavaScript engine into the program via program rewriting.  Lots of compilers and language runtimes do things like this; some short language constructs are expressed internally in terms of more verbose ones.&lt;/p&gt;

&lt;p&gt;The important thing is that we've allowed even a program that makes use of very dynamic features to run in a hygienic manner.&lt;/p&gt;

&lt;p&gt;We could have had consistently intuitive scoping in JavaScript if only we'd had a bit more time.&lt;/p&gt;

&lt;p&gt;This matters because every JavaScript tool, from Babel to VSCode, needs to deal with these corner cases, or unintentionally change the meanings of programs, and because the JavaScript &lt;a href="https://tc39.es/"&gt;language designers&lt;/a&gt; have to think through these corner cases, and may have to reject otherwise excellent language changes that are affected by these.&lt;/p&gt;

&lt;p&gt;Let's not make the same mistake in the next language.&lt;/p&gt;

</description>
      <category>languages</category>
      <category>computerscience</category>
      <category>javascript</category>
      <category>algorithms</category>
    </item>
  </channel>
</rss>
