<?xml version='1.0' encoding='utf-8' ?>

<rss version='2.0' xmlns:lj='http://www.livejournal.org/rss/lj/1.0/' xmlns:atom10='http://www.w3.org/2005/Atom'>
<channel>
  <title>simont</title>
  <link>https://simont.dreamwidth.org/</link>
  <description>simont - Dreamwidth Studios</description>
  <lastBuildDate>Fri, 23 Jun 2023 07:59:17 GMT</lastBuildDate>
  <generator>LiveJournal / Dreamwidth Studios</generator>
  <lj:journal>simont</lj:journal>
  <lj:journaltype>personal</lj:journaltype>
  <image>
    <url>https://v2.dreamwidth.org/10630417/707124</url>
    <title>simont</title>
    <link>https://simont.dreamwidth.org/</link>
    <width>89</width>
    <height>100</height>
  </image>

<item>
  <guid isPermaLink='true'>https://simont.dreamwidth.org/245672.html</guid>
  <pubDate>Fri, 23 Jun 2023 07:59:17 GMT</pubDate>
  <title>I wrote another article, and made an RSS feed</title>
  <link>https://simont.dreamwidth.org/245672.html</link>
  <description>&lt;p&gt;For those who were interested in my previous article about aperiodic tiling generation, I&apos;ve written a sequel, extending the same random generation algorithm to the even newer &apos;Spectre&apos; tiling discovered by the same people who found the hat tiling in March.&lt;/p&gt;&lt;p&gt;Here it is: &lt;a href=&quot;https://www.chiark.greenend.org.uk/~sgtatham/quasiblog/aperiodic-spectre/&quot;&gt;https://www.chiark.greenend.org.uk/~sgtatham/quasiblog/aperiodic-spectre/&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Also, it seems silly for me to make posts here announcing every article of this length I write &amp;#8211;&lt;wbr&gt; especially since I have another in progress already. So I&apos;ve finally got round to setting up an RSS feed for the area of my website where I publish them. RSS-&lt;wbr&gt;oriented people should be able to add this to their aggregator of choice: &lt;a href=&quot;https://www.chiark.greenend.org.uk/~sgtatham/quasiblog/feed.xml&quot;&gt;https://www.chiark.greenend.org.uk/~sgtatham/quasiblog/feed.xml&lt;/a&gt;&lt;/p&gt;&lt;p&gt;And for those reading on Dreamwidth, &lt;span style=&apos;white-space: nowrap;&apos;&gt;&lt;a href=&apos;https://simont-quasiblog-feed.dreamwidth.org/profile&apos;&gt;&lt;img src=&apos;https://www.dreamwidth.org/img/silk/identity/feed.png&apos; alt=&apos;[syndicated profile] &apos; width=&apos;16&apos; height=&apos;16&apos; style=&apos;vertical-align: text-bottom; border: 0; padding-right: 1px;&apos; /&gt;&lt;/a&gt;&lt;a href=&apos;https://simont-quasiblog-feed.dreamwidth.org/&apos;&gt;&lt;b&gt;simont_quasiblog_feed&lt;/b&gt;&lt;/a&gt;&lt;/span&gt;.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;https://www.dreamwidth.org/tools/commentcount?user=simont&amp;ditemid=245672&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>https://simont.dreamwidth.org/245672.html</comments>
  <lj:security>public</lj:security>
  <lj:reply-count>2</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>https://simont.dreamwidth.org/245425.html</guid>
  <pubDate>Mon, 10 Apr 2023 13:44:18 GMT</pubDate>
  <title>I wrote an article about aperiodic tiling generation</title>
  <link>https://simont.dreamwidth.org/245425.html</link>
  <description>&lt;p&gt;A few weeks ago, when I heard about the shiny new &lt;a href=&quot;https://cs.uwaterloo.ca/~csk/hat/&quot;&gt;aperiodic monotile&lt;/a&gt; that had been discovered, I immediately had to add it to the collection of grids that you can play &lt;a href=&quot;https://www.chiark.greenend.org.uk/~sgtatham/puzzles/js/loopy.html&quot;&gt;Loopy&lt;/a&gt; on, in &lt;a href=&quot;https://www.chiark.greenend.org.uk/~sgtatham/puzzles/&quot;&gt;my puzzle collection&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;This went fine, except for the fact that I got most of the way through implementing one algorithm for generating pieces of the tiling, and then threw it away and started again because I&apos;d had a much better idea.&lt;/p&gt;&lt;p&gt;In fact, there are so many things I like about the algorithm I ended up with that I&apos;ve decided it deserves a proper public writeup. So I&apos;ve spent the Easter weekend hard at work on producing one. I present: &lt;a href=&quot;https://www.chiark.greenend.org.uk/~sgtatham/quasiblog/aperiodic-tilings/&quot;&gt;https://www.chiark.greenend.org.uk/~sgtatham/quasiblog/aperiodic-tilings/&lt;/a&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;https://www.dreamwidth.org/tools/commentcount?user=simont&amp;ditemid=245425&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>https://simont.dreamwidth.org/245425.html</comments>
  <lj:security>public</lj:security>
  <lj:reply-count>5</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>https://simont.dreamwidth.org/245104.html</guid>
  <pubDate>Tue, 13 Sep 2022 06:19:39 GMT</pubDate>
  <title>Imaginary bing!</title>
  <link>https://simont.dreamwidth.org/245104.html</link>
  <description>&lt;p&gt;I was jolted awake by the first &amp;#8216;bing!&amp;#8217; of my alarm clock.&lt;/p&gt;&lt;p&gt;But wait &amp;#8211;&lt;wbr&gt; I&apos;m on holiday this week, so my alarm clock ought not to be turned on!&lt;/p&gt;&lt;p&gt;And it&apos;s not. I&apos;d managed to &lt;em&gt;dream&lt;/em&gt; the sound. And once the first dream-&lt;wbr&gt;bing had woken me up, the second bing never came, because by that time I was awake enough to realise the alarm clock wasn&apos;t ringing after all.&lt;/p&gt;&lt;p&gt;All right, that&apos;s just one of those hilarious japes dreams play on you. But the impressive part was that the dream bing occurred within 2 minutes of my actual alarm time!&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;https://www.dreamwidth.org/tools/commentcount?user=simont&amp;ditemid=245104&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>https://simont.dreamwidth.org/245104.html</comments>
  <lj:security>public</lj:security>
  <lj:reply-count>2</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>https://simont.dreamwidth.org/244922.html</guid>
  <pubDate>Sun, 05 Sep 2021 10:20:24 GMT</pubDate>
  <title>Silliest housework accident ever</title>
  <link>https://simont.dreamwidth.org/244922.html</link>
  <description>&lt;p&gt;I was cleaning my bathroom just now with a bottle of spray cleaner. I put the cleaner down for a moment and bent down to scrub a surface. I heard a momentary clatter, looked up again &amp;#8211;&lt;wbr&gt; and the cleaner bottle was nowhere to be seen. At all.&lt;/p&gt;&lt;p&gt;After some searching, and some headscratching, I recovered it from &lt;em&gt;the neighbour&apos;s back garden&lt;/em&gt;, by knocking on their door and asking nicely if they could check whether it was there.&lt;/p&gt;&lt;p&gt;I had put the bottle down on the bathroom window sill, which is wide enough to use as a shelf for storing all kinds of stuff. The window was open. The bottle was nearly empty, hence light enough that a mild gust of wind could &lt;em&gt;just conceivably&lt;/em&gt; have knocked it out of the window. In nearly 14 years of living here, that&apos;s never happened before, so it seemed pretty unlikely, especially since no such gust of wind had been perceptible to me; but by the Holmesian principle of elimination (it most certainly was not anywhere &lt;em&gt;in&lt;/em&gt; the bathroom any more), I concluded that, &lt;em&gt;no matter how improbable&lt;/em&gt;, that surely had to be the truth.&lt;/p&gt;&lt;p&gt;But just below the bathroom window is a sloping conservatory roof. After ruling out it having come to rest &lt;em&gt;on&lt;/em&gt; that roof, and also checking if it had slid down the roof slope and fallen just off the edge into an awkward hard-&lt;wbr&gt;to-&lt;wbr&gt;reach part of &lt;em&gt;my&lt;/em&gt; garden, the Holmes principle again (with an even stronger &amp;#8216;no matter how improbable&amp;#8217; clause) said that it must have &lt;em&gt;bounced&lt;/em&gt; on my conservatory roof, and somehow achieved enough boing to get all the way over the fence into the neighbour&apos;s garden.&lt;/p&gt;&lt;p&gt;And it had! Good job too &amp;#8211;&lt;wbr&gt; if I&apos;d gone to the neighbour with that question and it &lt;em&gt;hadn&apos;t&lt;/em&gt; been there, I&apos;d have sounded even sillier than I did.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;https://www.dreamwidth.org/tools/commentcount?user=simont&amp;ditemid=244922&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>https://simont.dreamwidth.org/244922.html</comments>
  <lj:security>public</lj:security>
  <lj:reply-count>7</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>https://simont.dreamwidth.org/244574.html</guid>
  <pubDate>Mon, 08 Feb 2021 15:08:46 GMT</pubDate>
  <title>Earworm of the day</title>
  <link>https://simont.dreamwidth.org/244574.html</link>
  <description>&lt;p&gt;I don&apos;t even know &lt;em&gt;Hamilton&lt;/em&gt; that well, but even I am capable of getting a sudden earworm when the colleague presenting part of an all-&lt;wbr&gt;afternoon meeting finishes up with &amp;#8216;I have massively overrun my slot.&amp;#8217;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;https://www.dreamwidth.org/tools/commentcount?user=simont&amp;ditemid=244574&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>https://simont.dreamwidth.org/244574.html</comments>
  <lj:security>public</lj:security>
  <lj:reply-count>4</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>https://simont.dreamwidth.org/244258.html</guid>
  <pubDate>Fri, 22 Jan 2021 09:21:50 GMT</pubDate>
  <title>Nonsense and nonsensibility</title>
  <link>https://simont.dreamwidth.org/244258.html</link>
  <description>&lt;p&gt;I saw a software licence agreement recently in which a subheading read &amp;#8216;Term and Termination&amp;#8217;, and my first thought was that I&apos;d had no idea Jane Austen had once worked as a corporate lawyer.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;https://www.dreamwidth.org/tools/commentcount?user=simont&amp;ditemid=244258&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>https://simont.dreamwidth.org/244258.html</comments>
  <lj:security>public</lj:security>
  <lj:reply-count>1</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>https://simont.dreamwidth.org/244089.html</guid>
  <pubDate>Mon, 23 Nov 2020 09:29:16 GMT</pubDate>
  <title>Dewy-eyed</title>
  <link>https://simont.dreamwidth.org/244089.html</link>
  <description>&lt;p&gt;It was chilly this morning. Probably the coldest it&apos;s been since First Lockdown kicked off in March. So I went out for my morning walk with full cold weather gear: big coat, fur hat, gloves.&lt;/p&gt;&lt;p&gt;Normally, in those clothes, I just have to put up with my actual face still feeling chilly, and rely on blood circulation from the warmer parts to keep it manageable. But not this year! A Covid face mask will be just the thing to keep even my face warm, I thought. And it did: the air around my nose and mouth was at a lovely temperature. A little humid, but not uncomfortably so.&lt;/p&gt;&lt;p&gt;But what I &lt;em&gt;wasn&apos;t&lt;/em&gt; expecting was that my moisture-&lt;wbr&gt;laden breath, mostly expelled upward and downward because of the mask in the way, would graze lightly across my eyelashes on its way out and &amp;#8211;&lt;wbr&gt; since they are of course &lt;em&gt;not&lt;/em&gt; under the face mask and hence much colder than my breath &amp;#8211;&lt;wbr&gt; promptly condense all its moisture again in the form of dew.&lt;/p&gt;&lt;p&gt;That was a very strange sensation! I&apos;m used to my &lt;em&gt;eyes themselves&lt;/em&gt; watering from time to time, for all the usual reasons human eyes do that. But water getting in my eyes whose source is the tips of my eyelashes feels very different, and I haven&apos;t quite got the hang of how to blink it away effectively yet.&lt;/p&gt;&lt;p&gt;(Also, being slow and snoozy and early-&lt;wbr&gt;Monday-&lt;wbr&gt;morning, it took me ten minutes to even work out what was going on. Ahem.)&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;https://www.dreamwidth.org/tools/commentcount?user=simont&amp;ditemid=244089&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>https://simont.dreamwidth.org/244089.html</comments>
  <lj:security>public</lj:security>
  <lj:reply-count>3</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>https://simont.dreamwidth.org/243492.html</guid>
  <pubDate>Mon, 09 Sep 2019 12:31:43 GMT</pubDate>
  <title>Being less good at something impresses people more</title>
  <link>https://simont.dreamwidth.org/243492.html</link>
  <description>&lt;p&gt;A long time ago, I was in a nightclub, with a friend, and we ran into a woman who we&apos;d both met a few times before. My friend struggled visibly for a moment, and then correctly remembered her name. She was pleased and flattered. I had known her name immediately without any struggle, but she didn&apos;t look flattered at &lt;em&gt;that&lt;/em&gt;!&lt;/p&gt;&lt;p&gt;A while back a group of my friends used to play a general-&lt;wbr&gt;knowledge quiz game. One question I particularly remember from it was &amp;#8216;Which Bond film was Ringo Starr&apos;s wife in?&amp;#8217;, which we only managed to answer as a team effort: one of us knew Ringo Starr&apos;s wife was Barbara Bach, and another knew Barbara Bach was in &amp;#8216;The Spy Who Loved Me&amp;#8217;, but neither of us knew both facts beforehand. That one sticks in my mind as more memorably satisfying than any of the questions that I got right on my own, even though those demonstrated more knowledge on my part.&lt;/p&gt;&lt;p&gt;If you release a piece of software with a security hole in it, and then fix it promptly and competently when someone finds it, users will be vocally grateful. You&apos;ll get compliments on your dedication and your integrity, and it will increase general trust in you to maintain a security product &amp;#8211;&lt;wbr&gt; far more so, in my experience, than if you&apos;d never introduced the hole in the first place.&lt;/p&gt;&lt;p&gt;Psychologically, it&apos;s easy to come up with reasons why this general pattern of human behaviour makes sense. But it seems like a cognitive weakness nonetheless: &lt;em&gt;surely&lt;/em&gt; there must be a multitude of cases where it creates a perverse incentive to pretend to be less competent than you are, or to make deliberate mistakes so you can earn kudos for fixing them&amp;#8230;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;https://www.dreamwidth.org/tools/commentcount?user=simont&amp;ditemid=243492&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>https://simont.dreamwidth.org/243492.html</comments>
  <lj:security>public</lj:security>
  <lj:reply-count>7</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>https://simont.dreamwidth.org/243294.html</guid>
  <pubDate>Mon, 26 Aug 2019 15:29:51 GMT</pubDate>
  <title>Writing a soluble-grid generator for Mines</title>
  <link>https://simont.dreamwidth.org/243294.html</link>
  <description>&lt;p&gt;Recently, two people emailed me asking the same question about my puzzle collection: they wanted to know how it&apos;s possible for &lt;a href=&quot;https://www.chiark.greenend.org.uk/~sgtatham/puzzles/js/mines.html&quot;&gt;Mines&lt;/a&gt;, my Minesweeper implementation, to guarantee that every grid can be solved without guesswork.&lt;/p&gt;&lt;p&gt;So I wrote up a longish answer to that question, and sent it to both people. And it seems like a waste not to post it here too. Perhaps it could be article number 2 in the informal series that also includes the &lt;a href=&quot;https://simont.dreamwidth.org/242895.html&quot;&gt;article I wrote in March&lt;/a&gt; about how the solver for Net works.&lt;/p&gt;&lt;span class=&quot;cut-wrapper&quot;&gt;&lt;span style=&quot;display: none;&quot; id=&quot;span-cuttag___1&quot; class=&quot;cuttag&quot;&gt;&lt;/span&gt;&lt;b class=&quot;cut-open&quot;&gt;(&amp;nbsp;&lt;/b&gt;&lt;b class=&quot;cut-text&quot;&gt;&lt;a href=&quot;https://simont.dreamwidth.org/243294.html#cutid1&quot;&gt;algorithmics&lt;/a&gt;&lt;/b&gt;&lt;b class=&quot;cut-close&quot;&gt;&amp;nbsp;)&lt;/b&gt;&lt;/span&gt;&lt;div style=&quot;display: none;&quot; id=&quot;div-cuttag___1&quot; aria-live=&quot;assertive&quot;&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;https://www.dreamwidth.org/tools/commentcount?user=simont&amp;ditemid=243294&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>https://simont.dreamwidth.org/243294.html</comments>
  <lj:security>public</lj:security>
  <lj:reply-count>0</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>https://simont.dreamwidth.org/243061.html</guid>
  <pubDate>Wed, 03 Jul 2019 08:41:17 GMT</pubDate>
  <title>The X-Y macro</title>
  <link>https://simont.dreamwidth.org/243061.html</link>
  <description>&lt;p&gt;Here&apos;s a fun piece of C preprocessor trickery I thought up earlier this year.&lt;/p&gt;&lt;span class=&quot;cut-wrapper&quot;&gt;&lt;span style=&quot;display: none;&quot; id=&quot;span-cuttag___1&quot; class=&quot;cuttag&quot;&gt;&lt;/span&gt;&lt;b class=&quot;cut-open&quot;&gt;(&amp;nbsp;&lt;/b&gt;&lt;b class=&quot;cut-text&quot;&gt;&lt;a href=&quot;https://simont.dreamwidth.org/243061.html#cutid1&quot;&gt;preprocessor noodling&lt;/a&gt;&lt;/b&gt;&lt;b class=&quot;cut-close&quot;&gt;&amp;nbsp;)&lt;/b&gt;&lt;/span&gt;&lt;div style=&quot;display: none;&quot; id=&quot;div-cuttag___1&quot; aria-live=&quot;assertive&quot;&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;https://www.dreamwidth.org/tools/commentcount?user=simont&amp;ditemid=243061&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>https://simont.dreamwidth.org/243061.html</comments>
  <lj:security>public</lj:security>
  <lj:reply-count>0</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>https://simont.dreamwidth.org/242895.html</guid>
  <pubDate>Wed, 27 Mar 2019 13:36:22 GMT</pubDate>
  <title>Writing a solver for Net</title>
  <link>https://simont.dreamwidth.org/242895.html</link>
  <description>&lt;p&gt;I had mail yesterday from a computer science student asking how I went about writing the solver for the game &lt;a href=&quot;https://www.chiark.greenend.org.uk/~sgtatham/puzzles/js/net.html&quot;&gt;Net&lt;/a&gt; in my &lt;a href=&quot;https://www.chiark.greenend.org.uk/~sgtatham/puzzles/&quot;&gt;puzzle collection&lt;/a&gt;. I took the question literally, i.e. not just &amp;#8216;what is the algorithm?&amp;#8217; but &amp;#8216;what was your thought process that allowed you to come up with the algorithm?&amp;#8217;. I thought that was a good question, and so I wrote a fairly complete answer.&lt;/p&gt;&lt;p&gt;Having done that, of course, it seems a shame to only send it to a single recipient! So I&apos;ll post it here as well, in case anyone else is interested.&lt;/p&gt;&lt;span class=&quot;cut-wrapper&quot;&gt;&lt;span style=&quot;display: none;&quot; id=&quot;span-cuttag___1&quot; class=&quot;cuttag&quot;&gt;&lt;/span&gt;&lt;b class=&quot;cut-open&quot;&gt;(&amp;nbsp;&lt;/b&gt;&lt;b class=&quot;cut-text&quot;&gt;&lt;a href=&quot;https://simont.dreamwidth.org/242895.html#cutid1&quot;&gt;long description&lt;/a&gt;&lt;/b&gt;&lt;b class=&quot;cut-close&quot;&gt;&amp;nbsp;)&lt;/b&gt;&lt;/span&gt;&lt;div style=&quot;display: none;&quot; id=&quot;div-cuttag___1&quot; aria-live=&quot;assertive&quot;&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;https://www.dreamwidth.org/tools/commentcount?user=simont&amp;ditemid=242895&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>https://simont.dreamwidth.org/242895.html</comments>
  <lj:security>public</lj:security>
  <lj:reply-count>6</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>https://simont.dreamwidth.org/242479.html</guid>
  <pubDate>Sat, 09 Mar 2019 10:34:52 GMT</pubDate>
  <title>Lvalue min and max</title>
  <link>https://simont.dreamwidth.org/242479.html</link>
  <description>&lt;p&gt;I was just reading a paper on gcd algorithms, and was struck by the following statement appearing in a snippet of pseudocode:&lt;/p&gt;&lt;blockquote style=&quot;padding-left: 1.2em; margin-left: 1em&quot;&gt;&lt;pre&gt;&lt;code&gt;max{u, v} := |u-&lt;wbr&gt;v| / 2;&lt;/code&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;in which the obviously intended meaning was &amp;#8216;Replace the larger of u and v with the value computed on the RHS.&amp;#8217; In other words, the author is implicitly considering the &lt;code&gt;max&lt;/code&gt; function to return an lvalue.&lt;/p&gt;&lt;p&gt;It had never occurred to me before that &lt;code&gt;max&lt;/code&gt; &lt;em&gt;could&lt;/em&gt; return an lvalue! If I&apos;d wanted to express the same concept myself, I&apos;d surely have either pre-&lt;wbr&gt;sorted my variables, or written some tedious &lt;code&gt;if&lt;/code&gt; statements out longhand, or else resorted to the notation of &amp;#8216;arg max&amp;#8217;, in which you replace your &lt;em&gt;set&lt;/em&gt; of values to compare with some kind of &lt;em&gt;mapping&lt;/em&gt; of indices to values (say, an array or hash), and where &lt;code&gt;max(set)&lt;/code&gt; simply returns the largest element of the set, &lt;code&gt;argmax(mapping)&lt;/code&gt; returns whatever index maps &lt;em&gt;to&lt;/em&gt; the largest value. I wouldn&apos;t even have &lt;em&gt;thought&lt;/em&gt; of writing it like this.&lt;/p&gt;&lt;p&gt;I think for pseudocode purposes, any of my other options would have been worse, because each one introduces extra bookkeeping or formalism that the reader has to mentally clear out of the way to get at the underlying concept. So I quite liked this notation for its pedagogical value &amp;#8211;&lt;wbr&gt; but at the same time, I recognised that you&apos;d have to translate it back into one of those other less clear idioms as soon as you wanted to implement the algorithm in a real programming language.&lt;/p&gt;&lt;p&gt;Or do you? Now that I think about it, there&apos;s no reason at all why a programming language &lt;em&gt;couldn&apos;t&lt;/em&gt; define a function like &lt;code&gt;min&lt;/code&gt; or &lt;code&gt;max&lt;/code&gt; to return an lvalue. In fact, in C++, a simple implementation is as easy as adding three &lt;code&gt;&amp;amp;&lt;/code&gt; characters to the most obvious version:&lt;/p&gt;&lt;blockquote style=&quot;padding-left: 1.2em; margin-left: 1em&quot;&gt;&lt;pre&gt;&lt;code&gt;// before&lt;br /&gt;template&amp;lt;typename T&amp;gt;&lt;br /&gt;T max(T u, T v) { return u&amp;gt;v ? u : v; }&lt;/code&gt;&lt;/pre&gt;&lt;pre&gt;&lt;code&gt;// after&lt;br /&gt;template&amp;lt;typename T&amp;gt;&lt;br /&gt;T &amp;amp;max(T &amp;amp;u, T &amp;amp;v) { return u&amp;gt;v ? u : v; }&lt;/code&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;But for maximum flexibility, you&apos;d surely want &lt;code&gt;max&lt;/code&gt; to return an lvalue &lt;em&gt;if possible&lt;/em&gt;, and fall back to an rvalue if not. You&apos;d like to be able to write &lt;code&gt;max(u,v) = w&lt;/code&gt; as the above pseudocode did, but you &lt;em&gt;also&lt;/em&gt; still want to be able to write &lt;code&gt;x = max(y,1000)&lt;/code&gt; without a compile error.&lt;/p&gt;&lt;p&gt;And that doesn&apos;t seem so easy in C++. The obvious approach is to have both of the above template definitions in scope at the same time. Overload resolution will use the by-&lt;wbr&gt;value version in cases where only that one matches, and you &lt;em&gt;hope&lt;/em&gt; it will manage to pick the reference version in cases where both match. But sadly, when I tried it, that hope turned out to be misplaced &amp;#8211;&lt;wbr&gt; the language defines no preference order between those two templates.&lt;/p&gt;&lt;p&gt;I wonder if any other languages allow you to get the lvalue/rvalue flexible version to work!&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;https://www.dreamwidth.org/tools/commentcount?user=simont&amp;ditemid=242479&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>https://simont.dreamwidth.org/242479.html</comments>
  <lj:security>public</lj:security>
  <lj:reply-count>12</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>https://simont.dreamwidth.org/242297.html</guid>
  <pubDate>Mon, 18 Feb 2019 13:39:55 GMT</pubDate>
  <title>In praise of xlogo</title>
  <link>https://simont.dreamwidth.org/242297.html</link>
  <description>&lt;p&gt;For those who haven&apos;t encountered it before, &lt;code&gt;xlogo&lt;/code&gt; is a trivial X11 application that pops up a window showing the X Window System logo.&lt;/p&gt;&lt;p&gt;It&apos;s close to being the X equivalent of a &amp;#8216;hello, world&amp;#8217; program, which makes it a good lightweight initial test case. Whenever I need to do a quick check of my X11 connectivity (which in my case usually means I&apos;m checking that SSH X forwarding is basically alive), &lt;code&gt;xlogo&lt;/code&gt; is a good choice of program to run: it won&apos;t spend ages setting itself up, and unlike text-&lt;wbr&gt;only alternatives like &lt;code&gt;xdpyinfo&lt;/code&gt;, it&apos;ll pop up a window on the target display, which makes it easy to check that my connection has gone to the &lt;em&gt;right&lt;/em&gt; display.&lt;/p&gt;&lt;p&gt;But that&apos;s not all &lt;code&gt;xlogo&lt;/code&gt; is good for. There are several other things I use it for:&lt;/p&gt;&lt;p&gt;&lt;b&gt;As a specification&lt;/b&gt;. The source code of &lt;code&gt;xlogo&lt;/code&gt; is the official location of the &lt;em&gt;definition&lt;/em&gt; of the X logo. On one occasion I wanted to put the X logo into some kind of document (though I now can&apos;t remember what), and it turned out that the right way to do that was to read the &lt;code&gt;xlogo&lt;/code&gt; source and hand-&lt;wbr&gt;translate the drawing code into SVG.&lt;/p&gt;&lt;p&gt;&lt;b&gt;As a ruler&lt;/b&gt;. Want to know how big something on your screen is in pixels? Fire up an &lt;code&gt;xlogo&lt;/code&gt;, line it up with one edge of the thing, resize until the opposite edge lines up too, and if your window manager puts up a tooltip during window resizing (which I think all the ones I&apos;ve ever used do), then you know the size.&lt;/p&gt;&lt;p&gt;&lt;b&gt;As an alarm clock&lt;/b&gt;. One of my favourite ways to get a computer to notify me when a job has finished is to get it to start up a &lt;em&gt;giant&lt;/em&gt; &lt;code&gt;xlogo&lt;/code&gt; &amp;#8211;&lt;wbr&gt; large enough to obscure most of my screen &amp;#8211;&lt;wbr&gt; when it&apos;s done. This is better than an audible alert because it&apos;s less antisocial in an open-&lt;wbr&gt;plan office; it&apos;s better than a momentary window flash because if you happen to be looking away at the time the &lt;code&gt;xlogo&lt;/code&gt; is still there when you look back; and it&apos;s better than something like &lt;code&gt;echo Done&lt;/code&gt; because there&apos;s no risk of the window with the message in it being behind something at the time.&lt;/p&gt;&lt;p&gt;&lt;b&gt;As a colour chart&lt;/b&gt;. Want to quickly check what &lt;code&gt;#012345&lt;/code&gt; looks like, or one of those X-&lt;wbr&gt;specific colour names like &lt;code&gt;SteelBlue&lt;/code&gt; or &lt;code&gt;OliveDrab&lt;/code&gt;? I don&apos;t know of a faster way than &lt;code&gt;xlogo -bg &apos;whatever&apos;&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;I&apos;ve also heard of people using it &lt;b&gt;as an X session lifetime process&lt;/b&gt; &amp;#8211;&lt;wbr&gt; that is, the thing which, when it goes away, causes the rest of your X session to shut down. I don&apos;t do that one myself, and I think it&apos;s not common these days because desktop environments generally come with something specifically designed to play that role; but it still has some advantages, because &lt;code&gt;xlogo&lt;/code&gt; is so simple that it&apos;s very unlikely to crash by accident, whereas if your session lifetime process is doing almost any kind of real work, it&apos;s more likely to run into fatal trouble.&lt;/p&gt;&lt;p&gt;In short, I find it a much more useful program than you might think! The only thing I&apos;ve always found a bit annoying about it is that pressing &amp;#8216;q&amp;#8217; doesn&apos;t close it &amp;#8211;&lt;wbr&gt; I&apos;ve always had to go hunting for the close button. But I&apos;ve just found out that that&apos;s configurable, so now I can do&lt;/p&gt;&lt;blockquote style=&quot;padding-left: 1.2em; margin-left: 1em&quot;&gt;&lt;pre&gt;&lt;code&gt;echo &amp;quot;XLogo*translations: :&amp;lt;Key&amp;gt;q: quit()&amp;quot; | xrdb -merge&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;and now my &lt;code&gt;xlogo&lt;/code&gt;s are easily dismissible, as I&apos;ve always wanted. Hooray!&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;https://www.dreamwidth.org/tools/commentcount?user=simont&amp;ditemid=242297&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>https://simont.dreamwidth.org/242297.html</comments>
  <lj:security>public</lj:security>
  <lj:reply-count>3</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>https://simont.dreamwidth.org/242010.html</guid>
  <pubDate>Sat, 16 Feb 2019 16:41:04 GMT</pubDate>
  <title>Adages III</title>
  <link>https://simont.dreamwidth.org/242010.html</link>
  <description>&lt;p&gt;Somehow, in spite of &lt;a href=&quot;http://simont.dreamwidth.org/8317.html&quot;&gt;two&lt;/a&gt; &lt;a href=&quot;http://simont.dreamwidth.org/9613.html&quot;&gt;posts&lt;/a&gt; already full of personal adages of mine, I somehow haven&apos;t exhausted my supply of them yet. In the last couple of years I&apos;ve collected another postful of things that I noticed myself saying a lot and realised I&apos;ve been saying all along.&lt;/p&gt;&lt;span class=&quot;cut-wrapper&quot;&gt;&lt;span style=&quot;display: none;&quot; id=&quot;span-cuttag___1&quot; class=&quot;cuttag&quot;&gt;&lt;/span&gt;&lt;b class=&quot;cut-open&quot;&gt;(&amp;nbsp;&lt;/b&gt;&lt;b class=&quot;cut-text&quot;&gt;&lt;a href=&quot;https://simont.dreamwidth.org/242010.html#cutid1&quot;&gt;much adage about nothing&lt;/a&gt;&lt;/b&gt;&lt;b class=&quot;cut-close&quot;&gt;&amp;nbsp;)&lt;/b&gt;&lt;/span&gt;&lt;div style=&quot;display: none;&quot; id=&quot;div-cuttag___1&quot; aria-live=&quot;assertive&quot;&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;https://www.dreamwidth.org/tools/commentcount?user=simont&amp;ditemid=242010&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>https://simont.dreamwidth.org/242010.html</comments>
  <lj:security>public</lj:security>
  <lj:reply-count>7</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>https://simont.dreamwidth.org/241734.html</guid>
  <pubDate>Tue, 28 Aug 2018 08:18:38 GMT</pubDate>
  <title>ScriptPost</title>
  <link>https://simont.dreamwidth.org/241734.html</link>
  <description>&lt;p&gt;I&apos;ve been handwriting PostScript on occasion for more than half my life &amp;#8211;&lt;wbr&gt; it&apos;s one of those odd side skills that comes in handy more often than you might think &amp;#8211;&lt;wbr&gt; and somehow I think yesterday was the first occasion I can remember when I had to swap the values of two variables.&lt;/p&gt;&lt;p&gt;Usually, in a language where the assignment operator can only change one variable at a time, the idiom for swapping two variables requires three statements, using a temporary variable to save one value in at the point where you&apos;ve just copied the other value from one variable to the other (so they both hold the same value).&lt;/p&gt;&lt;p&gt;PostScript is such a language. The syntax for doing a swap that way (supposing the variables you&apos;re swapping are called &lt;code&gt;foo&lt;/code&gt; and &lt;code&gt;bar&lt;/code&gt;) would be&lt;/p&gt;&lt;blockquote style=&quot;padding-left: 1.2em; margin-left: 1em&quot;&gt;&lt;pre&gt;&lt;code&gt;/tmp foo def&lt;br /&gt;/foo bar def&lt;br /&gt;/bar tmp def&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;in which, for example, &lt;code&gt;/tmp&lt;/code&gt; pushes a variable &lt;em&gt;name&lt;/em&gt; on the operand stack; &lt;code&gt;foo&lt;/code&gt; pushes a variable&apos;s &lt;em&gt;value&lt;/em&gt;; and the &lt;code&gt;def&lt;/code&gt; operator pops both of those operands back off and writes the given value into the variable identified by the given name.&lt;/p&gt;&lt;p&gt;But this is excessively roundabout. PostScript may only let you assign one variable at a time, but its stack structure lets you avoid defining a temporary &lt;em&gt;name&lt;/em&gt;: in order to save the old value of the first variable, you only have to push it temporarily on the operand stack, and recover it after the redefinition of the other. For example:&lt;/p&gt;&lt;blockquote style=&quot;padding-left: 1.2em; margin-left: 1em&quot;&gt;&lt;pre&gt;&lt;code&gt;bar            % push the original value of bar&lt;br /&gt;/bar foo def   % set the final value of bar&lt;br /&gt;/foo exch def  % set foo to the value pulled back off the stack&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;But a neater way avoids even the need for that &lt;code&gt;exch&lt;/code&gt;:&lt;/p&gt;&lt;blockquote style=&quot;padding-left: 1.2em; margin-left: 1em&quot;&gt;&lt;pre&gt;&lt;code&gt;/foo bar       % parameters for the &apos;def&apos; that will set foo&lt;br /&gt;/bar foo       % parameters for the &apos;def&apos; that will set bar&lt;br /&gt;def            % set bar, using the second pair of params&lt;br /&gt;def            % set foo, using the first pair&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;or, once you&apos;re using it in anger and not explaining it every time,&lt;/p&gt;&lt;blockquote style=&quot;padding-left: 1.2em; margin-left: 1em&quot;&gt;&lt;pre&gt;&lt;code&gt;/foo bar /bar foo def def&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;I thought that was unexpectedly cute! It&apos;s got the same set of words as the two separate assignment operations &amp;#8216;&lt;code&gt;/foo bar def&lt;/code&gt;&amp;#8217; and &amp;#8216;&lt;code&gt;/bar foo def&lt;/code&gt;&amp;#8217;, but it uses the fact that PostScript assignment &amp;#8216;statements&amp;#8217; are in some sense &lt;em&gt;not atomic&lt;/em&gt; &amp;#8211;&lt;wbr&gt; specifically, that the evaluation of their RHS and the enaction of the assignment itself can be separated &amp;#8211;&lt;wbr&gt; to interleave those two statements in a way that avoids the usual problem.&lt;/p&gt;&lt;p&gt;And that&apos;s why I think I can&apos;t ever have had to do that before &amp;#8211;&lt;wbr&gt; if I had, then surely I&apos;d have run into this mild cuteness already!&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;https://www.dreamwidth.org/tools/commentcount?user=simont&amp;ditemid=241734&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>https://simont.dreamwidth.org/241734.html</comments>
  <lj:security>public</lj:security>
  <lj:reply-count>6</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>https://simont.dreamwidth.org/241558.html</guid>
  <pubDate>Thu, 14 Jun 2018 22:51:29 GMT</pubDate>
  <title>I fought the law</title>
  <link>https://simont.dreamwidth.org/241558.html</link>
  <description>&lt;p&gt;I had an idea for a silly word game on the way to the pub.&lt;/p&gt;&lt;p&gt;I remembered the famous song lyric &amp;#8216;I fought the law and the law won&amp;#8217;, and I wondered: &lt;em&gt;what&lt;/em&gt; law? If you fought some particular law, might it win in a thematically appropriate way?&lt;/p&gt;&lt;p&gt;For example:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;I fought the law of gravity, and it won by two falls.&lt;/li&gt;&lt;li&gt;I fought the Law of Large Numbers, and it won &amp;#8230; on balance &amp;#8230; in the long run.&lt;/li&gt;&lt;li&gt;I fought Newton&apos;s Third Law, and it fought back just as hard.&lt;/li&gt;&lt;li&gt;I fought the Law of Unintended Consequences, and &amp;#8211;&lt;wbr&gt; BADGER!&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;I feel there are probably more good ones of these that the combined wisdom of the pub didn&apos;t think of&amp;#8230;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;https://www.dreamwidth.org/tools/commentcount?user=simont&amp;ditemid=241558&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>https://simont.dreamwidth.org/241558.html</comments>
  <lj:security>public</lj:security>
  <lj:reply-count>10</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>https://simont.dreamwidth.org/241261.html</guid>
  <pubDate>Fri, 16 Feb 2018 12:41:14 GMT</pubDate>
  <title>Accidental i18n</title>
  <link>https://simont.dreamwidth.org/241261.html</link>
  <description>&lt;p&gt;I told a silly story in the pub last night which I suddenly realise would make a fun post here as well. It&apos;s from a few years ago originally, but I don&apos;t think it matters.&lt;/p&gt;&lt;p&gt;You may have heard of that old chestnut in which an alleged Cambridge University researcher allegedly claims that people can still read written text with no problems even if the internal letters of each word are arbitrarily reordered, as long as the &lt;em&gt;first and last&lt;/em&gt; letters of each word are still the right ones.&lt;/p&gt;&lt;p&gt;This is nonsense, of course, and it&apos;s been &lt;a href=&quot;http://www.mrc-cbu.cam.ac.uk/personal/matt.davis/Cmabrigde/&quot;&gt;debunked&lt;/a&gt; before. But a few years ago, Gareth and I were discussing it, and I dashed off a Perl one-&lt;wbr&gt;liner to do that scrambling transformation. (Perhaps it seemed like a good Perl-&lt;wbr&gt;golf challenge to waste half an hour on, or something like that.)&lt;/p&gt;&lt;p&gt;I got a draft implementation working quickly enough, although it didn&apos;t quite fit on one line:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;$ perl -pe &apos;s!(?&amp;lt;=\b[a-&lt;wbr&gt;z])[a-&lt;wbr&gt;z]*(?=[a-&lt;wbr&gt;z]\b)!join&amp;quot;&amp;quot;,map{$_-&amp;gt;[1]}&lt;br /&gt;            sort{$a-&amp;gt;[0]&amp;lt;=&amp;gt;$b-&amp;gt;[0]}map{[rand,$_]}split//,$&amp;amp;!egi&apos;&lt;br /&gt;But soft, what light through yonder window breaks?&lt;br /&gt;But soft, what lghit tughroh yedonr woindw bkears?&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;But shortly before the working version, I made a small error of a kind that Perl makes uniquely easy: I briefly got my scalar and list contexts confused, tried omitting the &lt;code&gt;join&lt;/code&gt; step, and this happened:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;$ perl -pe &apos;s!(?&amp;lt;=\b[a-&lt;wbr&gt;z])[a-&lt;wbr&gt;z]*(?=[a-&lt;wbr&gt;z]\b)!map{$_-&amp;gt;[1]}&lt;br /&gt;            sort{$a-&amp;gt;[0]&amp;lt;=&amp;gt;$b-&amp;gt;[0]}map{[rand,$_]}split//,$&amp;amp;!egi&apos;&lt;br /&gt;But soft, what light through yonder window breaks?&lt;br /&gt;B1t s2t, w2t l3t t5h y4r w4w b4s?&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Of course &amp;#8211;&lt;wbr&gt; if you don&apos;t explicitly use &lt;code&gt;join&lt;/code&gt; to turn a list of characters back into a single string, then Perl&apos;s default conversion when you use a list in scalar context is to replace it with the length of the list. Slap forehead, mutter &amp;#8216;oh yes, this is Perl&amp;#8217;, fix bug.&lt;/p&gt;&lt;p&gt;But I&apos;m glad I made the mistake, because look at what the wrong program is actually doing: it&apos;s exactly a tool for abbreviating long words in the style of &amp;#8216;i18n&amp;#8217; and &amp;#8216;l10n&amp;#8217;. Of course that&apos;s not a hard thing to do, but I was very amused to have managed to do it &lt;em&gt;completely by accident&lt;/em&gt;!&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;https://www.dreamwidth.org/tools/commentcount?user=simont&amp;ditemid=241261&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>https://simont.dreamwidth.org/241261.html</comments>
  <lj:security>public</lj:security>
  <lj:reply-count>4</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>https://simont.dreamwidth.org/240914.html</guid>
  <pubDate>Sun, 21 Jan 2018 22:02:34 GMT</pubDate>
  <title>Poetry quasi-competition</title>
  <link>https://simont.dreamwidth.org/240914.html</link>
  <description>&lt;p&gt;I woke up this morning with an unholy combination of two famous lines of poetry running around my head. The mashed-&lt;wbr&gt;up line &lt;em&gt;scans&lt;/em&gt; nicely, but I couldn&apos;t work out what would be a good follow-&lt;wbr&gt;up.&lt;/p&gt;&lt;p&gt;So, readers of this diary in all its locations, please send suggestions to follow after this opening line:&lt;/p&gt;&lt;blockquote style=&quot;padding-left: 1.2em; margin-left: 1em&quot;&gt;&lt;p&gt;If I should die before I wake, think only this of me: &lt;/p&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;https://www.dreamwidth.org/tools/commentcount?user=simont&amp;ditemid=240914&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>https://simont.dreamwidth.org/240914.html</comments>
  <lj:security>public</lj:security>
  <lj:reply-count>11</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>https://simont.dreamwidth.org/240668.html</guid>
  <pubDate>Thu, 31 Aug 2017 09:28:44 GMT</pubDate>
  <title>High-layer errors</title>
  <link>https://simont.dreamwidth.org/240668.html</link>
  <description>&lt;p&gt;&amp;#8216;To err is human,&amp;#8217; the quotation says. But it&apos;s not &lt;em&gt;only&lt;/em&gt; human. To err, in general, is the common lot of humans, all other life forms, all mechanical devices, and surely anything else I haven&apos;t thought of for which you can specify any idea of a purpose or intention to have erred from.&lt;/p&gt;&lt;p&gt;Something that&apos;s closer to being human-&lt;wbr&gt;specific (though surely still not completely) is to err at a high cognitive layer.&lt;/p&gt;&lt;p&gt;For example, a few years ago I got home from work, carrying my usual rucksack of random stuff. I opened the front door, found a letter on the mat, picked it up, shut the door behind me, carried letter and rucksack to the study, put them down, unzipped the rucksack &amp;#8230; and then stood there confusedly wondering why I&apos;d done that, and what I might have wanted out of the rucksack.&lt;/p&gt;&lt;p&gt;Of course, I &lt;em&gt;might&lt;/em&gt; have just forgotten what I wanted by the time I got the bag open. But not this time. In this case, what had actually gone wrong was that I had meant to open the &lt;em&gt;letter&lt;/em&gt;, not to open the rucksack.&lt;/p&gt;&lt;p&gt;But I&apos;d somehow mistaken that intention, somewhere in my brain, and issued the wrong &amp;#8216;open this thing&amp;#8217; instruction. And having made that error, the lower layers of my brain&apos;s planning apparatus and motor cortex had all cooperated to faithfully implement the wrong instruction they&apos;d been given.&lt;/p&gt;&lt;p&gt;This is a particularly beautiful example of a high-&lt;wbr&gt;layer cognitive error, because you can easily imagine what a &lt;em&gt;lower&lt;/em&gt;-layer error in the same situation would have looked like. I didn&apos;t, for example, pick up the paper knife and try to slit the rucksack open with it (or, more likely, stop half way through that motion and find myself confusedly wondering how to proceed). Instead, the erroneous intention was carried through perfectly competently, by choosing all the right subgoals and pursuing them in the right way, and it wasn&apos;t until the rucksack was successfully open in front of me that I was confronted with the realisation that I&apos;d made a mistake.&lt;/p&gt;&lt;p&gt;A slightly different example of this phenomenon happened to me the other day, in a computing context. I was sitting at a &lt;code&gt;bash&lt;/code&gt; prompt in a &lt;code&gt;git&lt;/code&gt; checkout, and I ran &lt;code&gt;git stash&lt;/code&gt;, then &lt;code&gt;git pull -r&lt;/code&gt;, and then pressed Ctrl-&lt;wbr&gt;Y &amp;#8230; and then sat there confusedly wondering why I&apos;d just pasted some old half-&lt;wbr&gt;written piece of a past command on to my shell command line.&lt;/p&gt;&lt;p&gt;The right way to complete the sequence would have been the command &lt;code&gt;git stash pop&lt;/code&gt;, to restore the uncommitted changes that I&apos;d had in the checkout before realising I needed to do the disruptive pull operation. So why did I press Ctrl-&lt;wbr&gt;Y instead?&lt;/p&gt;&lt;p&gt;Because in other situations, I&apos;ll sometimes be half way through typing a command, and then realise I need to run another command first (e.g. a &lt;code&gt;cd&lt;/code&gt; command, so as to be in the right directory for the original command to work). In that situation, my habit is to press Ctrl-&lt;wbr&gt;A then Ctrl-&lt;wbr&gt;K, to transfer the half-&lt;wbr&gt;typed command into &lt;code&gt;bash&lt;/code&gt;&apos;s paste buffer; then run the preparatory command; and then press Ctrl-&lt;wbr&gt;Y to paste the original command back on to my command line, after which I can finish typing it and run it.&lt;/p&gt;&lt;p&gt;In other words, the &lt;code&gt;bash&lt;/code&gt;-driving part of my brain has two separate procedures for the high-&lt;wbr&gt;level idea of &amp;#8216;set this half-&lt;wbr&gt;done thing temporarily aside, do a disruptive thing, get the half-&lt;wbr&gt;done thing back from wherever you stashed it&amp;#8217;. One is for half-&lt;wbr&gt;done things in the form of uncommitted work in a &lt;code&gt;git&lt;/code&gt; checkout, and is spelled &lt;code&gt;git stash&lt;/code&gt; / &lt;code&gt;git stash pop&lt;/code&gt;. The other is for half-&lt;wbr&gt;done things in the form of unfinished shell commands, and is spelled &lt;code&gt;^A^K&lt;/code&gt; / &lt;code&gt;^Y&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;And I&apos;d simply forgotten, half way through the action, &lt;em&gt;which&lt;/em&gt; of those two procedures I was in the middle of performing, so I did the second half of the wrong one.&lt;/p&gt;&lt;p&gt;These kinds of high-&lt;wbr&gt;layer error are fascinating to me. They&apos;re often comical &amp;#8211;&lt;wbr&gt; much more so than very &lt;em&gt;low&lt;/em&gt;-layer errors, such as a typo, or a fumble with the paper knife. And it&apos;s always seemed to me that they shed light on the functioning of the brain in a way that low-&lt;wbr&gt;layer errors don&apos;t.&lt;/p&gt;&lt;p&gt;Also, I find that a common feature of high-&lt;wbr&gt;layer errors is that they cause a great deal more confusion afterwards. If I make a low-&lt;wbr&gt;layer motor error like a typo, it will typically be instantly obvious to me that what I &lt;em&gt;meant&lt;/em&gt; to do is not the same as what I &lt;em&gt;did&lt;/em&gt; do; it might be inconvenient to recover from the mistake, but it&apos;s not &lt;em&gt;confusing&lt;/em&gt;. But with high-&lt;wbr&gt;layer errors, in which I&apos;ve just quite competently performed completely the wrong task, I seem to also have half-&lt;wbr&gt;convinced myself that that wrong task &lt;em&gt;was&lt;/em&gt; what I meant to do, and it will take me several seconds of complete confusion to recover from that belief and figure out what just happened.&lt;/p&gt;&lt;p&gt;For example, in the above cases, after I&apos;d opened the rucksack I spent a while trying to remember &lt;em&gt;what&lt;/em&gt; I might have wanted from it; and having pasted some old nonsense on to my shell command line, I started from the assumption that I&apos;d &lt;em&gt;meant&lt;/em&gt; to do that and that the nonsense was about to be useful in some way, if only I could just remember what I might have had in mind. In both cases, my prior for &amp;#8216;you meant to do that and it will make sense in a moment&amp;#8217; was much higher than my prior for &amp;#8216;this was a weird high-&lt;wbr&gt;layer error and you didn&apos;t &lt;em&gt;really&lt;/em&gt; mean to do it at all&amp;#8217;.&lt;/p&gt;&lt;p&gt;I suppose that does make Bayesian sense, since high-&lt;wbr&gt;layer errors seem quite rare &amp;#8211;&lt;wbr&gt; which is another reason I find them notable and interesting when they occur!&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;https://www.dreamwidth.org/tools/commentcount?user=simont&amp;ditemid=240668&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>https://simont.dreamwidth.org/240668.html</comments>
  <lj:security>public</lj:security>
  <lj:reply-count>2</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>https://simont.dreamwidth.org/240479.html</guid>
  <pubDate>Thu, 03 Aug 2017 10:43:37 GMT</pubDate>
  <title>Deoptimisation can be a virtue</title>
  <link>https://simont.dreamwidth.org/240479.html</link>
  <description>&lt;p&gt;There&apos;s a well-&lt;wbr&gt;known saying in computing: &lt;b&gt;premature optimisation is the root of all evil&lt;/b&gt;. The rationale is more or less that tweaking code to make it run faster tends to make it less desirable in various other ways &amp;#8211;&lt;wbr&gt; less easy to read and understand, less flexible in the face of changing future requirements, more complicated and bug-&lt;wbr&gt;prone &amp;#8211;&lt;wbr&gt; and therefore one should get into the habit of not habitually optimising everything proactively, but instead, wait until it becomes clear that some particular piece of your code really is &lt;em&gt;too&lt;/em&gt; slow and is causing a problem. And then optimise just that part.&lt;/p&gt;&lt;p&gt;I have no problem &lt;em&gt;in principle&lt;/em&gt; with this adage. I broadly agree with what it&apos;s trying to say. (Although I must admit to an underlying uneasiness at the idea of &lt;em&gt;most&lt;/em&gt; code being written with more or less no thought for performance. I feel as if that general state of affairs probably contributes to a Parkinson&apos;s Law phenomenon, in which software slows down to fill the CPU time available, so that the main effect of computers getting faster is not that software actually delivers its results more quickly but merely that programmers can afford to be lazier without falling below the &amp;#8216;just about fast enough&amp;#8217; threshold.)&lt;/p&gt;&lt;p&gt;But I have one big problem with applying it in practice, which is that often when I think of the solution to a problem, the first version of it that I am even &lt;em&gt;conscious of&lt;/em&gt; is already somewhat optimised. And sometimes it&apos;s optimised to the point of already being incomprehensible.&lt;/p&gt;&lt;p&gt;For example, ages ago I put up a web page about &lt;a href=&quot;https://www.chiark.greenend.org.uk/~sgtatham/algorithms/listsort.html&quot;&gt;mergesorting linked lists&lt;/a&gt;; &lt;span style=&apos;white-space: nowrap;&apos;&gt;&lt;a href=&apos;https://fanf.dreamwidth.org/profile&apos;&gt;&lt;img src=&apos;https://www.dreamwidth.org/img/silk/identity/user.png&apos; alt=&apos;[personal profile] &apos; width=&apos;17&apos; height=&apos;17&apos; style=&apos;vertical-align: text-bottom; border: 0; padding-right: 1px;&apos; /&gt;&lt;/a&gt;&lt;a href=&apos;https://fanf.dreamwidth.org/&apos;&gt;&lt;b&gt;fanf&lt;/b&gt;&lt;/a&gt;&lt;/span&gt; &lt;a href=&quot;https://fanf.dreamwidth.org/39714.html&quot;&gt;critiqued&lt;/a&gt; my presentation of the algorithm as resembling &amp;#8216;pre-&lt;wbr&gt;optimised assembler translated into prose&amp;#8217;, and presented a logical derivation of the same idea from simple first principles. But that derivation had not gone through my head at any point &amp;#8211;&lt;wbr&gt; the first version of the algorithm that even worked for me at all was more or less the version I published.&lt;/p&gt;&lt;p&gt;Another example of this came up this week, in an algorithmic sort of maths proof &amp;#8211;&lt;wbr&gt; I had proved something to be possible &lt;em&gt;at all&lt;/em&gt; by presenting an example procedure that actually did it, and it turned out that the procedure I&apos;d presented was too optimised to be easily understood, because in the process of thinking it up in the first place, I&apos;d spotted that one of the steps in the procedure would do two of the necessary jobs at once, and then I devoted more complicated verbiage to explaining that fact than it would have taken to present a much simpler procedure that did the two jobs separately. The simpler procedure would have taken more steps, but when all you&apos;re trying to prove is that &lt;em&gt;some&lt;/em&gt; procedure will work, that doesn&apos;t matter at all.&lt;/p&gt;&lt;p&gt;I think the problem I have is that although I recognise in principle that optimisation and legibility often pull in opposite directions, and I can (usually) resist the urge to optimise when it&apos;s clear that legibility would suffer, one thing I&apos;m very resistant to is &lt;em&gt;deliberate de-&lt;wbr&gt;optimisation&lt;/em&gt;: once I&apos;ve got something that &lt;em&gt;has&lt;/em&gt; been optimised (whether on purpose or by accident), it basically doesn&apos;t even occur to me in the first place to make it slower on purpose. And if it did occur to me, I&apos;d still feel very reluctant to actually do it.&lt;/p&gt;&lt;p&gt;This is probably a bias I should try to get under control. The real meaning of &amp;#8216;premature optimisation is bad&amp;#8217; is that the right tradeoff between performance and clarity is often further towards clarity than you think it is &amp;#8211;&lt;wbr&gt; and a corollary is that sometimes it&apos;s further towards clarity than wherever you &lt;em&gt;started&lt;/em&gt;, in which case, &lt;b&gt;deoptimisation can be a virtue&lt;/b&gt;.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;https://www.dreamwidth.org/tools/commentcount?user=simont&amp;ditemid=240479&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>https://simont.dreamwidth.org/240479.html</comments>
  <lj:security>public</lj:security>
  <lj:reply-count>1</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>https://simont.dreamwidth.org/14029.html</guid>
  <pubDate>Wed, 29 Mar 2017 08:09:54 GMT</pubDate>
  <title>More parser theory</title>
  <link>https://simont.dreamwidth.org/14029.html</link>
  <description>I had a conversation recently about low-priority prefix operators in infix expression grammars, which left me mildly uncertain about what they ought to mean. So here&apos;s a quick straw poll.&lt;p&gt;Suppose I have an expression grammar in which the multiplication operator &lt;code&gt;*&lt;/code&gt; and the addition operator &lt;code&gt;+&lt;/code&gt; have their usual relative priority (namely, &lt;code&gt;*&lt;/code&gt; binds more tightly, i.e. is evaluated first). Then suppose I – perhaps unwisely – introduce a prefix operator, which I&apos;ll call &lt;code&gt;PFX&lt;/code&gt; for want of a better name, which has &lt;em&gt;intermediate&lt;/em&gt; priority between the two, so that&lt;ul&gt;&lt;li&gt;&lt;code&gt;PFX a + b&lt;/code&gt; behaves like &lt;code&gt;(PFX a) + b&lt;/code&gt;, i.e. the &lt;code&gt;PFX&lt;/code&gt; is evaluated first&lt;li&gt;&lt;code&gt;PFX a * b&lt;/code&gt; behaves like &lt;code&gt;PFX (a * b)&lt;/code&gt;, i.e. the &lt;code&gt;PFX&lt;/code&gt; is evaluated second.&lt;/li&gt;&lt;/li&gt;&lt;/ul&gt;That&apos;s simple enough (if unusual). But things get weirder when &lt;code&gt;PFX&lt;/code&gt; appears on the &lt;em&gt;right&lt;/em&gt; of another operator. Specifically, what would you imagine happens to &lt;em&gt;this&lt;/em&gt; expression:&lt;pre align=&quot;center&quot;&gt;a * PFX b + c&lt;/pre&gt;in which you &lt;em&gt;can&apos;t&lt;/em&gt; process the operators in priority order (&lt;code&gt;*&lt;/code&gt; then &lt;code&gt;PFX&lt;/code&gt; then &lt;code&gt;+&lt;/code&gt;) because the &lt;code&gt;PFX&lt;/code&gt; necessarily has to happen before the &lt;code&gt;*&lt;/code&gt;.&lt;p&gt;&lt;br /&gt;&lt;div&gt;&lt;a href=&quot;https://www.dreamwidth.org/poll/?id=18119&quot;&gt;View Poll: BODMASWTFBBQ&lt;/a&gt;&lt;/div&gt;&lt;/p&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;https://www.dreamwidth.org/tools/commentcount?user=simont&amp;ditemid=14029&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>https://simont.dreamwidth.org/14029.html</comments>
  <lj:security>public</lj:security>
  <lj:reply-count>3</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>https://simont.dreamwidth.org/13722.html</guid>
  <pubDate>Mon, 20 Feb 2017 20:09:51 GMT</pubDate>
  <title>My language design is bad and I should feel bad</title>
  <link>https://simont.dreamwidth.org/13722.html</link>
  <description>&lt;p&gt;Over the weekend, I realised, extremely belatedly, that the expression language I designed for my free-&lt;wbr&gt;software project &lt;a href=&quot;http://www.chiark.greenend.org.uk/~sgtatham/spigot/&quot;&gt;&lt;code&gt;spigot&lt;/code&gt;&lt;/a&gt; has a grammar bug. Specifically, it&apos;s a context-&lt;wbr&gt;dependency analogous to the C &lt;code&gt;typedef&lt;/code&gt; bug: the same expression can parse differently depending on whether a given identifier is currently defined to be a function or a variable, which means that you need to do your scope analysis in sync with the parse, so that you can know what set of definitions is currently in scope for the subexpression you&apos;re currently looking at.&lt;/p&gt;&lt;span class=&quot;cut-wrapper&quot;&gt;&lt;span style=&quot;display: none;&quot; id=&quot;span-cuttag___1&quot; class=&quot;cuttag&quot;&gt;&lt;/span&gt;&lt;b class=&quot;cut-open&quot;&gt;(&amp;nbsp;&lt;/b&gt;&lt;b class=&quot;cut-text&quot;&gt;&lt;a href=&quot;https://simont.dreamwidth.org/13722.html#cutid1&quot;&gt;confessions, lamentations, and parser theory&lt;/a&gt;&lt;/b&gt;&lt;b class=&quot;cut-close&quot;&gt;&amp;nbsp;)&lt;/b&gt;&lt;/span&gt;&lt;div style=&quot;display: none;&quot; id=&quot;div-cuttag___1&quot; aria-live=&quot;assertive&quot;&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;https://www.dreamwidth.org/tools/commentcount?user=simont&amp;ditemid=13722&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>https://simont.dreamwidth.org/13722.html</comments>
  <lj:security>public</lj:security>
  <lj:reply-count>7</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>https://simont.dreamwidth.org/13393.html</guid>
  <pubDate>Mon, 10 Oct 2016 15:46:25 GMT</pubDate>
  <title>Is there a name for this bad argument?</title>
  <link>https://simont.dreamwidth.org/13393.html</link>
  <description>&lt;p&gt;There&apos;s a particular annoying pattern I notice in debate, in which one person criticises another&apos;s choice of argument on the basis of a sort of misapplication of pragmatics.&lt;/p&gt;&lt;p&gt;Here&apos;s a concrete (if slightly melodramatic) example. Imagine we&apos;re drinking together, and you demand, suspiciously, &amp;#8216;Wait, how do I know you haven&apos;t poisoned this bottle of wine?&amp;#8217;. To which I respond, &amp;#8216;I&apos;m drinking from it too, so that would be a really bad idea!&amp;#8217; Now if you were to think, or say, &amp;#8216;Oh, so you &lt;em&gt;would&lt;/em&gt; have poisoned it if we &lt;em&gt;hadn&apos;t&lt;/em&gt; been drinking from the same bottle?&amp;#8217;, you&apos;d be committing this fallacy.&lt;/p&gt;&lt;p&gt;Because in fact, of course, the &lt;em&gt;main&lt;/em&gt; reason I haven&apos;t tried to poison you is some combination of &lt;em&gt;because I don&apos;t want to&lt;/em&gt; and &lt;em&gt;because I&apos;m too moral to do such a wrong thing&lt;/em&gt;, and both of those reasons would still apply regardless of any detail of who was drinking what.&lt;/p&gt;&lt;p&gt;But you can&apos;t &lt;em&gt;check&lt;/em&gt; those statements, because they&apos;re about stuff entirely inside my own head. So if I&apos;d tried to use either one as a defence, then you&apos;d be no more convinced of my non-&lt;wbr&gt;murderousness than you are now, because if you can believe I might try to poison you in the first place, then you&apos;d have no trouble also believing that I&apos;d lie about my motives in the course of the attempt. Whereas you &lt;em&gt;can&lt;/em&gt; easily verify for yourself that I am indeed drinking from the same bottle, and perhaps you might find it harder to believe I was &lt;em&gt;self-&lt;wbr&gt;sacrificingly&lt;/em&gt; murderous than merely self-&lt;wbr&gt;interestedly murderous.&lt;/p&gt;&lt;p&gt;(Since this is a silly hypothetical example, let&apos;s assume we can disregard all the even more improbable edge cases beloved of fiction, like the poison being in the ice cubes, or smeared on your particular glass in advance, or that I took the antidote beforehand, or have spent ten years building up resistance to iocane powder, etc&amp;#8230;)&lt;/p&gt;&lt;p&gt;Anyway. &lt;em&gt;That&apos;s&lt;/em&gt; why I chose that particular reason as the one to mention: not because it was my &lt;em&gt;core&lt;/em&gt; reason or my &lt;em&gt;only&lt;/em&gt; reason, but because it was one you&apos;d be more likely to believe, because you could check it yourself.&lt;/p&gt;&lt;p&gt;I think the general pattern of which this is an example is: it&apos;s a fallacy to assume that someone who has mentioned &lt;em&gt;one&lt;/em&gt; good or bad property of a thing (or reason to do it or not do it, or whatever) must have chosen that particular property because it&apos;s the &lt;em&gt;most important&lt;/em&gt; or the &lt;em&gt;only&lt;/em&gt; one, rather than choosing the property most appropriate to what particular goal the utterance as a whole is trying to achieve.&lt;/p&gt;&lt;p&gt;In this silly example, my goal is to try to convince you that you&apos;re safe; so I have to pick a reason that will actually &lt;em&gt;manage&lt;/em&gt; to do that job, rather than one that is more important &lt;em&gt;to me&lt;/em&gt; but likely to be less effective. In other kinds of debate, one might similarly choose the argument that appeals most to the particular audience one is trying to convince, not the one that is most fundamental in the arguer&apos;s own mind. Or you might avoid particular arguments because you know they&apos;ll cause some enormous derailing sidetrack. Any number of reasons, really.&lt;/p&gt;&lt;p&gt;So. Does this fallacy have a well-&lt;wbr&gt;known name?&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;https://www.dreamwidth.org/tools/commentcount?user=simont&amp;ditemid=13393&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>https://simont.dreamwidth.org/13393.html</comments>
  <lj:security>public</lj:security>
  <lj:reply-count>13</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>https://simont.dreamwidth.org/13079.html</guid>
  <pubDate>Tue, 21 Jun 2016 07:48:30 GMT</pubDate>
  <title>Regular language</title>
  <link>https://simont.dreamwidth.org/13079.html</link>
  <description>&lt;p&gt;I noticed yesterday after writing a comment in some code that one of my writing habits had changed, without me really noticing. So I thought I&apos;d see what other people&apos;s opinions were.&lt;br /&gt;&lt;div&gt;&lt;a href=&quot;https://www.dreamwidth.org/poll/?id=17528&quot;&gt;View Poll: A regular holy war&lt;/a&gt;&lt;/div&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;https://www.dreamwidth.org/tools/commentcount?user=simont&amp;ditemid=13079&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>https://simont.dreamwidth.org/13079.html</comments>
  <lj:security>public</lj:security>
  <lj:reply-count>20</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>https://simont.dreamwidth.org/12804.html</guid>
  <pubDate>Sun, 27 Mar 2016 12:41:26 GMT</pubDate>
  <title>Found in the files</title>
  <link>https://simont.dreamwidth.org/12804.html</link>
  <description>&lt;p&gt;I visited my mum yesterday, and we ended up going through a box file of snippets she&apos;d saved from my childhood. Among them, printed on silvery ZX thermal printer paper that brought a nostalgic smile to my face in its own right, was the following Sinclair BASIC program, printed together with its output.&lt;/p&gt;&lt;blockquote style=&quot;padding-left: 1.2em; margin-left: 1em&quot;&gt;&lt;pre&gt;&lt;code&gt;   5 BORDER 0: PAPER 0: INK 7: CLS&lt;br /&gt;  10 DIM x(40)&lt;br /&gt;  20 FOR z=1 TO 40: LET a=z*0.1&lt;br /&gt;  30 LET y=SQR (1+(a*a))+SQR ((4-&lt;wbr&gt;a)*(4-&lt;wbr&gt;a)+4)&lt;br /&gt;  40 LET x(z)=y&lt;br /&gt;  50 NEXT z&lt;br /&gt;  60 LET smsf=1&lt;br /&gt;  70 FOR z=1 TO 40: LET a=z*0.1&lt;br /&gt;  80 IF x(smsf)&amp;gt;x(z) THEN LET smsf=z&lt;br /&gt;  90 NEXT z&lt;br /&gt;  95 PRINT &amp;quot;GG end to J&amp;quot;, &amp;quot;Road length&amp;quot;&lt;br /&gt; 100 PRINT smsf,x(smsf)&lt;/code&gt;&lt;/pre&gt;&lt;pre&gt;&lt;code&gt;GG end to J     Road length&lt;br /&gt;13              5.0001815&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;I don&apos;t know why Mum chose to save that program in particular, out of all the ones I must have printed out in the few years I had the Spectrum and that printer. She guessed that it must have been the first one I wrote, but it seems a bit sophisticated for that &amp;#8211;&lt;wbr&gt; surely there would have been a pile of &amp;#8216;hello, world&amp;#8217; type things before this quite mathematical one?&lt;/p&gt;&lt;p&gt;Regardless, I had completely forgotten it, and it makes me smile at the fact that what it seems to be doing is &lt;em&gt;numerically testing&lt;/em&gt; the proposition that a straight line is the shortest distance between two points. (Line 30 calculates the distance from (0,0) to (4,3) via the point (a,1); the rest of the program tries this for lots of different values of a, and finds the one that gives the shortest total distance, which unsurprisingly is the point where the straight-&lt;wbr&gt;line route intersects the line y=1, to the limits of rounding error.)&lt;/p&gt;&lt;p&gt;But I do wonder whether this was something I typed in from elsewhere in full, or followed hints in a manual, or what. I&apos;m particularly curious about the variable name &lt;code&gt;smsf&lt;/code&gt; and the cryptic legend &amp;#8216;GG end to J&amp;#8217;&amp;#8230;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;https://www.dreamwidth.org/tools/commentcount?user=simont&amp;ditemid=12804&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>https://simont.dreamwidth.org/12804.html</comments>
  <lj:security>public</lj:security>
  <lj:reply-count>6</lj:reply-count>
</item>
</channel>
</rss>
