<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="https://shkspr.mobi/blog/wp-content/themes/edent-wordpress-theme/rss-style.xsl" type="text/xsl"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	    xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	     xmlns:dc="http://purl.org/dc/elements/1.1/"
	   xmlns:atom="http://www.w3.org/2005/Atom"
	     xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	  xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>
<channel>
	<title>programming &#8211; Terence Eden’s Blog</title>
	<atom:link href="https://shkspr.mobi/blog/tag/programming/feed/" rel="self" type="application/rss+xml" />
	<link>https://shkspr.mobi/blog</link>
	<description>Regular nonsense about tech and its effects 🙃</description>
	<lastBuildDate>Sat, 04 Apr 2026 08:49:21 +0000</lastBuildDate>
	<language>en-GB</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>

<image>
	<url>https://shkspr.mobi/blog/wp-content/uploads/2023/07/cropped-avatar-32x32.jpeg</url>
	<title>programming &#8211; Terence Eden’s Blog</title>
	<link>https://shkspr.mobi/blog</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title><![CDATA[40 years later, are Bentley's "Programming Pearls" still relevant?]]></title>
		<link>https://shkspr.mobi/blog/2025/09/40-years-later-are-bentleys-programming-pearls-still-relevant/</link>
					<comments>https://shkspr.mobi/blog/2025/09/40-years-later-are-bentleys-programming-pearls-still-relevant/#comments</comments>
				<dc:creator><![CDATA[@edent]]></dc:creator>
		<pubDate>Wed, 03 Sep 2025 11:34:14 +0000</pubDate>
				<category><![CDATA[/etc/]]></category>
		<category><![CDATA[programming]]></category>
		<guid isPermaLink="false">https://shkspr.mobi/blog/?p=44218</guid>

					<description><![CDATA[In September 1985, Jon Bentley published Programming Pearls. A collection of aphorisms designed to reveal truths about the field of programming.  It&#039;s 40 years later - long enough to see several revolutions in the field - so surely these are obsolete, right? They belong in the same category as &#34;always carry a bundle of hay for the horses&#34; or &#34;you won&#039;t always have a pocket calculator with you&#34; or …]]></description>
										<content:encoded><![CDATA[<p>In September 1985, Jon Bentley published <a href="https://dl.acm.org/doi/10.1145/4284.315122">Programming Pearls</a>. A collection of aphorisms designed to reveal truths about the field of programming.</p>

<p>It's 40 years later - long enough to see several revolutions in the field - so surely these are obsolete, right? They belong in the same category as "always carry a bundle of hay for the horses" or "you won't always have a pocket calculator with you" or "tie an onion on your belt to stay stylish".</p>

<p>Ah, my sweet summer child! <i lang="fr">Plus ça change, plus c'est la même chose.</i>  You'll find nearly everything in here depressingly relevant.</p>

<p>Before we dive in, a word for Bentley on the provenance of this collection:</p>

<p><a href="https://shkspr.mobi/blog/wp-content/uploads/2025/09/4284.315122.pdf">Programming Pearls.</a></p>

<blockquote><p>Although there is some truth in each saying in this column, all should be taken with a grain of salt. A word about credit. The name associated with a rule is usually the person who sent me the rule, even if they in fact attributed it to their Cousin Ralph (sorry, Ralph). In a few cases I have listed an earlier reference, together with the author’s current affiliation (to the best of my knowledge). I’m sure that I have slighted many people by denying them proper attribution, and to them I offer the condolence that Plagiarism is the sincerest form of flattery.</p></blockquote>

<p>Here we go!</p>

<p><a href="https://dl.acm.org/doi/10.1145/4284.315122"><img src="https://shkspr.mobi/blog/wp-content/uploads/2025/09/pp-fs8.png" alt="Gnarly monochrome scan of Programming Pearls." width="800" height="243" class="aligncenter size-full wp-image-49144"></a></p>

<h2 id="coding"><a href="https://shkspr.mobi/blog/2025/09/40-years-later-are-bentleys-programming-pearls-still-relevant/#coding">Coding</a></h2>

<blockquote><p>When in doubt, use brute force.
Ken Thompson - Bell Labs</p></blockquote>

<p>Straight off the bat, a winner! Almost all problems are solvable through brute force. It may take time - but throw more resources at it! Once you know it <em>can</em> be done, then it is time to see <em>how</em> it can be done better.</p>

<blockquote><p>Avoid arc-sine and arc-cosine functions - you can usually do better by applying a trig identity or computing a vector dot-product.
Jim Conyngham - Arvin/Calspan Advanced Technology Center</p></blockquote>

<p>And then, just like that, something broadly irrelevant today. These sorts of mathematical functions have been optimised so far that it probably doesn't matter which way you calculate them.</p>

<blockquote><p>Allocate four digits for the year part of a date: a new millenium is coming.
David Martin - Norristown, Pennsylvania</p></blockquote>

<p><em>*weeps*</em> Why didn't they listen to you, David? While I would hope any code written this side of Y2K uses ISO8601, it is amusing that you still occasionally encounter people who want to save two bytes <em>somewhere</em>. Handy in some small systems, but mostly just a recipe for disaster. Looking at you, <a href="https://www.gps.gov/support/user/rollover/">GPS</a>!</p>

<blockquote><p>Avoid asymmetry.
Andy Huber - Data General Corporation</p></blockquote>

<p>I'll be honest, I'm not sure what Andy is going on about here. I <em>assume</em> that he's talking about having the ability to go A-&gt;B without being able to go B-&gt;A. Equally, it could be about accepting data in one format and outputting it in a different format. <a href="https://news.ycombinator.com/item?id=33739184">Some more discussion on the topic</a>.</p>

<blockquote><p>The sooner you start to code, the longer the program will take.
Roy Carlson - University of Wisconsin</p></blockquote>

<p><em>Bam!</em> Right in the truth. Much like <a href="https://quoteinvestigator.com/2014/03/29/sharp-axe/">the woodsman who spends his time sharpening his axe</a>, we know that diving into code is probably the least efficient way to create something.</p>

<blockquote><p>If you can’t write it down in English, you can’t code it.
Peter Halpern - Brooklyn, New York</p></blockquote>

<p>So many bugs come from us not understanding the requirements of the user / customer.</p>

<blockquote><p>Details count.
Peter Weinberger - Bell Labs</p></blockquote>

<p>Hard agree, Pete! It's very easy to go for the "big picture" view of the software. But unless all those sharp edges are filed down, the code isn't going to have a happy life.</p>

<blockquote><p>If the code and the comments disagree, then both are probably wrong.
Norm Schyer - Belt Labs</p></blockquote>

<p>Ah, the dream of self-documenting code will never be realised. Again, this goes back to our (in)ability to properly describe our requirements and our (in)adequacies at turning those comments into code.</p>

<blockquote><p>A procedure should fit on a page.
David Tribble - Arlington, Texas</p></blockquote>

<p>Famously, <a href="https://www.theguardian.com/technology/2018/apr/24/the-two-pizza-rule-and-the-secret-of-amazons-success">Amazon has a "Two Pizza" rule</a> which defines the maximum size of a team. The larger and more complex something is, the more likely it is to go wrong. Yes, there are limits to <abbr title="Don't repeat yourself">DRY</abbr> and <abbr title="You ain't gonna need it">YAGNI</abbr> - but we seem firmly in the paradigm that large procedures / functions are ruinous to one's health.</p>

<blockquote><p>If you have too many special cases, you are doing it wrong.
Craig Zerouni - Computer FX Ltd. London, England</p></blockquote>

<p><code>IF/ELSE</code> and <code>CASE/SWITCH</code> still really test our patience. Beautifully clean code which is ruined by special subroutines for rarely occurring situations. But it is hard to call them "wrong". Sometimes the world is complex and it is the job of computers to do the hard work for us.</p>

<blockquote><p>Get your data structures correct first, and the rest of the program will write itself.
David Jones. Assen, The Netherlands</p></blockquote>

<p>Dave is right. A well-defined data structure is <em>still</em> the essence of most <abbr title="Create, read, update and delete">CRUD</abbr> systems.</p>

<h2 id="user-interfaces"><a href="https://shkspr.mobi/blog/2025/09/40-years-later-are-bentleys-programming-pearls-still-relevant/#user-interfaces">User Interfaces</a></h2>

<blockquote><p>[The Principle of Least Astonishment] Make a user interface as consistent and as predictable as possible.
Contributed by several readers</p></blockquote>

<p><em>*weeps*</em> Why isn't this hammered into every programmer? Today's tools are filled with hidden UI gestures, random menus, and a complete disregard for the user's time.</p>

<blockquote><p>A program designed for inputs from people is usually stressed beyond the breaking point by computer-generated inputs.
Dennis Ritchie. Bell Labs</p></blockquote>

<p>I think this one is mostly irrelevant now. Humans can only type at a limited speed, but computers can generate massive amounts of data instantly. But our machines' abilities to ingest that data has also grown. I suppose the nearest thing is the DDoS - where a webserver designed for a few visitors is overwhelmed by a flood of automated and malicious requests.</p>

<blockquote><p>Twenty percent of all input forms filled out by people contain bad data.
Vic Vyssotsky. Bell Labs</p></blockquote>

<p>Ha! Vic didn't know that we'd have <code>&lt;input type...</code> validation in the 21st century! But, yeah, people write all sorts of crap into forms.</p>

<blockquote><p>Eighty percent of all input forms ask questions they have no business asking.
Mike Garey. Bell Labs</p></blockquote>

<p>Mike was sent from the future to warn the people of the past - but they paid him no heed.</p>

<blockquote><p>Don't make the user provide information that the system already knows.
Rick Lemons. Cardinal Data Systems</p></blockquote>

<p>I'm going to slightly disagree with Rick here. Asking for repeated information is a reasonable way to double-check you've got that information correct. It also helps to validate that the user is who they say they are.</p>

<blockquote><p>For 80 percent of all data sets, 95 percent of the information can be seen in a good graph.
William S. Cleveland. Bell Labs</p></blockquote>

<p>Those of us who have seen <a href="https://en.wikipedia.org/wiki/Anscombe's_quartet">Anscombe's quartet</a> know how true this is.</p>

<h2 id="debugging"><a href="https://shkspr.mobi/blog/2025/09/40-years-later-are-bentleys-programming-pearls-still-relevant/#debugging">Debugging</a></h2>

<blockquote><p>Of all my programming bugs, 80 percent are syntax errors. Of the remaining 20 percent, 80 percent are trivial logical errors. Of the remaining 4 percent, 80 percent are pointer errors. And the remaining 0.8 percent are hard.
Marc Donner. IBM T. J. Watson Research Center</p></blockquote>

<p>Syntax errors are rarer now that we have IDEs. And I hope visual programming languages will further reduce them. Logic errors still plague us. Pointer errors have been eradicated unless you're working at the very lowest levels. And I'd say the number of "hard" bugs is probably higher now due to the complex interaction of multiple libraries and systems.</p>

<blockquote><p>It takes three times the effort to find and fix bugs in system test than when done by the developer. It takes ten times the effort to find and fix bugs in the field than when done in system test. Therefore, insist on unit tests by the developer.
Larry Bernstein. Bell Communications Research</p></blockquote>

<p>We can quibble about the numbers and the ratios - but it is generally harder to fix in prod. That said, getting crash logs from the field has considerable shortened those ratio.</p>

<blockquote><p>Don’t debug standing up. It cuts your patience in half, and you need all you can muster.
Dave Storer. Cedar Rapids, Iowa</p></blockquote>

<p>I'm with Team-Standing-Desk!  So I think Dave is wrong.</p>

<blockquote><p>Don’t get suckered in by the comments - they can be terribly misleading. Debug only the code. 
Dave Storer. Cedar Rapids, Iowa</p></blockquote>

<p>Hmmm. Yes, this is probably correct.  I'm not going to say code is self-documenting these days; but it certainly is a lot easier to read.</p>

<blockquote><p>Testing can show the presence of bugs, but not their absence.
Edsger W. Dijkstra. University of Texas</p></blockquote>

<p>Dare we disagree with Dijkstra?! Well, perhaps a little. With modern fuzzing tools we can show the absence of certain kinds of bugs.</p>

<blockquote><p>Each new user of a new system uncovers a new class of bugs.
Brian Kernighan. Bell Labs</p></blockquote>

<p>Yup! Our code would be bug-free if it weren't for those pesky users!</p>

<blockquote><p>If it ain’t broke, don’t fix it.
Ronald Reagan. Santa Barbara, California</p></blockquote>

<p>Amongst the many things about which to disagree with the former President, this is up there! Code needs maintenance. Some things aren't broke until all of a sudden they are.  Sure, maybe don't change your app's layout because a manager wants a bonus; but things constantly need fixing.</p>

<blockquote><p>[The Maintainer’s Motto] If we can’t fix it, it ain’t broke.
Lieutenant Colonel Walt Weir. United States Army</p></blockquote>

<p>I believe in you. Self deprecation is fine, but self confidence is better.</p>

<blockquote><p>The first step in fixing a broken program is getting it to fail repeatably.
Tom Duff. Bell Labs</p></blockquote>

<p>Yes! Transient errors are the worst! And a huge source of the "it works for me" antipattern.</p>

<h2 id="performance"><a href="https://shkspr.mobi/blog/2025/09/40-years-later-are-bentleys-programming-pearls-still-relevant/#performance">Performance</a></h2>

<blockquote><p>[The First Rule of Program Optimization] Don’t do it.
[The Second Rule of Program Optimization - for experts only] Don't do it yet.
Michael Jackson. Michael Jackson Systems Ltd.</p></blockquote>

<p>As true now as it ever was.</p>

<blockquote><p>The fastest algorithm can frequently be replaced by one that is almost as fast and much easier to understand.
Douglas W. Jones. University of Iowa</p></blockquote>

<p>I'm only <em>mostly</em> in agreement here. Many of the security bugs we see in modern code are due to "clever" tricks which turn out to have nasty strings attached. But, at the microcode level, performance is still everything. And a well-tested fast algorithm may be necessary. As part of the climate crisis we should all be thinking about the efficiency of our code.</p>

<blockquote><p>On some machines indirection is slower with displacement, so the most-used member of a structure or a record should be first. 
Mike Morton. Boston, Massachusetts</p></blockquote>

<p>We live in an age of ridiculously fast SSD and RAM access times. Sequential reads are still slightly faster than random jumps, and structures like <a href="https://en.wikipedia.org/wiki/B-tree">B-Tree</a> give us a good mix of the two. We don't need to align data to the physical tracks of a spinning disk any more.</p>

<blockquote><p>In non-I/O-bound programs, a few percent of the source code typically accounts for over half the run time.
Don Knuth. Stanford University</p></blockquote>

<p>I wonder how true this now is? Perhaps we could replace "I/O" with "Internet requests" and still be accurate?</p>

<blockquote><p>Before optimizing, use a profiler to locate the “hot spots” of the program.
Mike Morton. Boston, Massachusetts</p></blockquote>

<p>Mostly true. But you don't lose much by doing some manual optimisations that you know (from bitter experience) will make a difference.</p>

<blockquote><p>[Conservation of Code Size] When you turn an ordinary page of code into just a handful of instructions for speed, expand the comments to keep the number of source lines, constant.
Mike Morton. Boston, Massachusetts</p></blockquote>

<p>I don't think this is relevant these days. Perhaps it is useful to spend time explaining exactly what trickery you're pulling off with weird syntax. But our tools are now line-count agnostic. Mostly.</p>

<blockquote><p>If the programmer can simulate a construct faster than the compiler can implement the construct itself, then the compiler writer has blown it badly.
Guy L. Steele, Jr. Tartan Laboratories</p></blockquote>

<p>I think this is rather self-evident. But compilers are so ridiculously optimised that this scenario is increasingly rare.</p>

<blockquote><p>To speed up an I/O-bound program, begin by accounting for all I/O. Eliminate that which is unnecessary or redundant, and make the remaining as fast as possible.
David Martin. Norristown, Pennsylvania</p></blockquote>

<p>I think this can be generalised even further. I'm reminded of <a href="https://github.com/npm/npm/issues/11283">NPM's progress bar slowdown issue</a>. There's a lot of redundancy which can be removed in many programs.</p>

<blockquote><p>The fastest I/O is no I/O.
Nils-Peter Nelson. Bell Labs</p></blockquote>

<p>Man! They were <em>obsessed</em> with I/O back in the day! At large volumes, it is still an issue. But perhaps now we can relax just a little?</p>

<blockquote><p>The cheapest, fastest, and most reliable components of a computer system are those that aren’t there.
Gordon Bell. Encore Computer Corporation</p></blockquote>

<p>A little unfair, I think. It's cheaper to have less RAM, but that doesn't make my laptop faster.</p>

<blockquote><p>[Compiler Writer’s Motto-Optimization Pass] Making a wrong program worse is no sin.
Bill McKeeman. Wang Znstitute</p></blockquote>

<p>Personally, I don't think it is the compiler's job to tell me I'm doing it wrong.</p>

<blockquote><p>Electricity travels a foot in a nanosecond.
Commodore Grace Murray Hopper. United States Navy</p></blockquote>

<p>And a nano-Century is Pi seconds! One of those pub-trivia facts which are irrelevant to modern computing.</p>

<blockquote><p>LISP programmers know the value of everything but the cost of nothing.
Alan Perlis. Yale University</p></blockquote>

<p>Nowadays LISP programmers are a protected species and shouldn't be subject to such harsh treatment.</p>

<blockquote><p>[Little’s Formula] The average number of objects in a queue is the product of the entry rate and the average holding time.
Richard E. Fairley. Wang Institute</p></blockquote>

<p>Another of those truisms which kinda don't matter in a world with infinite disk space. Speed is our greatest worry.</p>

<h2 id="documentation"><a href="https://shkspr.mobi/blog/2025/09/40-years-later-are-bentleys-programming-pearls-still-relevant/#documentation">Documentation</a></h2>

<blockquote><p>[The Test of Negation] Don’t include a sentence in documentation if its negation is obviously false.
Bob Martin. AT&amp;T Technologies</p></blockquote>

<p>I don't know if that's the same guy as <a href="https://blog.wesleyac.com/posts/robert-martin">Uncle Bob</a> - but it sounds like the sort of claptrap he'd come up with.  What's obvious to you might not be obvious to others.  Test your writing with your audience to see if they understand your meaning.</p>

<blockquote><p>When explaining a command, or language feature, or hardware widget, first describe the problem it is designed to solve.
David Martin. Norristown, Pennsylvania</p></blockquote>

<p>Agreed. It doesn't need to be an essay, but documentation needs context.</p>

<blockquote><p>[One Page Principle] A (specification, design, procedure, test plan) that will not fit on one page of 8.5-by-11 inch paper cannot be understood.
Mark Ardis. Wang Institute</p></blockquote>

<p>I do have some sympathy with this - see the Two-Pizza rule above - but I think this ignores the reality of modern systems. Yes, we should keep things simple, but we also have to recognise that complexity is unavoidable.</p>

<blockquote><p>The job’s not over until the paperwork’s done.
Anon</p></blockquote>

<p>Amen!</p>

<h2 id="managing-software"><a href="https://shkspr.mobi/blog/2025/09/40-years-later-are-bentleys-programming-pearls-still-relevant/#managing-software">Managing Software</a></h2>

<blockquote><p>The structure of a system reflects the structure of the organization that built it.
Richard E. Fairley. Wang Institute</p></blockquote>

<p>This is <a href="https://en.wikipedia.org/wiki/Conway%27s_law">Conway's Law</a> and it is still fairly true. <a href="https://dl.acm.org/doi/10.1109/RESER.2013.14">Some studies show it is possible to break out of the paradigm</a> but it holds remarkable power.</p>

<blockquote><p>Don’t keep doing what doesn’t work.
Anon</p></blockquote>

<p>If only we could tattoo this on the inside of our eyelids, eh?</p>

<blockquote><p>[Rule of Credibility] The first 90 percent of the code accounts for the first 90 percent of the development time. The remaining 10 percent of the code accounts for the other 90 percent of the development time.
Tom Cargill. Bell Labs</p></blockquote>

<p>Agile methodology has <em>somewhat</em> dimmed the potency of this prediction.  I think people are <em>generally</em> better at estimating now.  But it is hard to escape <a href="https://shkspr.mobi/blog/2022/12/zenos-paradox-and-why-modern-technology-is-rubbish/">Zeno's Paradox</a>.</p>

<blockquote><p>Less than 10 percent of the code has to do with the ostensible purpose of the system; the rest deals with input-output, data validation, data structure maintenance, and other housekeeping.
May Shaw. Carnegie-Mellon University</p></blockquote>

<p>How many times have you installed a simple program only to see it pull in every dependency under the sun?  We need an awful lot of scaffolding to keep our houses standing.</p>

<blockquote><p>Good judgment comes from experience, and experience comes from bad judgment.
Fred Brooks. University of North Carolina</p></blockquote>

<p>I lean <em>slightly</em> towards this. I also strongly believe that you can pick up a lot of good judgement by listening to your users.</p>

<blockquote><p>Don’t write a new program if one already does more or less what you want. And if you must write a program, use existing code to do as much of the work as possible.
Richard Hill. Hewlett-Packard S.A. Geneva, Switzerland</p></blockquote>

<p>This is the open source way. Much easier to fork than start again. But at some point you'll run up against an unwanted design decision which will be load-bearing. Think carefully before you re-use.</p>

<blockquote><p>Whenever possible, steal code.
Tom Duff. Bell Labs</p></blockquote>

<p>ITYM "Respect the terms of an OSI approved Open Source licence" - don't you, Tom?</p>

<blockquote><p>Good customer relations double productivity.
Larry Bernstein. Bell Communications Research</p></blockquote>

<p>A lesson learned by Apple and ignored by Google.</p>

<blockquote><p>Translating a working program to a new language or system takes 10 percent of the original development time or manpower or cost.
Douglas W. Jones University of Iowa</p></blockquote>

<p>I honestly don't know how true that is any more. Automated tools must surely have improved that somewhat?</p>

<blockquote><p>Don’t use the computer to do things that can be done efficiently by hand.
Richard Hill. Hewlett-Packard S.A. Geneva, Switzerland</p></blockquote>

<p>A rare disagreement! Things can be efficiently done by hand <em>once or twice</em> but after that, go nuts! Even if it's something as simple as renaming a dozen files in a directory, you'll learn something interesting from automating it.</p>

<blockquote><p>I’d rather write programs to write programs than write programs.
Dick Sites. Digital Equipment Corporation</p></blockquote>

<p>There will always be people who love working on the meta-task.  They're not wrong for doing so, but it can be an unhelpful distraction sometimes.</p>

<blockquote><p>[Brooks’s Law of Prototypes] Plan to throw one away, you will anyhow.
Fred Brooks. University of North Carolina</p></blockquote>

<p>I'd go further an suggest throwing out even more. It can be hard to sell that to management - but it is necessary.</p>

<blockquote><p>If you plan to throw one away, you will throw away two.
Craig Zerouni. Computer FX Ltd. London, England</p></blockquote>

<p>Craig with the double-tap!</p>

<blockquote><p>Prototyping cuts the work to produce a system by 40 percent.
Larry Bernstein. Bell Communications Research</p></blockquote>

<p>Minor disagreement. Prototyping <em>is</em> part of the work. And it should probably take a considerable amount of time.</p>

<blockquote><p>[Thompson’s rule for first-time telescope makers] It is faster to make a four-inch mirror then a six-inch mirror than to make a six-inch mirror.
Bill McKeeman. Wang Institute</p></blockquote>

<p>Yes. It is always tempting to go for the big win. But baby-steps!</p>

<blockquote><p>Furious activity is no substitute for understanding.
H. H. Williams. Oakland, California</p></blockquote>

<p>Goodness me, yes! It's always tempting to rush in pell-mell. But that's a poor use of time.</p>

<blockquote><p>Always do the hard part first. If the hard part is impossible, why waste time on the easy part? Once the hard part is done, you’re home free.
Always do the easy part first. What you think at first is the easy part often turns out to be the hard part. Once the easy part is done, you can concentrate all your efforts on the hard part.
Al Schapira. Bell Labs</p></blockquote>

<p>Oh, Al! You card! Luckily, there are very few "basic" problems to be solved in modern computing. We know what most of the hard problems are. Perhaps Agile teaches us to always leave software in a working state, so we start with the easy parts?</p>

<blockquote><p>If you lie to the computer, it will get you.
Perry Farrar. Germantown, Maryland</p></blockquote>

<p>We shouldn't anthropomorphise computers; they don't like it. Actually, nowadays it's is quite common to "lie" to computers with dummy data and virtualised environments. It's fine.</p>

<blockquote><p>If a system doesn’t have to be reliable, it can do anything else.
H. H. Williams. Oakland, California</p></blockquote>

<p>Perhaps it is my imagination, but we seem less concerned with reliability these days. A Tesla car is a wonderful example of that.</p>

<blockquote><p>One person’s constant is another person’s variable.
Susan Gerhart. Microelectronics and Computer Technology Corp.</p></blockquote>

<p>I wonder about this one a lot. Scoped access to variables possibly makes this less of an issue in the 21st century?</p>

<blockquote><p>One person’s data is another person’s program.
Guy L. Steele, Jr. Tartan Laboratories</p></blockquote>

<p>I don't quite get this. Anyone care to explain?</p>

<blockquote><p>Eschew clever rules.
Joe Condon. Bell Labs</p></blockquote>

<p>The pearls end with this gem.</p>

<h2 id="what-have-we-learned-today"><a href="https://shkspr.mobi/blog/2025/09/40-years-later-are-bentleys-programming-pearls-still-relevant/#what-have-we-learned-today">What have we learned today?</a></h2>

<p>The majority of my disagreements are minor quibbles. And while disk-bound I/O is rarely a problem, network latency has replaced it as the main cause of delays. We've managed to fix some things, but many seem irrevocably tied to the human condition.</p>

<p>Which one was your favourite?</p>
<img src="https://shkspr.mobi/blog/wp-content/themes/edent-wordpress-theme/info/okgo.php?ID=44218&HTTP_REFERER=RSS" alt="" width="1" height="1" loading="eager">]]></content:encoded>
					
					<wfw:commentRss>https://shkspr.mobi/blog/2025/09/40-years-later-are-bentleys-programming-pearls-still-relevant/feed/</wfw:commentRss>
			<slash:comments>29</slash:comments>
		
		
			</item>
		<item>
		<title><![CDATA[Using Tempest Highlight with WordPress]]></title>
		<link>https://shkspr.mobi/blog/2025/04/using-tempest-highlight-with-wordpress/</link>
					<comments>https://shkspr.mobi/blog/2025/04/using-tempest-highlight-with-wordpress/#comments</comments>
				<dc:creator><![CDATA[@edent]]></dc:creator>
		<pubDate>Sat, 26 Apr 2025 11:34:19 +0000</pubDate>
				<category><![CDATA[/etc/]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[WordPress]]></category>
		<guid isPermaLink="false">https://shkspr.mobi/blog/?p=59866</guid>

					<description><![CDATA[I like to highlight bits of code on my blog. I was using GeSHi - but it has ceased to receive updates and the colours it uses aren&#039;t WCAG compliant.  After skimming through a few options, I found Tempest Highlight. It has nearly everything I want in a code highlighter:        PHP with no 3rd party dependencies.      Lots of common languages.      Modern, with regular updates.      Easy to use fun…]]></description>
										<content:encoded><![CDATA[<p>I like to highlight bits of code on my blog. I <em>was</em> using <a href="https://shkspr.mobi/blog/2025/04/a-small-php-update-to-geshi/">GeSHi</a> - but it has ceased to receive updates and the colours it uses aren't WCAG compliant.</p>

<p>After skimming through a few options, I found <a href="https://github.com/tempestphp/highlight">Tempest Highlight</a>. It has <em>nearly</em> everything I want in a code highlighter:</p>

<ul style="list-style-type: &quot;✅&quot;;">
    <li>&nbsp;PHP with no 3rd party dependencies.</li>
    <li>&nbsp;Lots of common languages.</li>
    <li>&nbsp;Modern, with regular updates.</li>
    <li>&nbsp;Easy to use functions.</li>
    <li>&nbsp;Range of difference style sheets.</li>
</ul>

<p>But, on the downside:</p>

<ul style="list-style-type: &quot;❌&quot;;">
    <li>&nbsp;No WordPress plugin.</li>
    <li>&nbsp;Not all languages supported.</li>
    <li>&nbsp;CSS embedded in HTML.</li>
</ul>

<p>I can live without some esoteric languages, but I don't really want to run <code>composer install</code> on my blog. I just want a quick WordPress plugin.  So, here's how I did it.</p>

<p></p><nav role="doc-toc"><menu><li><h2 id="table-of-contents"><a href="https://shkspr.mobi/blog/2025/04/using-tempest-highlight-with-wordpress/#table-of-contents">Table of Contents</a></h2><menu><li><a href="https://shkspr.mobi/blog/2025/04/using-tempest-highlight-with-wordpress/#here-be-dragons">Here Be Dragons</a></li><li><a href="https://shkspr.mobi/blog/2025/04/using-tempest-highlight-with-wordpress/#the-art-of-loading-without-loading">The Art of Loading without Loading</a></li><li><a href="https://shkspr.mobi/blog/2025/04/using-tempest-highlight-with-wordpress/#testing">Testing</a></li><li><a href="https://shkspr.mobi/blog/2025/04/using-tempest-highlight-with-wordpress/#draw-the-rest-of-the-owl">Draw The Rest of the Owl</a></li><li><a href="https://shkspr.mobi/blog/2025/04/using-tempest-highlight-with-wordpress/#todo">ToDo</a></li><li><a href="https://shkspr.mobi/blog/2025/04/using-tempest-highlight-with-wordpress/#get-the-code">Get the code</a></li></menu></li></menu></nav><p></p>

<h2 id="here-be-dragons"><a href="https://shkspr.mobi/blog/2025/04/using-tempest-highlight-with-wordpress/#here-be-dragons">Here Be Dragons</a></h2>

<p>This is a quick prototype. It has an audience of one; me. It may break in unexpected ways. Use at your own risk.</p>

<p>The file layout is relatively simple:</p>

<pre><code class="language-_">WordPress Plugins
├── Highlight_Plugin
│&nbsp;&nbsp; ├── src/
│&nbsp;&nbsp; ├── autoload.php
│&nbsp;&nbsp; ├── index.php
│&nbsp;&nbsp; └── base.css
</code></pre>

<p>The <code>src/</code> directory contains the <code>src/</code> directory from <a href="https://github.com/tempestphp/highlight">Tempest Highlight</a>.</p>

<h2 id="the-art-of-loading-without-loading"><a href="https://shkspr.mobi/blog/2025/04/using-tempest-highlight-with-wordpress/#the-art-of-loading-without-loading">The Art of Loading without Loading</a></h2>

<p>Normally, to install a PHP package, the <code>composer</code> app creates an autoloader which will magically import everything you need into your project.  We can't do that here. Instead, we need to manually load the library.</p>

<p>Create a file in the plugin's directory called <code>autoload.php</code> - its job is to autoload everything in the <code>src/</code> directory.</p>

<pre><code class="language-php">&lt;?php
spl_autoload_register( function ( $class ) {
    //  Project-specific namespace prefix
    $prefix = "Tempest\\Highlight\\";

    //  Base directory for the namespace prefix
    $base_dir = __DIR__ . "/src/";

    //  Does the class use the namespace prefix?
    $len = strlen( $prefix );
    if ( strncmp( $prefix, $class, $len ) !== 0) {
        //  No, move to the next registered autoloader
        return;
    }

    //  Get the relative class name
    $relative_class = substr( $class, $len );

    //  Replace namespace separators with directory separators, append with .php
    $file = $base_dir . str_replace( "\\", "/", $relative_class ) . ".php";

    //  If the file exists, require it
    if ( file_exists( $file ) ) {
        require $file;
    }
});
</code></pre>

<p>I don't know if that's the <em>easiest</em> way to do it. But it works!</p>

<h2 id="testing"><a href="https://shkspr.mobi/blog/2025/04/using-tempest-highlight-with-wordpress/#testing">Testing</a></h2>

<p>The <code>index.php</code> file can now be tested:</p>

<pre><code class="language-php">//  Load the Tempest Highlight library
require_once __DIR__ . "/autoload.php";

//  Set up the namespace
use Tempest\Highlight\Highlighter;

//  Define the theme.
$theme = new Tempest\Highlight\Themes\InlineTheme( __DIR__ . "/src/Themes/Css/light-plus.css");

//  Create the highlighter.
$highlighter = new Tempest\Highlight\Highlighter( $theme );

//  Print some formatted HTML
echo $highlighter-&gt;parse("&lt;em id='foo' class='bar'&gt;test&lt;/em&gt;", "html" );
</code></pre>

<p>All being well, that should produce this:</p>

<pre><code class="language-_">&amp;lt;&lt;span style="color: #0000ff;"&gt;em&lt;/span&gt; id='foo' class='bar'&amp;gt;test&amp;lt;/&lt;span style="color: #0000ff;"&gt;em&lt;/span&gt;&amp;gt;
</code></pre>

<p>That has the CSS embedded. Not ideal, but certainly good enough.  I picked "light-plus" because it was the only theme which seemed to meet at least WCAG AA when on a white background.</p>

<p>OK, so how do we go from printing out a scrap of HTML to extracting all the code snippets from a WordPress blog?</p>

<h2 id="draw-the-rest-of-the-owl"><a href="https://shkspr.mobi/blog/2025/04/using-tempest-highlight-with-wordpress/#draw-the-rest-of-the-owl">Draw The Rest of the Owl</a></h2>

<p>In <em>theory</em> the code is relatively straightforward.</p>

<h3 id="find-code-snippets"><a href="https://shkspr.mobi/blog/2025/04/using-tempest-highlight-with-wordpress/#find-code-snippets">Find code snippets</a></h3>

<p>My <a href="https://codeberg.org/edent/markdown-extra-unofficial/">Markdown plugin</a> transforms this:</p>

<pre><code class="language-_"> ```javascript
 var a = 2.0;
 ``` 
</code></pre>

<p>Into this:</p>

<pre><code class="language-html">&lt;pre&gt;&lt;code class="language-javascript"&gt;
var a = 2.0;
&lt;/code&gt;&lt;/pre&gt;
</code></pre>

<p>No need to use a regex, the new PHP 8.4 HTMLDocument gives us direct programmatic access to the HTML.</p>

<pre><code class="language-php">//  Load the content into PHP 8.4's HTML DOM.
$dom = Dom\HTMLDocument::createFromString( $content, LIBXML_NOERROR | LIBXML_HTML_NOIMPLIED, "UTF-8" );

//  Select the code snippets.
//  `&lt;pre&gt;&lt;code class="language-*"&gt;`
$codeSnippets = $dom-&gt;querySelectorAll( "pre&gt;code[class^=language-]" );
</code></pre>

<h3 id="replace-the-snippets"><a href="https://shkspr.mobi/blog/2025/04/using-tempest-highlight-with-wordpress/#replace-the-snippets">Replace the snippets</a></h3>

<p>From the above, I have the language and code, so it can "easily" be replaced.</p>

<pre><code class="language-php">//  Iterate through each snippet.
foreach ( $codeSnippets as $code ) {
    //  Get the HTML from within the &lt;code&gt;.
    $originalCode = $code-&gt;textContent;
    //  Replace the contents of &lt;code&gt; with the highlighted HTML.
    $code-&gt;innerHTML = $highlighter-&gt;parse( $originalCode, $language )
}
</code></pre>

<p>Replacing the code in that node manipulates the original DOM.  Which means, after looping through all the snippets, I can return the altered HTML like so:</p>

<pre><code class="language-php">return $dom-&gt;saveHTML();
</code></pre>

<h3 id="and-then"><a href="https://shkspr.mobi/blog/2025/04/using-tempest-highlight-with-wordpress/#and-then">And then…</a></h3>

<p>Obviously, there's a bit more too it than that. It ignores RSS feeds, it adds a base CSS style to the head, some SVGs get embedded, semantic metadata is included, and it all gets a bit tangled and complicated.</p>

<h2 id="todo"><a href="https://shkspr.mobi/blog/2025/04/using-tempest-highlight-with-wordpress/#todo">ToDo</a></h2>

<p>A few things need to happen to make this even better.</p>

<ul>
<li>Encoded comments as well and posts.</li>
<li>Add new languages.</li>
<li>Don't in-line the CSS into the HTML, but add it as a separate stylesheet.</li>
</ul>

<p>But, for now, it is running on my blog and that's good enough for me!</p>

<h2 id="get-the-code"><a href="https://shkspr.mobi/blog/2025/04/using-tempest-highlight-with-wordpress/#get-the-code">Get the code</a></h2>

<p>You can <a href="https://github.com/edent/highlight">play about with the WordPress plugin</a>. Bugs reports, pull requests, and suggestions all warmly welcomed.</p>
<img src="https://shkspr.mobi/blog/wp-content/themes/edent-wordpress-theme/info/okgo.php?ID=59866&HTTP_REFERER=RSS" alt="" width="1" height="1" loading="eager">]]></content:encoded>
					
					<wfw:commentRss>https://shkspr.mobi/blog/2025/04/using-tempest-highlight-with-wordpress/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title><![CDATA[Is this a bug in every Markdown (Extra) parser?]]></title>
		<link>https://shkspr.mobi/blog/2024/10/is-this-a-bug-in-every-markdown-extra-parser/</link>
					<comments>https://shkspr.mobi/blog/2024/10/is-this-a-bug-in-every-markdown-extra-parser/#comments</comments>
				<dc:creator><![CDATA[@edent]]></dc:creator>
		<pubDate>Wed, 30 Oct 2024 12:34:24 +0000</pubDate>
				<category><![CDATA[/etc/]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[markdown]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[syntax]]></category>
		<guid isPermaLink="false">https://shkspr.mobi/blog/?p=53007</guid>

					<description><![CDATA[Markdown is, I think it is fair to say, a frustrating &#34;specification&#34;. It&#039;s origins are a back-of-a-fag-packet document and a buggy Perl script - and we&#039;ve been dealing with the consequences ever since.  There are now multiple Markdown parsers, each with their own idiosyncrasies. To make matters worse, there&#039;s a set of extensions popularly known as &#34;Markdown Extra&#34;.  Extra has support for things…]]></description>
										<content:encoded><![CDATA[<p>Markdown is, I think it is fair to say, a frustrating "specification". It's origins are <a href="https://daringfireball.net/projects/markdown/">a back-of-a-fag-packet document</a> and a buggy Perl script - and we've been dealing with the consequences ever since.</p>

<p>There are now multiple Markdown parsers, each with their own idiosyncrasies. To make matters worse, there's a set of extensions popularly known as "Markdown Extra".</p>

<p>Extra has support for things like tables, footnotes, and - in some dialects - autolinks.</p>

<p>Most of the time, when an author writes the text <code>Visit https://example.com</code> they want the URl to be automatically turned into a hyperlink.  Most Markdown parsers support that. Hurrah!</p>

<p>But there's a rather nasty little edge case.</p>

<p>Markdown is explicitly designed so that <a href="https://daringfireball.net/projects/markdown/syntax#html">authors can mix and match HTML and Markdown</a> in the same document.  This is perfectly valid:</p>

<p><code>I &lt;em&gt;love&lt;/em&gt; the delicious taste of **fresh** oranges!</code></p>

<p>Which becomes:</p>

<p><code>I &lt;em&gt;love&lt;/em&gt; the delicious taste of &lt;strong&gt;fresh&lt;/strong&gt; oranges!</code></p>

<p>This is also valid:</p>

<p><code>&lt;a href="https://example.com/"&gt;Visit my *favourite* site https://example.com/&lt;/a&gt;!</code></p>

<p>The parser is smart enough to ignore the link inside the <code>href=""</code> but will process all the Markdown contents of the <code>&lt;a&gt;</code> element.</p>

<p>The text <em>favourite</em> is converted to <code>&lt;em&gt;favourite&lt;/em&gt;</code> correctly.</p>

<p>But what about the link? Should that be autolinked?</p>

<p>Here's how <a href="https://babelmark.github.io/?text=Autolink%3A+https%3A%2F%2Fexample.com%2F%0A%0AHTML%3A+%3Ca+href%3D%22https%3A%2F%2Fexample.com%2F%22%3EVisit+my+*favourite*+site+https%3A%2F%2Fexample.com%2F%3C%2Fa%3E!">a few dozen different Markdown parsers fare</a>.</p>

<p>Nearly all of the ones which support Autolink end up producing <em>broken</em> HTML. They nest an anchor within an anchor. Something explicitly forbidden by the HTML specification.</p>

<pre><code class="language-html">&lt;a href="https://example.com/"&gt;Visit my
   &lt;em&gt;favourite&lt;/em&gt; site 
   &lt;a href="https://example.com/"&gt;https://example.com/&lt;/a&gt;
&lt;/a&gt;!
</code></pre>

<p>Others break in weird and unexpected ways.</p>

<h2 id="is-this-a-bug"><a href="https://shkspr.mobi/blog/2024/10/is-this-a-bug-in-every-markdown-extra-parser/#is-this-a-bug">Is this a bug?</a></h2>

<p>Markdown is an excellent example of "do what I mean, not what I say" software. To the human reading the text, it might seem obvious which parts need to be transformed and which don't.</p>

<p>There are various specifications for how autolinking should work - but I couldn't find any documents which explicitly discuss where it <em>shouldn't</em> work.</p>

<p>At this point, you're probably going to leave a comment saying that it is the users who are wrong. They should wrap links in brackets, or stick to pure Markdown, or some other tosh.</p>

<p>Markdown was supposed to <strong>simplify</strong> the process of writing HTML. Anything which forces the user to write in an unnatural or confusing way is a bug.</p>

<blockquote><p>Markdown allows you to write using an easy-to-read, easy-to-write plain text format, then convert it to structurally valid XHTML (or HTML).</p>

<p><a href="https://daringfireball.net/projects/markdown/">Markdown Introduction</a></p></blockquote>

<p>I don't think any of the authors of Markdown parsers have been naughty here. They mostly just follow the spec. But Markdown was designed without ever being tested with real users.  And real users break things in all sorts of unexpected and delightful ways.</p>

<p>That's where the real bug is. When we don't test with users and fail to meet their expectations, we produce faulty software.</p>
<img src="https://shkspr.mobi/blog/wp-content/themes/edent-wordpress-theme/info/okgo.php?ID=53007&HTTP_REFERER=RSS" alt="" width="1" height="1" loading="eager">]]></content:encoded>
					
					<wfw:commentRss>https://shkspr.mobi/blog/2024/10/is-this-a-bug-in-every-markdown-extra-parser/feed/</wfw:commentRss>
			<slash:comments>3</slash:comments>
		
		
			</item>
		<item>
		<title><![CDATA[LLMs are good for coding because your documentation is shit]]></title>
		<link>https://shkspr.mobi/blog/2024/07/llms-are-good-for-coding-because-your-documentation-is-shit/</link>
					<comments>https://shkspr.mobi/blog/2024/07/llms-are-good-for-coding-because-your-documentation-is-shit/#comments</comments>
				<dc:creator><![CDATA[@edent]]></dc:creator>
		<pubDate>Fri, 12 Jul 2024 11:34:06 +0000</pubDate>
				<category><![CDATA[/etc/]]></category>
		<category><![CDATA[AI]]></category>
		<category><![CDATA[LLM]]></category>
		<category><![CDATA[programming]]></category>
		<guid isPermaLink="false">https://shkspr.mobi/blog/?p=51036</guid>

					<description><![CDATA[That&#039;s it. That&#039;s the post.  Fine! I&#039;ll expand a little more.  Large Language Models are a type of Artificial Intelligence. They can read text, parse it, process it using the known rules of English, and then regurgitate parts of it on demand.  This means they can read and parse a question like &#34;In Python, how do I add two numbers together?&#34; and then read and parse the Python documentation.  It…]]></description>
										<content:encoded><![CDATA[<p>That's it. That's the post.</p>

<p>Fine! I'll expand a little more.</p>

<p>Large Language Models are a type of Artificial Intelligence. They can read text, parse it, process it using the known rules of English, and then regurgitate parts of it on demand.  This means they can read and parse a question like "In Python, how do I add two numbers together?" and then read and parse the Python documentation.  It will <a href="https://chatgpt.com/share/643a3718-f99b-46d6-b60d-6e60e09ce2ef">produce an output like</a>:</p>

<img src="https://shkspr.mobi/blog/wp-content/uploads/2024/07/pychatgpt-fs8.png" alt="Screenshot of ChatGPT giving a brief tutorial in adding numbers." width="1024" height="724" class="aligncenter size-full wp-image-51037">

<p>What happens if you <a href="https://docs.python.org/3/search.html?q=adding+numbers">search the official Python documentation for "adding numbers"</a>? Nothing useful.</p>

<p>Now, perhaps you think that's a trivial and unfair example. Python has <a href="https://docs.python.org/3/tutorial/introduction.html#numbers">an excellent tutorial which explains addition</a> and the main documentation isn't really aimed at the casual user.</p>

<p>But how many times have you tried to use a moderately popular library, searched through its documentation, and found yourself lost in a maze of twisty passages, all alike?</p>

<p>Be honest! Reading bad documentation sucks. Sometimes it can be impossible to look up the most inconsequential piece of syntax, and sometimes it's maddening to find an example which does exactly what you're trying to do.</p>

<p>We all know that <a href="https://www.zdnet.com/article/stack-overflow-ceo-on-how-it-became-the-worlds-most-popular-programming-site/">StackOverflow built its empire</a> on the back of poor documentation.  Take a look at <a href="https://stackoverflow.com/questions?sort=votes">the highest ranked questions</a> in your favourite language and see if you could answer them <em>using only the official documentation</em>.</p>

<p>Humans aren't good at doing boring things. And programmers (a sub-type of humans) <em>hate</em> the boring job of writing documentation and tutorials. It seems anathema to them.  Even when they can be arsed to write documentation, it is rarely tested with users to see if it is understandable.</p>

<p>We've had over half a century of people writing documentation which is so poor that publishers have made a fortune selling books called "Learn How To Program in ___ the Easy Way!"</p>

<p>Do LLMs occasionally get things wrong? Yes. But official tutorials are also frequently outdated.</p>

<p>Do LLMs burn through hideous amounts of electricity? Yes.</p>

<p>Do LLMs have infinite patience when being asked simple questions? Yes.</p>

<p>Do LLMs win in this arena because humans are lazy? Yes.</p>
<img src="https://shkspr.mobi/blog/wp-content/themes/edent-wordpress-theme/info/okgo.php?ID=51036&HTTP_REFERER=RSS" alt="" width="1" height="1" loading="eager">]]></content:encoded>
					
					<wfw:commentRss>https://shkspr.mobi/blog/2024/07/llms-are-good-for-coding-because-your-documentation-is-shit/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title><![CDATA[Falsehoods Programmers Believe About Weather]]></title>
		<link>https://shkspr.mobi/blog/2024/06/falsehoods-programmers-believe-about-weather/</link>
					<comments>https://shkspr.mobi/blog/2024/06/falsehoods-programmers-believe-about-weather/#comments</comments>
				<dc:creator><![CDATA[@edent]]></dc:creator>
		<pubDate>Tue, 18 Jun 2024 11:34:49 +0000</pubDate>
				<category><![CDATA[/etc/]]></category>
		<category><![CDATA[falsehoods]]></category>
		<category><![CDATA[programming]]></category>
		<guid isPermaLink="false">https://shkspr.mobi/blog/?p=37063</guid>

					<description><![CDATA[(Mostly written in response to this issue on the Awesome Falsehoods list)  For those new to the format, there is a popular meme about things which computer programmers erroneously believe. This isn&#039;t intended to shame anyone - just to point out things which may not be immediately obvious to the neophyte.  There&#039;s nothing us Brits love more than moaning talking about the weather. And, just as…]]></description>
										<content:encoded><![CDATA[<p>(Mostly written in response to <a href="https://github.com/kdeldycke/awesome-falsehood/issues/46">this issue on the Awesome Falsehoods list</a>)</p>

<p>For those new to the format, there is a popular meme about things which computer programmers erroneously believe. This isn't intended to shame anyone - just to point out things which may not be immediately obvious to the neophyte.</p>

<p>There's nothing us Brits love more than <del>moaning</del> talking about the weather. And, just as <a href="https://en.wikipedia.org/wiki/Eskimo_words_for_snow">Inuit speakers have hundreds of words for snow</a>, so English speakers have hundreds of words for rain.</p>

<h2 id="whats-cold-for-you-is-not-cold-for-me"><a href="https://shkspr.mobi/blog/2024/06/falsehoods-programmers-believe-about-weather/#whats-cold-for-you-is-not-cold-for-me">What's cold for you is not cold for me</a></h2>

<p>I've visited countries where I was sweating as soon as I stepped off the plane while the locals were dressed in layers and shivering.</p>

<p>Similarly, I'm sure you've visited a blustery northern English town at night and worried that the hoards of teenagers on the lash are going to catch a chill.</p>

<h2 id="it-doesnt-always-snow-at-christmas"><a href="https://shkspr.mobi/blog/2024/06/falsehoods-programmers-believe-about-weather/#it-doesnt-always-snow-at-christmas">It doesn't always snow at Christmas</a></h2>

<p>A few years ago, I had the delightful experience of enjoying Xmas in the southern hemisphere. The weather was blazing hot - and several stores had artificial snow in the windows for a "festive" look.</p>

<p>There are plenty of calendars which have snowy motifs for December, even on the side of the planet where the Moon is upside down.</p>

<h2 id="%e2%84%83-%e2%84%89-k"><a href="https://shkspr.mobi/blog/2024/06/falsehoods-programmers-believe-about-weather/#%e2%84%83-%e2%84%89-k">℃ ℉ °K</a></h2>

<p>Perhaps the most obvious one. 100° may either be delightfully warm or fatal, depending on what system you use.</p>

<p>There are, of course, <a href="https://en.wikipedia.org/wiki/Conversion_of_scales_of_temperature#Comparison_of_temperature_scales">many different temperature scales</a>.  I recommend <a href="https://shkspr.mobi/blog/2023/05/book-review-inventing-temperature-hasok-chang/">Hasok Chang's Inventing Temperature</a> for more information.</p>

<h2 id="and-more"><a href="https://shkspr.mobi/blog/2024/06/falsehoods-programmers-believe-about-weather/#and-more">And more?</a></h2>

<p>Feel free to add your favourites in the comment box.</p>
<img src="https://shkspr.mobi/blog/wp-content/themes/edent-wordpress-theme/info/okgo.php?ID=37063&HTTP_REFERER=RSS" alt="" width="1" height="1" loading="eager">]]></content:encoded>
					
					<wfw:commentRss>https://shkspr.mobi/blog/2024/06/falsehoods-programmers-believe-about-weather/feed/</wfw:commentRss>
			<slash:comments>8</slash:comments>
		
		
			</item>
		<item>
		<title><![CDATA[Server-Side Rendering of Embedded Markdown Code Snippets in WordPress]]></title>
		<link>https://shkspr.mobi/blog/2024/04/server-side-rendering-of-embedded-markdown-code-snippets/</link>
					<comments>https://shkspr.mobi/blog/2024/04/server-side-rendering-of-embedded-markdown-code-snippets/#comments</comments>
				<dc:creator><![CDATA[@edent]]></dc:creator>
		<pubDate>Thu, 18 Apr 2024 11:34:21 +0000</pubDate>
				<category><![CDATA[/etc/]]></category>
		<category><![CDATA[HowTo]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[WordPress]]></category>
		<guid isPermaLink="false">https://shkspr.mobi/blog/?p=50213</guid>

					<description><![CDATA[Because I&#039;m a grumpy old man, I don&#039;t use Gutenberg or Block themes on my WordPress.  Instead, I write everything in Markdown.  When I write code snippets in Markdown, they look like this:  ```php $a = 1; echo $a; if ($a &#60; 5) {    // Do Something    return thing( $a, true ); } ```   But I want to render that with code highlighting.  I was using the Prismatic Plugin. It is excellent and very…]]></description>
										<content:encoded><![CDATA[<p>Because I'm a grumpy old man, I don't use Gutenberg or Block themes on my WordPress.  Instead, I write everything in Markdown.</p>

<p>When I write code snippets in Markdown, they look like this:</p>

<pre>```php
$a = 1;
echo $a;
if ($a &lt; 5) {
   // Do Something
   return thing( $a, true );
}
```
</pre>

<p>But I want to render that with code highlighting.  I <em>was</em> using the <a href="https://wordpress.org/plugins/prismatic/">Prismatic Plugin</a>. It is excellent and very customisable. But it uses JavaScript to do the code highlighting. I want to respect my readers' time and battery life; so I'm trying to reduce my dependency on Client-Side rendering.</p>

<p>I've switched to a <em>modified</em> version of <a href="https://gehrcke.de/wp-geshi-highlight/">WP-GeSHi-Highlight</a>.  That turns the above Markdown into:</p>

<pre><code class="language-php">$a = 1;
echo $a;
if ($a &lt; 5) {
   // Do Something
   return thing( $a, true );
}
</code></pre>

<h2 id="necessary-changes"><a href="https://shkspr.mobi/blog/2024/04/server-side-rendering-of-embedded-markdown-code-snippets/#necessary-changes">Necessary Changes</a></h2>

<p>When the JetPack Markdown pre-processor encounters a code block, it changes:</p>

<pre>```php</pre>

<p>into</p>

<pre>&lt;pre&gt;&lt;code class="language-php"&gt;</pre>

<p>This means the WP-GeSHi-Highlight detection needs to be changed.</p>

<p>Old version:</p>

<pre><code class="language-php">return preg_replace_callback(
    "/\s*&lt;pre(?:lang=[\"']([\w-]+)[\"']|line=[\"'](\d*)[\"']"
   ."|escaped=[\"'](true|false)?[\"']|cssfile=[\"']([\S]+)[\"']|\s)+&gt;".
    "(.*)&lt;\/pre&gt;\s*/siU",
   "wp_geshi_store_and_substitute",
   $s
);
</code></pre>

<p>New version:</p>

<pre><code class="language-php">return preg_replace_callback(
    "/\s*&lt;code(?:class=[\"']language\-([\w-]+)[\"']|line=[\"'](\d*)[\"']"
   ."|escaped=[\"'](true|false)?[\"']|cssfile=[\"']([\S]+)[\"']|\s)+&gt;".
    "(.*)&lt;\/code&gt;\s*/siU",
   "wp_geshi_store_and_substitute",
   $s
);
</code></pre>

<p>One of those matches looks for <code>escaped=</code> which can be <code>true</code> or <code>false</code>. I always want this to be true so, later in the code, I change a variable from:</p>

<pre><code class="language-php">$escaped = trim($match[3]);
</code></pre>

<p>To:</p>

<pre><code class="language-php">$escaped = true;
</code></pre>

<h2 id="style-changes"><a href="https://shkspr.mobi/blog/2024/04/server-side-rendering-of-embedded-markdown-code-snippets/#style-changes">Style Changes</a></h2>

<p>By default, everything looks pretty good - but there are a few changes I found necessary to make.</p>

<p>Firstly, there was something weird going on with the line-heights of my style, so I added this to my site's CSS:</p>

<pre><code class="language-css">/* GeSHI Highlighter Fixes */
pre:has(&gt; .wp-geshi-highlight-wrap5) {
    line-height: 0;
    padding: 0;
    background: none;
    filter: invert(1);
}
</code></pre>

<p>The <code>invert</code> gives it a dark mode.</p>

<p>Secondly, in order to make any changes to the default styles of the highlighter, you need to add the bundled <code>wp-geshi-highlight.css</code> file into your style directory. The plugin will use that if it exists - so you can change font size and padding to be the same as your main theme.</p>

<h2 id="limitations"><a href="https://shkspr.mobi/blog/2024/04/server-side-rendering-of-embedded-markdown-code-snippets/#limitations">Limitations</a></h2>

<p>There are a few limitations with this approach.</p>

<p>No line-numbers. The plugin looks for something like <code>line="13"</code>, but there's no way to add that in Markdown.</p>

<p>GeSHi hasn't received style updates on some languages for quite some time. It hasn't received <a href="https://github.com/GeSHi/geshi-1.0">any significant update since 2019</a>. Which means bugs and security issues are likely.</p>

<p>Language definitions are quite strict. You can use <code>javascript</code> but not <code>json</code>.</p>

<p>The plugin doesn't have any options - nor an easy way to override its settings. So I've monkeypatched everything above. If the plugin updates, I'll need to change my code.</p>

<h2 id="demos"><a href="https://shkspr.mobi/blog/2024/04/server-side-rendering-of-embedded-markdown-code-snippets/#demos">Demos</a></h2>

<p>A few demos - just so you can see what it looks like.</p>

<h3 id="python"><a href="https://shkspr.mobi/blog/2024/04/server-side-rendering-of-embedded-markdown-code-snippets/#python">Python</a></h3>

<pre><code class="language-python">#!/usr/bin/env python
from datetime import datetime, timedelta
from mastodon import Mastodon
from bs4 import BeautifulSoup

import config

#  Set up access
mastodon = Mastodon( api_base_url=config.instance, access_token=config.access_token )

#  Get user's info
me = mastodon.me()
my_id = me["id"]
year_joined = me["created_at"].year
</code></pre>

<h3 id="bash"><a href="https://shkspr.mobi/blog/2024/04/server-side-rendering-of-embedded-markdown-code-snippets/#bash">Bash</a></h3>

<pre><code class="language-bash">if [ "$(basename $2)" = "Image.gz" ] || [ "$(basename $2)" = "vmlinuz.efi" ]
then
# Compressed install
  echo "Installing compressed kernel"
  base=vmlinuz
else
# Normal install
  echo "Installing normal kernel"
  base=vmlinux
fi

if [ -f $4/$base-$1 ]; then
  mv $4/$base-$1 $4/$base-$1.old
fi
</code></pre>

<h3 id="rust"><a href="https://shkspr.mobi/blog/2024/04/server-side-rendering-of-embedded-markdown-code-snippets/#rust">Rust</a></h3>

<pre><code class="language-rust">// This is the main function.
fn main() {
    // Print text to the console.
    println!("Hello World!");
}
</code></pre>

<h3 id="javascript"><a href="https://shkspr.mobi/blog/2024/04/server-side-rendering-of-embedded-markdown-code-snippets/#javascript">JavaScript</a></h3>

<pre><code class="language-javascript">if (hour &lt; 18) {
  greeting = "Good day";
  alert( greeting );
} 
</code></pre>
<img src="https://shkspr.mobi/blog/wp-content/themes/edent-wordpress-theme/info/okgo.php?ID=50213&HTTP_REFERER=RSS" alt="" width="1" height="1" loading="eager">]]></content:encoded>
					
					<wfw:commentRss>https://shkspr.mobi/blog/2024/04/server-side-rendering-of-embedded-markdown-code-snippets/feed/</wfw:commentRss>
			<slash:comments>3</slash:comments>
		
		
			</item>
		<item>
		<title><![CDATA[There should only ever be one way to express yourself]]></title>
		<link>https://shkspr.mobi/blog/2024/02/there-should-only-ever-be-one-way-to-express-yourself/</link>
					<comments>https://shkspr.mobi/blog/2024/02/there-should-only-ever-be-one-way-to-express-yourself/#comments</comments>
				<dc:creator><![CDATA[@edent]]></dc:creator>
		<pubDate>Sun, 11 Feb 2024 12:34:39 +0000</pubDate>
				<category><![CDATA[/etc/]]></category>
		<category><![CDATA[Computer Science]]></category>
		<category><![CDATA[language]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[python]]></category>
		<guid isPermaLink="false">https://shkspr.mobi/blog/?p=45224</guid>

					<description><![CDATA[I&#039;ve been thinking about programming languages and their design.  In her book about the divergence of the English and American languages, Lynne Murphy asks this question:  wouldn’t it be great if language were logical and maximally efficient? If sentences had only as many syllables as strictly needed? If each word had a single, unique meaning? If there were no homophones, so we’d not be able to mi…]]></description>
										<content:encoded><![CDATA[<p>I've been thinking about programming languages and their design.</p>

<p>In her book about the divergence of the English and American languages, Lynne Murphy asks this question:</p>

<blockquote><p>wouldn’t it be great if language were logical and maximally efficient? If sentences had only as many syllables as strictly needed? If each word had a single, unique meaning? If there were no homophones, so we’d not be able to mix up dear and deer or two and too?</p></blockquote>

<p>That got me thinking about the creativity which can be expressed in code - and whether its a good thing.</p>

<p>Let's take an incredibly simple and common operation - incrementing an integer variable by one.  How would you do that? You've probably see these variations:</p>

<pre><code class="language-_">$i = $i + 1;
</code></pre>

<p>or</p>

<pre><code class="language-_">$i = $i++;
</code></pre>

<p>or</p>

<pre><code class="language-_">$i = 1 + $i;
</code></pre>

<p>or</p>

<pre><code class="language-_">$i = int( float_adder( float($i), 1.00 ) );
</code></pre>

<p>or</p>

<pre><code class="language-_">i1, i2 = i1^i2, (i1&amp;i2) &lt;&lt; 1 
</code></pre>

<p>I'm sure you can come up with a few more esoteric methods.</p>

<p>The Python programming language has a <a href="https://legacy.python.org/dev/peps/pep-0020/">list of aphorisms for good programming practice</a>. One of which is:</p>

<blockquote><p>There should be one-- and preferably only one --obvious way to do it.</p></blockquote>

<p>Is that right? As described in <a href="https://blog.startifact.com/posts/older/what-is-pythonic.html">What is Pythonic?</a>, the Python language itself has multiple ways to accomplish one thing.</p>

<p>But, is it a good idea?</p>

<p>Back to Lynne Murphy again:</p>

<blockquote><p>No, absolutely not. No way. Quit even thinking that. What are you, some kind of philistine? If Shakespeare hadn’t played with the number of syllables in his sentences, he would not have been able to communicate in iambic pentameter.</p></blockquote>

<p>Shakespeare wasn't writing Python though, was he?</p>
<img src="https://shkspr.mobi/blog/wp-content/themes/edent-wordpress-theme/info/okgo.php?ID=45224&HTTP_REFERER=RSS" alt="" width="1" height="1" loading="eager">]]></content:encoded>
					
					<wfw:commentRss>https://shkspr.mobi/blog/2024/02/there-should-only-ever-be-one-way-to-express-yourself/feed/</wfw:commentRss>
			<slash:comments>7</slash:comments>
		
		
			</item>
		<item>
		<title><![CDATA[The Joy and The Pity of making your own stuff]]></title>
		<link>https://shkspr.mobi/blog/2023/12/the-joy-and-the-pity-of-making-your-own-stuff/</link>
					<comments>https://shkspr.mobi/blog/2023/12/the-joy-and-the-pity-of-making-your-own-stuff/#comments</comments>
				<dc:creator><![CDATA[@edent]]></dc:creator>
		<pubDate>Wed, 20 Dec 2023 12:34:13 +0000</pubDate>
				<category><![CDATA[/etc/]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[vegan]]></category>
		<guid isPermaLink="false">https://shkspr.mobi/blog/?p=48955</guid>

					<description><![CDATA[I made my own tofu a few weeks ago.  I got soy milk, heated it, mixed in coagulants, drained it, pressed it, sliced it, then cooked it.  And, you know what? I&#039;m not sure it was worth the effort.    It tasted basically fine - no different to any shop bought tofu. It wasn&#039;t noticeably cheaper, it wasn&#039;t more nutritious, nor was it easier to store and prepare.  I&#039;m sure that if I spent several…]]></description>
										<content:encoded><![CDATA[<p>I made my own tofu a few weeks ago<sup id="fnref:graun"><a href="https://shkspr.mobi/blog/2023/12/the-joy-and-the-pity-of-making-your-own-stuff/#fn:graun" class="footnote-ref" title="Yes, I am fully aware that I am a knit-your-own tofu, Guardian-reading, hipster, vegan stereotype." role="doc-noteref">0</a></sup>.  I got soy milk, heated it, mixed in coagulants, drained it, pressed it, sliced it, then cooked it.  And, you know what? I'm not sure it was worth the effort.</p>

<p><a href="https://mastodon.social/deck/@Edent/111404530882763663"><img src="https://shkspr.mobi/blog/wp-content/uploads/2023/12/tofu.jpg" alt="A thin block of white beancurd." width="554" height="416" class="aligncenter size-full wp-image-48970"></a></p>

<p>It tasted basically fine - no different to any shop bought tofu. It wasn't noticeably cheaper, it wasn't more nutritious, nor was it easier to store and prepare.  I'm sure that if I spent several attempts I would gradually get closer to creating something comparable with the shop-bought product.  And then what? Do I want to spend a few hours tending to my tofu whenever I feel like a stir-fry?</p>

<p>Cooking - and learning its chemistry - can be fun. It can also be a drudge.  Sometimes I don't want to individually peel and slice a dozen ingredients. I want to push a few buttons on my microwave and then eat something.</p>

<p>The same extends to nearly every field. I <em>could</em> knit my own clothes and - no doubt - I would find the process interesting, relaxing, and entertaining.  But for everyday wear, it would be a startling waste of my time to do so. Even if I avoid sweatshop labour and fast-fashion, a decent jumper is <em>cheap</em> and provides excellent utility.</p>

<p>But part of the joy of making - and mending - is that you get to learn a little slice of how the world works.</p>

<p>I first encountered Conway's Game of Life when I was a kid. I thought it was the hideously complicated thing which I simply was not qualified to understand.  But after reading <a href="https://shkspr.mobi/blog/2023/12/book-review-the-man-from-the-future-by-ananyo-bhattacharya/">the biography of von Neumann</a> it suddenly clicked. I <em>understood</em> its simplicity.</p>

<p>In order to test my understanding, <a href="https://codeberg.org/edent/Game_Of_Life/">I built my own Game of Life interpreter</a>. It's nothing fancy. A few dozen lines of Python. It won't win any awards for efficiency nor for coding style. But it <em>works</em>.</p>

<p></p><div style="width: 620px;" class="wp-video"><video class="wp-video-shortcode" id="video-48955-2" width="620" height="620" preload="metadata" controls="controls"><source type="video/mp4" src="https://shkspr.mobi/blog/wp-content/uploads/2023/12/gol.mp4?_=2"><a href="https://shkspr.mobi/blog/wp-content/uploads/2023/12/gol.mp4">https://shkspr.mobi/blog/wp-content/uploads/2023/12/gol.mp4</a></video></div><p></p>

<p>In the unlikely event that I ever need to use Life in production, I'm going to use a mature and well supported library. But by building my own toy implementation, I have a superficial understanding of what it is meant to do, where the pitfalls are, and what limitations I might encounter.</p>

<p>And that's my approach to most things. Learn how to make, understand the obvious problems, fall back to the mainstream option if it is easier than continuing.</p>

<div id="footnotes" role="doc-endnotes">
<hr>
<ol start="0">

<li id="fn:graun">
<p>Yes, I am fully aware that I am a knit-your-own tofu, Guardian-reading, hipster, vegan stereotype.&nbsp;<a href="https://shkspr.mobi/blog/2023/12/the-joy-and-the-pity-of-making-your-own-stuff/#fnref:graun" class="footnote-backref" role="doc-backlink">↩︎</a></p>
</li>

</ol>
</div>
<img src="https://shkspr.mobi/blog/wp-content/themes/edent-wordpress-theme/info/okgo.php?ID=48955&HTTP_REFERER=RSS" alt="" width="1" height="1" loading="eager">]]></content:encoded>
					
					<wfw:commentRss>https://shkspr.mobi/blog/2023/12/the-joy-and-the-pity-of-making-your-own-stuff/feed/</wfw:commentRss>
			<slash:comments>9</slash:comments>
		
		
			</item>
		<item>
		<title><![CDATA[Free Open Banking API using Nordigen / GoCardless]]></title>
		<link>https://shkspr.mobi/blog/2023/10/free-open-banking-api-using-nordigen-gocardless/</link>
					<comments>https://shkspr.mobi/blog/2023/10/free-open-banking-api-using-nordigen-gocardless/#comments</comments>
				<dc:creator><![CDATA[@edent]]></dc:creator>
		<pubDate>Sun, 22 Oct 2023 11:34:09 +0000</pubDate>
				<category><![CDATA[/etc/]]></category>
		<category><![CDATA[api]]></category>
		<category><![CDATA[data]]></category>
		<category><![CDATA[finance]]></category>
		<category><![CDATA[money]]></category>
		<category><![CDATA[openbanking]]></category>
		<category><![CDATA[programming]]></category>
		<guid isPermaLink="false">https://shkspr.mobi/blog/?p=48443</guid>

					<description><![CDATA[A few weeks ago I was moaning about there being no OpenBanking API for personal use. Thankfully, I was wrong!  As pointed out by Dave a company called Nordigen was set up to provide a free Open Banking service. It was quickly bought by GoCardless who said:  We believe access to open banking data should be free. We can now offer it at scale to anyone - developers, partners and Fintechs - looking…]]></description>
										<content:encoded><![CDATA[<p>A few weeks ago I was moaning about <a href="https://shkspr.mobi/blog/2023/10/why-is-there-no-openbanking-api-for-personal-use/">there being no OpenBanking API for personal use</a>. Thankfully, I was wrong!</p>

<p>As pointed out by <a href="https://shkspr.mobi/blog/2023/10/why-is-there-no-openbanking-api-for-personal-use/#comment-330155">Dave</a> a company called <a href="https://www.ft.com/partnercontent/nordigen/europe-needs-free-open-banking-and-heres-why.html">Nordigen was set up to provide a free Open Banking service</a>. It was <a href="https://gocardless.com/g/gc-nordigen/">quickly bought by GoCardless</a> who said:</p>

<blockquote><p>We believe access to open banking data should be free. We can now offer it at scale to anyone - developers, partners and Fintechs - looking to solve customer problems.</p></blockquote>

<p>And, I'm delighted to report, it works! As a solo developer you can get access to your own data <em>for free</em> via the GoCardless APIs.</p>

<img src="https://shkspr.mobi/blog/wp-content/uploads/2023/10/gocardless-fs8.png" alt="Screenshot from GoCardless. 
1. Test with your own data. See how the product flow would look like for your users and what data is available. 2. Set up the API. Follow our documentation to set up the API and start collecting bank account data. 3. Customise the user interface.Pay as you go. Make the user agreement flow for your customers to match your brand. 4. Ready to go live? Need help and advice to set up faster?" width="1507" height="529" class="aligncenter size-full wp-image-48444">

<p>You'll get back a JSON file from each of your banks and credit cards with information like this in it:</p>

<pre><code class="language-json">{
   "bookingDate": "2023-07-11",
   "bookingDateTime": "2023-07-11T20:52:05Z",
   "transactionAmount": {
       "amount": "-2.35",
       "currency": "GBP"
   },
   "creditorName": "GREGGS PLC",
   "remittanceInformationUnstructured": "Greggs PLC, London se1",
   "merchantCategoryCode": "5812",
   "internalTransactionId": "123456789"
}
</code></pre>

<p>For foreign exchange, transactions look like this:</p>

<pre><code class="language-json">{
   "bookingDate": "2023-10-01",
   "bookingDateTime": "2023-10-01T21:41:40Z",
   "transactionAmount": {
      "amount": "-0.82",
      "currency": "GBP"
    },
    "currencyExchange": {
      "instructedAmount": {
         "amount": "1.00",
         "currency": "USD"
      },
      "sourceCurrency": "USD",
      "exchangeRate": "1.2195",
      "targetCurrency": "GBP"
   },
   "creditorName": "KICKSTARTER.COM",
   "remittanceInformationUnstructured": "Kickstarter.com, Httpswww.kick, 1.0 U.S. DOLLAR USA",
   "merchantCategoryCode": "5815",
   "internalTransactionId": "987654321"
}
</code></pre>

<p>Depending on your card and the transaction type, you might also get a few more bits of metadata.</p>

<p>Get started at <a href="https://gocardless.com/bank-account-data/"></a><a href="https://gocardless.com/bank-account-data/">https://gocardless.com/bank-account-data/</a>. From there, it's a case of <a href="https://developer.gocardless.com/bank-account-data/quick-start-guide">following the quickstart guide</a>.</p>

<h2 id="a-few-niggles"><a href="https://shkspr.mobi/blog/2023/10/free-open-banking-api-using-nordigen-gocardless/#a-few-niggles">A few niggles</a></h2>

<p>There's a bit of bouncing around. You've got to get an API key, get the institution ID, sign in, get redirected, get an ID from the callback, then get the bank account details. And <em>then</em> you can get the transactions!</p>

<p>Oh, and the access token only lasts a short while, so you'll need to either re-auth or use a refresh token.</p>

<p>Bank authorisation only lasts 90 days, so you'll have to refresh your details every 3 months. That's standard across all opening banking, but a bit of a pain.</p>

<p>GoCardless have <a href="https://gocardless.com/bank-account-data/coverage/">pretty comprehensive bank coverage</a> but they are missing a few which you might find useful.</p>

<p>Because there are so many financial institution in there, you might find it difficult to work out which one you need to log in to. For example, if you have a Barclays Credit Card, which of these is the right one for you?</p>

<pre><code class="language-json">{
    "id": "BARCLAYCARD_COMMERCIAL_BUKBGB22",
    "name": "Barclaycard Commercial Payments",
    "bic": "BUKBGB22",
    "transaction_total_days": "730",
    "countries": [
      "GB"
    ],
    "logo": "https://cdn.nordigen.com/ais/BARCLAYCARD_COMMERCIAL_BUKBGB22.png"
  },
  {
    "id": "BARCLAYCARD_BUKBGB22",
    "name": "Barclaycard UK",
    "bic": "BUKBGB22",
    "transaction_total_days": "730",
    "countries": [
      "GB"
    ],
    "logo": "https://cdn.nordigen.com/ais/BARCLAYCARD_COMMERCIAL_BUKBGB22.png"
  },
  {
    "id": "BARCLAYS_BUSINESS_BUKBGB22",
    "name": "Barclays Business",
    "bic": "BUKBGB22",
    "transaction_total_days": "730",
    "countries": [
      "GB"
    ],
    "logo": "https://cdn.nordigen.com/ais/BARCLAYS_WEALTH_BUKBGB22.png"
  },
  {
    "id": "BARCLAYS_CORPORATE_BUKBGB22",
    "name": "Barclays Corporate",
    "bic": "BUKBGB22",
    "transaction_total_days": "730",
    "countries": [
      "GB"
    ],
    "logo": "https://cdn.nordigen.com/ais/BARCLAYS_WEALTH_BUKBGB22.png"
  },
  {
    "id": "BARCLAYS_BUKBGB22",
    "name": "Barclays Personal",
    "bic": "BUKBGB22",
    "transaction_total_days": "730",
    "countries": [
      "GB"
    ],
    "logo": "https://cdn.nordigen.com/ais/BARCLAYS_WEALTH_BUKBGB22.png"
  },
  {
    "id": "BARCLAYS_WEALTH_BUKBGB22",
    "name": "Barclays Wealth",
    "bic": "BUKBGB22",
    "transaction_total_days": "730",
    "countries": [
      "GB"
    ],
    "logo": "https://cdn.nordigen.com/ais/BARCLAYS_WEALTH_BUKBGB22.png"
  },
</code></pre>

<p>But, overall, it's an excellent service. Now I just need to find / write something to ingest the data and do something with it!</p>
<img src="https://shkspr.mobi/blog/wp-content/themes/edent-wordpress-theme/info/okgo.php?ID=48443&HTTP_REFERER=RSS" alt="" width="1" height="1" loading="eager">]]></content:encoded>
					
					<wfw:commentRss>https://shkspr.mobi/blog/2023/10/free-open-banking-api-using-nordigen-gocardless/feed/</wfw:commentRss>
			<slash:comments>4</slash:comments>
		
		
			</item>
		<item>
		<title><![CDATA[Why aren't there more visual programming languages? (An ode to DRAKON)]]></title>
		<link>https://shkspr.mobi/blog/2023/04/why-arent-there-more-visual-programming-languages-an-ode-to-drakon/</link>
					<comments>https://shkspr.mobi/blog/2023/04/why-arent-there-more-visual-programming-languages-an-ode-to-drakon/#comments</comments>
				<dc:creator><![CDATA[@edent]]></dc:creator>
		<pubDate>Wed, 26 Apr 2023 11:34:46 +0000</pubDate>
				<category><![CDATA[/etc/]]></category>
		<category><![CDATA[drakon]]></category>
		<category><![CDATA[programming]]></category>
		<guid isPermaLink="false">https://shkspr.mobi/blog/?p=45606</guid>

					<description><![CDATA[I think the computer programming industry is about to reach a reckoning. No, not because ChatGPT can poorly plagiarise buggy code - but because a whole generation of kids have grown up with Scratch. And they&#039;ll want professional tools which have Scratch&#039;s level of usability.  Hand-coding YAML files is a mug&#039;s game; one wrong whitespace and everything is broken. Left a semi-colon off the end of a…]]></description>
										<content:encoded><![CDATA[<p>I think the computer programming industry is about to reach a reckoning. No, not because ChatGPT can poorly plagiarise buggy code - but because a whole generation of kids have grown up with Scratch. And they'll want professional tools which have Scratch's level of usability.</p>

<p>Hand-coding YAML files is a mug's game; one wrong whitespace and everything is broken. Left a semi-colon off the end of a line of code; watch the compiler moan. Mixed up your ints, floats, and strings; the computer has a conniption.</p>

<p>This, frankly, is bollocks. And it isn't solved by having a better IDE gently putting <span style="text-decoration-line: underline; text-decoration-style: wavy; text-decoration-color: red;">danger lines</span> under errant code.</p>

<p>It's solved by having tools which don't let you make that kind of mistake. For example, Scratch lets you drag and drop elements and makes it <em>really</em> hard to have a syntax error - even in complex code:
<img src="https://shkspr.mobi/blog/wp-content/uploads/2023/04/MD5-Scratch.png" alt="Part of the MD5 algorithm expressed in colourful Lego blocks." width="1024" height="854" class="aligncenter size-full wp-image-45607">
(Snippet of <a href="https://scratch.mit.edu/projects/202543793/">MD5 in Scratch</a>)</p>

<p>Scratch isn't perfect. It doesn't prevent you from making logical mistakes - but it makes it much easier to visualise and debug what the computer is doing.</p>

<p>I've long been a fan of the <a href="https://shkspr.mobi/blog/2013/04/use-drakon-to-generate-code-from-flowcharts/">DRAKON programming language</a>. It lets you draw a flow chart and then generate code from that chart. Sadly, the desktop software is rather flakey. But, there's <a href="https://drakon.tech/">a new interactive web editor</a>. It lets you draw flow charts and immediately compile them into JavaScript.</p>

<p>Here's an excerpt from their demo Tetris game:</p>

<img src="https://shkspr.mobi/blog/wp-content/uploads/2023/04/Drakon-Tetris-colourful.png" alt="A colourful state machine diagram." width="1024" height="537" class="aligncenter size-full wp-image-45609">

<p>It takes seconds to design a flow chart and, after a single click, have it spit out relatively optimised JavaScript.</p>

<p>I think you should give <a href="https://drakon.tech/"></a><a href="https://drakon.tech/">https://drakon.tech/</a> a try. It isn't quite as slick as Scratch in terms of having a strictly defined set of "blocks" to use - but it is a <em>much</em> easier tool for creating conditional statements compared to hand-creating a bunch of nested if-else statements which branch off in a twisted mess.</p>

<p>Are there any other tools which let programmers visually design their algorithms?</p>
<img src="https://shkspr.mobi/blog/wp-content/themes/edent-wordpress-theme/info/okgo.php?ID=45606&HTTP_REFERER=RSS" alt="" width="1" height="1" loading="eager">]]></content:encoded>
					
					<wfw:commentRss>https://shkspr.mobi/blog/2023/04/why-arent-there-more-visual-programming-languages-an-ode-to-drakon/feed/</wfw:commentRss>
			<slash:comments>10</slash:comments>
		
		
			</item>
		<item>
		<title><![CDATA[Are there any modern closed-source programming languages?]]></title>
		<link>https://shkspr.mobi/blog/2023/04/are-there-any-modern-closed-source-programming-languages/</link>
					<comments>https://shkspr.mobi/blog/2023/04/are-there-any-modern-closed-source-programming-languages/#comments</comments>
				<dc:creator><![CDATA[@edent]]></dc:creator>
		<pubDate>Sat, 08 Apr 2023 11:34:25 +0000</pubDate>
				<category><![CDATA[/etc/]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[programming]]></category>
		<guid isPermaLink="false">https://shkspr.mobi/blog/?p=45420</guid>

					<description><![CDATA[At a recent OpenUK meetup, one of the participants declared that Open Source had comprehensively won. While businesses might not always release their proprietary source code, 100% of everything they wrote used an open source programming language.  I wondered how true that was. You can, perhaps, moan about the shenanigans around Java&#039;s licencing and you mutter about whether it is easy to get…]]></description>
										<content:encoded><![CDATA[<p>At a recent <a href="https://openuk.uk/">OpenUK</a> meetup, one of the participants declared that Open Source had comprehensively won. While businesses might not always <em>release</em> their proprietary source code, 100% of everything they wrote used an open source programming language.</p>

<p>I wondered how true that was. You can, perhaps, moan about <a href="https://www.bbc.co.uk/news/technology-56639088">the shenanigans around Java's licencing</a> and you mutter about whether it is easy to get involved with C++'s <a href="https://isocpp.org/std/the-committee">JTC1/SC22/WG21</a> - but the core tech behind the two is open. Anyone can read the language specification freely and anyone can build a compiler legally.</p>

<p>It's the same with, to choose a random smattering, <a href="https://github.com/python/cpython">Python</a>, <a href="https://github.com/dotnet/fsharp/">F#</a>, and even <a href="https://github.com/apple/swift">Apple's Swift</a>.</p>

<p>Once upon a time, Flash ruled the roost. Now Flash is dead<sup id="fnref:gordon"><a href="https://shkspr.mobi/blog/2023/04/are-there-any-modern-closed-source-programming-languages/#fn:gordon" class="footnote-ref" title="Flash may be dead but... Clip from the movie &quot;Flash Gordon&quot;. Brian Blessed's character says &quot;Gordon's Alive!?&quot;" role="doc-noteref">0</a></sup>. While COBOL existed before the term Open Source was coined, it is now an open specification with a <a href="https://gnucobol.sourceforge.io/">GPL Compiler</a>. Everything has become open!</p>

<p>But...</p>

<p>There is still a stronghold of proprietary languages. <a href="https://uk.mathworks.com/products/matlab.html">MATLAB</a> is still heavily used by mathematicians and scientists. Languages like R are Open Source and making great in-roads. But MATLAB is popular.</p>

<p>The <a href="https://kx.com/">K Language</a> is widely used in financial firms.</p>

<p>Excel Macros, inexplicably, run the world.</p>

<p>Local scripting languages like AppleScript, and cloud languages like Google App Scripts are also closed - and can only run on proprietary software.</p>

<p>In the gaming world - while Lua and Godot and Blender are open - Unity is the big beast. And that's closed.</p>

<p>And, deep down in the silicon, the microcode running on your CPU, the blob in your Pi's multimedia decoder, and the baseband of your phone's modem are all locked down tighter than a whalebone corset.</p>

<p>But...</p>

<p>Even in those closed gardens, the weeds of Open Source take root. There are hundreds of Open Source libraries, plugins, and tutorials for all proprietary languages.  That doesn't get us to an open compiler or specification, but it brings the culture of Open Source with it.</p>

<p>So, has Open Source won? Mostly, I'd say. At the very least there are good Open Source alternatives to nearly every programming language and paradigm.</p>

<p>There are some niches - science, finance, gaming - which rely on proprietary languages. And Cloud services run custom software on their custom OS running on custom processors.  The new paradigm of LLM AI might eventually be fully open, but rely on processing power so out of reach of mortals that it might as well be closed.</p>

<p>But as more and more students become aware of Open Source, I hope that those last bastions of jealously guarded code will eventually fall.</p>

<p>Got any more examples of proprietary languages? <a href="https://mastodon.social/@Edent/110082980566230545">Join the discussion on Mastodon</a></p>

<div id="footnotes" role="doc-endnotes">
<hr>
<ol start="0">

<li id="fn:gordon">
<p>Flash may be dead but... <video muted="" autoplay="" loop=""><source src="https://shkspr.mobi/blog/wp-content/uploads/2023/03/gordons-alive.mp4" type="video/mp4" width="320">Clip from the movie "Flash Gordon". Brian Blessed's character says "Gordon's Alive!?"</video>&nbsp;<a href="https://shkspr.mobi/blog/2023/04/are-there-any-modern-closed-source-programming-languages/#fnref:gordon" class="footnote-backref" role="doc-backlink">↩︎</a></p>
</li>

</ol>
</div>
<img src="https://shkspr.mobi/blog/wp-content/themes/edent-wordpress-theme/info/okgo.php?ID=45420&HTTP_REFERER=RSS" alt="" width="1" height="1" loading="eager">]]></content:encoded>
					
					<wfw:commentRss>https://shkspr.mobi/blog/2023/04/are-there-any-modern-closed-source-programming-languages/feed/</wfw:commentRss>
			<slash:comments>4</slash:comments>
		
		
			</item>
		<item>
		<title><![CDATA[Regular Expressions make me feel like a powerful wizard - and that's not a good thing]]></title>
		<link>https://shkspr.mobi/blog/2023/02/regular-expressions-make-me-feel-like-a-powerful-wizard-and-thats-not-a-good-thing/</link>
					<comments>https://shkspr.mobi/blog/2023/02/regular-expressions-make-me-feel-like-a-powerful-wizard-and-thats-not-a-good-thing/#comments</comments>
				<dc:creator><![CDATA[@edent]]></dc:creator>
		<pubDate>Mon, 06 Feb 2023 12:34:19 +0000</pubDate>
				<category><![CDATA[/etc/]]></category>
		<category><![CDATA[Computer Science]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[regex]]></category>
		<guid isPermaLink="false">https://shkspr.mobi/blog/?p=44537</guid>

					<description><![CDATA[(This is a rant because I&#039;m exhausted after debugging something. If you&#039;ve made RegEx your whole personality, I&#039;m sorry.)  The other day I had to fix a multi-line Regular Expression (RegEx). After a few hours of peering at it with a variety of tools, I finally understood the problem. Getting that deep into the esoteric mysteries made me feel like a powerful wizard with complete mastery of my…]]></description>
										<content:encoded><![CDATA[<p>(This is a rant because I'm exhausted after debugging something. If you've made RegEx your whole personality, I'm sorry.)</p>

<p>The other day I had to fix a multi-line Regular Expression (RegEx). After a few hours of peering at it with a variety of tools, I finally understood the problem. Getting that deep into the esoteric mysteries made me feel like a powerful wizard with complete mastery of my domain. And I think that's dangerous.</p>

<p>I'm sure we've all read a story about a witch or wizard who distractedly substitutes eye-of-newt with iron-ute with disastrous consequences.  Humans are easily confused.  And confusion leads to unexpected mistakes.</p>

<p>Look, most humans are very bad at reading compiled code. Without any external tools - can you tell me what the following code does?</p>

<pre><code class="language-bin">0000000 c031 d88e c08e 15be b47c ac0e 003c 0474
0000010 10cd f7eb 48f4 6c65 6f6c 202c 6f57 6c72
0000020 2164 0a0d 0000 0000 0000 0000 0000 0000
0000030 0000 0000 0000 0000 0000 0000 0000 0000
*
00001f0 0000 0000 0000 0000 0000 0000 0000 aa55
0000200
</code></pre>

<p>No. Of course not<sup id="fnref:not"><a href="https://shkspr.mobi/blog/2023/02/regular-expressions-make-me-feel-like-a-powerful-wizard-and-thats-not-a-good-thing/#fn:not" class="footnote-ref" title="You can read the original code which is MIT Licenced." role="doc-noteref">0</a></sup>. That's why we write code in a more human readable language and then compile it to computer readable instructions.</p>

<p>Regular Expressions are a sort-of halfway house. They're <em>slightly</em> readable by humans - but written in such a terse vocabulary as to be mostly unintelligible without concentration. There's no space for comments. Different engines have variable support for all their functions. They are a symbolic language with unhelpfully indecipherable and inconsistent symbols.</p>

<p>As a result, once the RegEx becomes more than trivially complex they're hard for most humans to understand. That makes them difficult to debug. It also makes it difficult to add or remove functionality.</p>

<p>I genuinely - and possibly misguidedly - believe that even something like <code>^\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$</code> might just as well be written in <a href="https://esolangs.org/wiki/Brainfuck">BrainFuck</a>.</p>

<p>My contention is that <em>almost all</em> RegExs would be better served by more human readable code and that the very existence of <a href="https://regex101.com/">RegEx101.com</a> ought to bring shame on our industry.</p>

<p>Here are some positive use-cases for RegEx:</p>

<ul>
<li>You want to show off how smart you are.</li>
<li>You need maximum efficiency when combing through a billion lines of text.</li>
<li>You have a desire to build something hard to debug.</li>
<li>You don't have lots of printer paper and need to make your code as terse as possible.</li>
<li>You think if/else and switch/case statements are the mark of a diseased mind.</li>
<li>You don't trust compilers.</li>
</ul>

<p>I know what you're thinking: "This guy's too stupid to get regular expressions!"  Yes. Yes I am. So are most people.</p>

<p>What I'm getting at is that source code is designed to be read and edited by busy and distracted humans.  We should be writing intelligible code for each other and letting computers do the boring work of making it more efficient.</p>

<p>You don't have to agree with me. That's fine. But, perhaps you'll take note of the famous maxim from <a href="https://archive.org/details/newhackersdictio00raym/page/385/mode/1up?q=%22wizard+book%22">the "Wizard" book</a>:</p>

<blockquote><p>a computer language is not just a way of getting a computer to perform operations but rather that it is a novel formal medium for expressing ideas about methodology. Thus, programs must be written for people to read, and only incidentally for machines to execute.</p>

<p><a href="https://web.mit.edu/6.001/6.037/sicp.pdf">Structure and Interpretation of Computer Programs</a></p></blockquote>

<p>We are not wizards. Nor should we strive to be. The alchemists fell.</p>

<div id="footnotes" role="doc-endnotes">
<hr>
<ol start="0">

<li id="fn:not">
<p>You can <a href="https://github.com/AyrA/x86-hello-world">read the original code which is MIT Licenced</a>.&nbsp;<a href="https://shkspr.mobi/blog/2023/02/regular-expressions-make-me-feel-like-a-powerful-wizard-and-thats-not-a-good-thing/#fnref:not" class="footnote-backref" role="doc-backlink">↩︎</a></p>
</li>

</ol>
</div>
<img src="https://shkspr.mobi/blog/wp-content/themes/edent-wordpress-theme/info/okgo.php?ID=44537&HTTP_REFERER=RSS" alt="" width="1" height="1" loading="eager">]]></content:encoded>
					
					<wfw:commentRss>https://shkspr.mobi/blog/2023/02/regular-expressions-make-me-feel-like-a-powerful-wizard-and-thats-not-a-good-thing/feed/</wfw:commentRss>
			<slash:comments>28</slash:comments>
		
		
			</item>
		<item>
		<title><![CDATA[Unicode operators for semantically correct programming]]></title>
		<link>https://shkspr.mobi/blog/2023/01/unicode-operators-for-semantically-correct-programming/</link>
					<comments>https://shkspr.mobi/blog/2023/01/unicode-operators-for-semantically-correct-programming/#comments</comments>
				<dc:creator><![CDATA[@edent]]></dc:creator>
		<pubDate>Thu, 26 Jan 2023 12:34:13 +0000</pubDate>
				<category><![CDATA[/etc/]]></category>
		<category><![CDATA[coding]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[unicode]]></category>
		<guid isPermaLink="false">https://shkspr.mobi/blog/?p=44621</guid>

					<description><![CDATA[Why do most programming languages use the / character when we have a perfectly good ÷ symbol?  Similarly, why use != instead of ≠? Or =&#62; rather than →?  The obvious answer is that the humble keyboard usually only has around 100 keys - and most humans have a hard time remembering where thousands of alternate characters are.  Some programming fonts attempt to get around this with ligatures. That all…]]></description>
										<content:encoded><![CDATA[<p>Why do most programming languages use the <code>/</code> character when we have a perfectly good <code>÷</code> symbol?  Similarly, why use <code>!=</code> instead of <code>≠</code>? Or <code>=&gt;</code> rather than <code>→</code>?</p>

<p>The obvious answer is that the humble keyboard usually only has around 100 keys - and most humans have a hard time remembering where thousands of alternate characters are.</p>

<p>Some <a href="https://betterwebtype.com/articles/2020/02/13/5-monospaced-fonts-with-cool-coding-ligatures/">programming fonts attempt to get around this with ligatures</a>. That allows the user to type <code>&lt;=</code> but have the font display <code>≤</code></p>

<p>Are there any modern programming languages which allow the use of semantically correct Unicode symbols as operators?</p>

<p>As far as I can tell, there's only one!</p>

<h2 id="scala"><a href="https://shkspr.mobi/blog/2023/01/unicode-operators-for-semantically-correct-programming/#scala">Scala</a></h2>

<p>Here's a trivial example which creates the <code>÷</code> operator:</p>

<pre><code class="language-scala">case class A(v: Float) {
  def ÷(b: A): A = A(v / b.v)
}
val a = A(9)
val b = A(5)
a ÷ b
</code></pre>

<p>According to the <a href="https://docs.scala-lang.org/scala3/reference/syntax.html#">Scala reference documentation</a>, valid characters for operators include "Unicode categories Sm, So".</p>

<p>That's "<a href="https://www.fileformat.info/info/unicode/category/Sm/list.htm">Symbols, maths</a>" and "<a href="https://www.fileformat.info/info/unicode/category/So/list.htm">Symbols, others</a>".  That covers quite a lot of useful symbols. Including some Emoji!  So you could have <code>☺</code> as an operator.</p>

<p><a href="https://scastie.scala-lang.org/bUmhTgQEQB2rAPInMgVnJQ">Try it in your browser</a>.</p>

<h2 id="others"><a href="https://shkspr.mobi/blog/2023/01/unicode-operators-for-semantically-correct-programming/#others">Others</a></h2>

<p>I took a quick scan through some other modern languages:</p>

<ul>
<li>Ruby

<ul>
<li>Ruby has a <a href="https://github.com/collectiveidea/unicode_math">Unicode Math gem</a> which lets you write code like <code>∛ 27</code>.  But, as far as I can tell, there's no way to create your own operators.</li>
</ul></li>
<li>Haskell

<ul>
<li>There's <a href="https://downloads.haskell.org/ghc/latest/docs/users_guide/exts/unicode_syntax.html">an extension for <em>some</em> Unicode characters</a>. But there's not many there and no way to create new ones.</li>
</ul></li>
<li>Python

<ul>
<li>Nope. There's no way to create your own operators. <a href="https://peps.python.org/pep-3131/">And function names can only contain a subset of Unicode</a>.</li>
</ul></li>
<li>C++

<ul>
<li>Nope. You can overload existing operators but cannot define your own.</li>
</ul></li>
<li>Go

<ul>
<li>No.</li>
</ul></li>
<li>Rust

<ul>
<li><a href="https://doc.rust-lang.org/std/ops/index.html">Also no</a>.</li>
</ul></li>
<li>Java

<ul>
<li>Nuh-uh.</li>
</ul></li>
<li>Javascript

<ul>
<li><a href="https://www.destroyallsoftware.com/talks/wat">WAT</a>.</li>
</ul></li>
</ul>

<p>In fact, according to the inimitable <a href="http://xahlee.info/comp/unicode_support_ruby_python_elisp.html">Xah Lee</a> the only other languages which allow user-defined Unicode operators are Julia and Wolfram.</p>

<p>Julia, I had some difficulty with, but this works:</p>

<pre><code class="language-julia">☺(x)=sqrt(x)
print(☺(25))

÷(x,y)=x/y
print(25 ÷ 6)
</code></pre>

<p>I am, sadly, not clever enough to even understand the <em>documentation</em> for the Wolfram language.</p>

<h2 id="what-next"><a href="https://shkspr.mobi/blog/2023/01/unicode-operators-for-semantically-correct-programming/#what-next">What next?</a></h2>

<p>Obviously I am now a convert to Scala and will henceforth rewrite all my code in it using multiple Unicode symbols.</p>

<p>But, more practically, I wonder if there's demand for a (new) programming language which treats Unicode operators a first class citizens?  Or perhaps future versions of your favourite language should embrace the loving warmth of the Unicode consortium?</p>

<p>Thoughts?</p>
<img src="https://shkspr.mobi/blog/wp-content/themes/edent-wordpress-theme/info/okgo.php?ID=44621&HTTP_REFERER=RSS" alt="" width="1" height="1" loading="eager">]]></content:encoded>
					
					<wfw:commentRss>https://shkspr.mobi/blog/2023/01/unicode-operators-for-semantically-correct-programming/feed/</wfw:commentRss>
			<slash:comments>29</slash:comments>
		
		
			</item>
		<item>
		<title><![CDATA[Book Review: The Programmer's Brain - What every programmer needs to know about cognition by Felienne Hermans ★★★★★]]></title>
		<link>https://shkspr.mobi/blog/2022/04/book-review-the-programmers-brain-what-every-programmer-needs-to-know-about-cognition-by-felienne-hermans/</link>
					<comments>https://shkspr.mobi/blog/2022/04/book-review-the-programmers-brain-what-every-programmer-needs-to-know-about-cognition-by-felienne-hermans/#comments</comments>
				<dc:creator><![CDATA[@edent]]></dc:creator>
		<pubDate>Sun, 03 Apr 2022 11:34:05 +0000</pubDate>
				<category><![CDATA[/etc/]]></category>
		<category><![CDATA[Book Review]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[programming]]></category>
		<guid isPermaLink="false">https://shkspr.mobi/blog/?p=42264</guid>

					<description><![CDATA[There are some books which make you feel smarter just by having them on your shelf. This is one of them! I would consider it essential for anyone working with code - whether a wide-eyed newbie or grizzled veteran.  How do human brains understand code? What neurological quirks do we all have? Which common mistakes can be easily avoided?  Only by understanding our puny hardware (&#34;Isn’t it a miracle …]]></description>
										<content:encoded><![CDATA[<p><img src="https://shkspr.mobi/blog/wp-content/uploads/2022/04/Hermans-HI.jpg" alt="Book cover for the Programmer's Brain." width="200" class="alignleft size-full wp-image-42289">There are some books which make you feel smarter just by having them on your shelf. This is one of them! I would consider it essential for anyone working with code - whether a wide-eyed newbie or grizzled veteran.</p>

<p>How do human brains understand code? What neurological quirks do we all have? Which common mistakes can be easily avoided?  Only by understanding our puny hardware ("Isn’t it a miracle that humans can do anything with no more than 1 byte of memory") can we understand how we should read, write, and <em>think</em> about code.</p>

<p>It is a relatively quick read - I burned through it on a 4 hour flight - but there are lots of practical exercises to do. And it is worth taking the time to think about <em>the process</em> of thinking about code.</p>

<p>Some of the insights are a little obvious - but it is worth spelling them out. For example:</p>

<blockquote><p>when debugging, many programmers prefer to make small changes to their code (tweaks) and run it again to see if the bug is fixed rather than spending the energy to create a good mental model of the problem</p></blockquote>

<p>It me! Why do I do that? Why do I think bashing around on a keyboard is more productive than taking 15 minutes to investigate my assumptions about what I'm trying to do - and what the previous programmer was trying to do?  The book has answers - and some practical guides for helping you correct your behaviour.</p>

<p>Even "simple" things like naming conventions get a thorough examination, with plenty of academic references:</p>

<blockquote><p>8.3.2 Snake case or camel case?
The results of Binkley’s study show that the use of camel case leads to higher accuracy among both programmers and non-programmers
8.4.1 Code with bad names has more bugs
Butler’s study found statistically significant associations between naming issues and code quality.</p></blockquote>

<p>There are lots of footnotes if you want to go wandering into the academic studies - and there are <em>many</em>.</p>

<p>The book - rightly - throws a bit of shade on those of us who have got into bad habits, but haven't reflected on whether they're actually working for us.</p>

<blockquote><p>11.2.5 Some thoughts on multitasking
The interesting thing is that people who multitask often <em>feel</em> very productive</p></blockquote>

<p>Ha! True. The book goes into the studies of why people feel the way they do - and whether the data bears out those feelings.</p>

<p>I urge you to read this book. If you are just getting started, it will help you develop good habits. If you're an occasional coder, it will keep you from straying. If you've been doing this for so long that your code is indecipherable to anyone else - it will give you a much-needed reality check.</p>

<p>The book is available <a href="https://www.manning.com/books/the-programmers-brain">DRM free from publisher</a> in PDF, ePub, and Mobi.  At about £25, it's probably worth charging it as a business expense.</p>

<p>Thanks to the publishers for the review copy.</p>
<img src="https://shkspr.mobi/blog/wp-content/themes/edent-wordpress-theme/info/okgo.php?ID=42264&HTTP_REFERER=RSS" alt="" width="1" height="1" loading="eager">]]></content:encoded>
					
					<wfw:commentRss>https://shkspr.mobi/blog/2022/04/book-review-the-programmers-brain-what-every-programmer-needs-to-know-about-cognition-by-felienne-hermans/feed/</wfw:commentRss>
			<slash:comments>7</slash:comments>
		
		
			</item>
		<item>
		<title><![CDATA[⩵ != ==]]></title>
		<link>https://shkspr.mobi/blog/2021/06/%e2%a9%b5/</link>
					<comments>https://shkspr.mobi/blog/2021/06/%e2%a9%b5/#comments</comments>
				<dc:creator><![CDATA[@edent]]></dc:creator>
		<pubDate>Mon, 07 Jun 2021 11:04:36 +0000</pubDate>
				<category><![CDATA[/etc/]]></category>
		<category><![CDATA[Computer Science]]></category>
		<category><![CDATA[computers]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[ui]]></category>
		<category><![CDATA[unicode]]></category>
		<guid isPermaLink="false">https://shkspr.mobi/blog/?p=39195</guid>

					<description><![CDATA[One of the frustrating things about computers is their limited input options. A &#34;standard&#34; PC keyboard only has about 100 keys.  Sure, some have some bonus buttons for controlling the machine, but it is becoming clear that there simply aren&#039;t enough buttons to efficiently program computers.  Most programming languages have the concept of relational operators. How does variable X compare to…]]></description>
										<content:encoded><![CDATA[<p>One of the frustrating things about computers is their limited input options. A "standard" PC keyboard only has about 100 keys.  Sure, some have some bonus buttons for controlling the machine, but it is becoming clear that there simply aren't enough buttons to efficiently program computers.</p>

<p>Most programming languages have the concept of relational operators. How does variable <code>X</code> compare to variable <code>Y</code>?</p>

<p>If we want to ask if <code>X</code> is less than or equal to <code>Y</code>, we write <code>X &lt;= Y</code>.  Which is a bit weird, because Unicode has a "less-than-or-equal-to" character: <code>≤</code>. But because there's no button for that on a standard keyboard, we use a hacky solution of jamming two characters together.</p>

<p>In the R language, the assignment operator is <code>&lt;-</code> this is <a href="https://colinfay.me/r-assignment/">because programming keyboards used to have a <code>←</code> button on them</a>. That button has gone from modern machines, so we make do and mend.</p>

<p>There are some <a href="https://betterwebtype.com/articles/2020/02/13/5-monospaced-fonts-with-cool-coding-ligatures/">programming fonts which contain ligatures to automatically convert these characters</a> (although <a href="https://practicaltypography.com/ligatures-in-programming-fonts-hell-no.html">this makes some people very grumpy</a>).</p>

<p>Unicode includes <code>⩶</code> (<code>U+2A76</code>) and <code>⩵</code> (<code>U+2A75</code>) as distinct glyphs. So why are we still hitting the <code>=</code> key multiple times like <em>savages?</em></p>

<p>This leads to the <em>deeply</em> weird situation where <code>"⩵" ≠ "=="</code> and absolutely no programming language that I know of will let you use the <strong>correct</strong> Unicode characters!</p>

<p>(Except, of course, <a href="https://github.com/rakudo/rakudo/pull/4392">Raku</a> - which made this change <a href="https://twitter.com/liztormato/status/1400781849169965065">based on my suggestion</a>.)</p>

<p>Ideally, we need programming languages which support Unicode symbols as first class characters, and keyboards with a hundred more buttons.</p>

<video muted="true" autoplay="true" loop="true">
 <source src="https://shkspr.mobi/blog/wp-content/uploads/2021/06/fingers.mp4" type="video/mp4">
</video>
<img src="https://shkspr.mobi/blog/wp-content/themes/edent-wordpress-theme/info/okgo.php?ID=39195&HTTP_REFERER=RSS" alt="" width="1" height="1" loading="eager">]]></content:encoded>
					
					<wfw:commentRss>https://shkspr.mobi/blog/2021/06/%e2%a9%b5/feed/</wfw:commentRss>
			<slash:comments>3</slash:comments>
		
		
			</item>
		<item>
		<title><![CDATA[Code Palindromes]]></title>
		<link>https://shkspr.mobi/blog/2021/04/code-palindromes/</link>
					<comments>https://shkspr.mobi/blog/2021/04/code-palindromes/#respond</comments>
				<dc:creator><![CDATA[@edent]]></dc:creator>
		<pubDate>Sun, 04 Apr 2021 11:26:13 +0000</pubDate>
				<category><![CDATA[/etc/]]></category>
		<category><![CDATA[binary]]></category>
		<category><![CDATA[programming]]></category>
		<guid isPermaLink="false">https://shkspr.mobi/blog/?p=38545</guid>

					<description><![CDATA[An idle thought on a long weekend. Is it possible to create an executable binary which is a palindrome?  It&#039;s trivial to create a palindromic program in, say, Python:  print(&#34;hello&#34;) # )&#34;olleh&#34;(tnirp   Save that as test.py and then run cat test.py &#124; rev &#124; python3 and it&#039;ll work. But that&#039;s boring!  You could do the same by reversing the bits, rather than the characters:  01110000 01110010…]]></description>
										<content:encoded><![CDATA[<p>An idle thought on a long weekend. Is it possible to create an executable binary which is a palindrome?</p>

<p>It's trivial to create a palindromic program in, say, Python:</p>

<pre><code class="language-python">print("hello") # )"olleh"(tnirp
</code></pre>

<p>Save that as <code>test.py</code> and then run <code>cat test.py | rev | python3</code> and it'll work. But that's boring!</p>

<p>You could do the same by reversing the bits, rather than the characters:</p>

<pre><code class="language-_">01110000 01110010 01101001 01101110 
01110100 00101000 00100010 01101000 
01100101 01101100 01101100 01101111 
00100010 00101001 00100000 00100011 
00000100 10010100 01000100 11110110 
00110110 00110110 10100110 00010110 
01000100 00010100 00101110 01110110 
10010110 01001110 00001110
</code></pre>

<p>That requires a bit more bit-bashing to run properly.  And, if I'm honest, I think padding stuff with reversed comments is cheating.</p>

<p>Is it possible to make an executable assembly program which can be read forwards and back?</p>

<blockquote class="social-embed" id="social-embed-1376838503489806337" lang="en" itemscope="" itemtype="https://schema.org/SocialMediaPosting"><header class="social-embed-header" itemprop="author" itemscope="" itemtype="https://schema.org/Person"><a href="https://twitter.com/regularfry" class="social-embed-user" itemprop="url"><img class="social-embed-avatar social-embed-avatar-circle" src="data:image/webp;base64,UklGRpQBAABXRUJQVlA4IIgBAACQCQCdASowADAAPrVInUqnJCKhrjgMyOAWiWMAtRwEAbzco/XKIFl+OTDnh2qF3M9i1/ke69OohrUqswE7xeUncIUeM3P9pxpKOLfNvtxPPffABWwAAP7sOo/NI4mgtRrUIl34EeB87vA0vE/B2u+Zm2D65DKoR1Sjom6kvdxH9jnU6s+cox7CMvbw0yhXJSfHLuuqYIZpt7RKiDPHbD9LgrdnpKNPxJ8zCXykuQI7W6cEWVL0bZ2NALgImyqtcEh9crTOQghzIYyMBNk97g/kLnas2rzuwdMeqNSyaGDeNmPfBvxeMGZ2rijVbKWsDqUxoYIpR7UJ9ASS4TpuQ9DrZg2kZVaamioAKNf+7J6gkcLCZ7eS02BrT1QIOSdc71NHgquGt8ayJH1MS377+Mn0jD149tL4zsfz5uAFzKrxzSgEBI93p9UZGkKDmUlc9yLc89YQPgzFdi7fYBKde1Wzo7gGSDxJQ+VVi8ox3CvBYXpUdxFk5i7tR8CCkTC77WjTMJaa6AAAAA==" alt="" itemprop="image"><div class="social-embed-user-names"><p class="social-embed-user-names-name" itemprop="name">Alex @regularfry@mastodon.social Young</p>@regularfry</div></a><img class="social-embed-logo" alt="" src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciCmFyaWEtbGFiZWw9IlR3aXR0ZXIiIHJvbGU9ImltZyIKdmlld0JveD0iMCAwIDUxMiA1MTIiPjxwYXRoCmQ9Im0wIDBINTEyVjUxMkgwIgpmaWxsPSIjZmZmIi8+PHBhdGggZmlsbD0iIzFkOWJmMCIgZD0ibTQ1OCAxNDBxLTIzIDEwLTQ1IDEyIDI1LTE1IDM0LTQzLTI0IDE0LTUwIDE5YTc5IDc5IDAgMDAtMTM1IDcycS0xMDEtNy0xNjMtODNhODAgODAgMCAwMDI0IDEwNnEtMTcgMC0zNi0xMHMtMyA2MiA2NCA3OXEtMTkgNS0zNiAxczE1IDUzIDc0IDU1cS01MCA0MC0xMTcgMzNhMjI0IDIyNCAwIDAwMzQ2LTIwMHEyMy0xNiA0MC00MSIvPjwvc3ZnPg=="></header><section class="social-embed-text" itemprop="articleBody"><small class="social-embed-reply"><a href="https://twitter.com/edent/status/1376817404936916994">Replying to @edent</a></small><a href="https://twitter.com/edent">@edent</a> Related question: are there any paper tape programs which are valid when taped end-to-end as a mobius loop?</section><hr class="social-embed-hr"><footer class="social-embed-footer"><a href="https://web.archive.org/web/20210330100742/https://twitter.com/regularfry/status/1376838503489806337"><time datetime="2021-03-30T10:07:34.000Z" itemprop="datePublished">10:07 - Tue 30 March 2021</time></a></footer></blockquote>
<img src="https://shkspr.mobi/blog/wp-content/themes/edent-wordpress-theme/info/okgo.php?ID=38545&HTTP_REFERER=RSS" alt="" width="1" height="1" loading="eager">]]></content:encoded>
					
					<wfw:commentRss>https://shkspr.mobi/blog/2021/04/code-palindromes/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title><![CDATA[Goodbye avatars .io - hello unavatar!]]></title>
		<link>https://shkspr.mobi/blog/2020/07/goodbye-avatars-io-hello-unavatar/</link>
					<comments>https://shkspr.mobi/blog/2020/07/goodbye-avatars-io-hello-unavatar/#comments</comments>
				<dc:creator><![CDATA[@edent]]></dc:creator>
		<pubDate>Fri, 03 Jul 2020 11:43:30 +0000</pubDate>
				<category><![CDATA[/etc/]]></category>
		<category><![CDATA[avatar]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[programming]]></category>
		<guid isPermaLink="false">https://shkspr.mobi/blog/?p=35489</guid>

					<description><![CDATA[Given a social media user&#039;s username, how do you get a picture of their avatar?  I always used avatars.io - but sadly that service has bitten the dust. So I&#039;ve switched to unavatar.  It&#039;s dead easy to use.  https://unavatar.now.sh/twitter/edent will return @edent&#039;s avatar.  You can use GitHub, Facebook, Gravatar, Instagram, Telegram, YouTube, SoundCloud, and a couple of other providers.  Simple…]]></description>
										<content:encoded><![CDATA[<p>Given a social media user's username, how do you get a picture of their avatar?</p>

<p>I always used avatars.io - but sadly that service has bitten the dust. So I've switched to <a href="https://github.com/microlinkhq/unavatar">unavatar</a>.</p>

<p>It's dead easy to use.  <a href="https://unavatar.now.sh/twitter/edent"><code>https://unavatar.now.sh/twitter/edent</code></a> will return @edent's avatar.  You can use GitHub, Facebook, Gravatar, Instagram, Telegram, YouTube, SoundCloud, and a couple of other providers.</p>

<p>Simple to use, and easy to embed in an <code>&lt;img&gt;</code> element.</p>

<p>It's also <a href="https://github.com/Kikobeats/unavatar">open source</a> and looks pretty easy to deploy if you want to host it yourself.</p>

<h2 id="why-is-this-needed"><a href="https://shkspr.mobi/blog/2020/07/goodbye-avatars-io-hello-unavatar/#why-is-this-needed">Why is this needed?</a></h2>

<p>In an ideal world, there would be a standard for where to find a user's avatar. Possibly a <a href="https://tools.ietf.org/html/rfc8615"><code>.well-known</code></a> resource. Until then, we have to make do with 3rd party services playing intermediary.</p>
<img src="https://shkspr.mobi/blog/wp-content/themes/edent-wordpress-theme/info/okgo.php?ID=35489&HTTP_REFERER=RSS" alt="" width="1" height="1" loading="eager">]]></content:encoded>
					
					<wfw:commentRss>https://shkspr.mobi/blog/2020/07/goodbye-avatars-io-hello-unavatar/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title><![CDATA[Programming Languages - look how far we've come!]]></title>
		<link>https://shkspr.mobi/blog/2020/03/programming-languages-look-how-far-weve-come/</link>
					<comments>https://shkspr.mobi/blog/2020/03/programming-languages-look-how-far-weve-come/#respond</comments>
				<dc:creator><![CDATA[@edent]]></dc:creator>
		<pubDate>Thu, 19 Mar 2020 12:09:44 +0000</pubDate>
				<category><![CDATA[/etc/]]></category>
		<category><![CDATA[Computer Science]]></category>
		<category><![CDATA[programming]]></category>
		<guid isPermaLink="false">https://shkspr.mobi/blog/?p=34463</guid>

					<description><![CDATA[Back in the 1980s, when my family first got a micro-computer, there were only limited ways to program your machine.  The Internet was basically non-existent for domestic users. You could buy thick computer manuals, swap cassettes with other enthusiasts, or build a light pen and point it at a flashing square on your TV (Really!)  Or, you could go down to your local newsagent, buy a magazine, and…]]></description>
										<content:encoded><![CDATA[<p>Back in the 1980s, when my family first got a micro-computer, there were only limited ways to program your machine.  The Internet was basically non-existent for domestic users. You could buy thick computer manuals, swap cassettes with other enthusiasts, or <a href="https://web.archive.org/web/20230123012906/https://www.youtube.com/watch?v=wKmu68URUeI">build a light pen and point it at a flashing square on your TV</a> (Really!)</p>

<p>Or, you could go down to your local newsagent, buy a magazine, and laboriously hand-type in a code listing.  Sometimes, they would look like this:</p>

<img src="https://shkspr.mobi/blog/wp-content/uploads/2018/10/Machine-Code.jpg" alt="Dense blocks of Machine Code printed in a magazine." width="464" height="648" class="aligncenter size-full wp-image-30523">

<p>Yikes! Ah, but they were simpler days...</p>

<p>I recently rediscovered <a href="https://archive.org/details/Input_Vol_3_No_28_1997_Marshall_Cavendish_GB/mode/2up">an old issue of a British microcomputer magazine called "Input"</a>. It contained code listings for several popular machines.  Here's a sample:</p>

<img src="https://shkspr.mobi/blog/wp-content/uploads/2020/03/Code-Listing-in-a-Magazine.jpg" alt="Code Listing in a Magazine." width="600" height="795" class="aligncenter size-full wp-image-34464">

<p>See those little icons beside each code listing? Here's what they meant:</p>

<img src="https://shkspr.mobi/blog/wp-content/uploads/2020/03/List-of-computers.jpg" alt="List of computers." width="539" height="438" class="aligncenter size-full wp-image-34465">

<p>Thirteen different computers with seven different programming languages. They share some common syntax, but not much. The commands are terse and unintuitive.  But are things any better today?</p>

<p>A properly written Python3 program will run on Windows, Mac, and Linux - whether it's an expensive desktop or a pocket-money Raspberry Pi.</p>

<p>Or you can write in Go, Java, PHP, Haskell, Ruby, JavaScript - and many others that I'm not cool enough to know.</p>

<p>I know <a href="https://shkspr.mobi/blog/2020/01/why-do-we-have-different-programming-languages/"><em>why</em> we have different programming languages</a> - but it sometimes seems that we're making life unnecessarily  hard for ourselves.</p>
<img src="https://shkspr.mobi/blog/wp-content/themes/edent-wordpress-theme/info/okgo.php?ID=34463&HTTP_REFERER=RSS" alt="" width="1" height="1" loading="eager">]]></content:encoded>
					
					<wfw:commentRss>https://shkspr.mobi/blog/2020/03/programming-languages-look-how-far-weve-come/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title><![CDATA[Why do we have different programming languages?]]></title>
		<link>https://shkspr.mobi/blog/2020/01/why-do-we-have-different-programming-languages/</link>
					<comments>https://shkspr.mobi/blog/2020/01/why-do-we-have-different-programming-languages/#comments</comments>
				<dc:creator><![CDATA[@edent]]></dc:creator>
		<pubDate>Mon, 06 Jan 2020 12:55:15 +0000</pubDate>
				<category><![CDATA[/etc/]]></category>
		<category><![CDATA[Computer Science]]></category>
		<category><![CDATA[programming]]></category>
		<guid isPermaLink="false">https://shkspr.mobi/blog/?p=33482</guid>

					<description><![CDATA[I made a little girl cry recently.  &#34;But why do I have to learn Python?&#34; She wailed, &#34;I like Scratch!&#34;  &#34;I know,&#34; I said, &#34;But there are different programming languages for different sorts of tasks.&#34;  &#34;That&#039;s stupid&#34; she said, with all the perception of 6 weeks Code Club experience. &#34;You can do everything in Scratch.&#34;  I found it hard to argue with the twelve-year-old - you can do just about…]]></description>
										<content:encoded><![CDATA[<p>I made a little girl cry recently.</p>

<p>"But <em>why</em> do I have to learn Python?" She wailed, "I <em>like</em> Scratch!"</p>

<p>"I know," I said, "But there are different programming languages for different sorts of tasks."</p>

<p>"That's <em>stupid</em>" she said, with all the perception of 6 weeks Code Club experience. "You can do <em>everything</em> in Scratch."</p>

<p>I found it hard to argue with the twelve-year-old - you can do just about anything with the child-friendly Scratch programming language. You can even <a href="https://en.scratch-wiki.info/wiki/Operating_System">build an entire Operating System</a>.</p>

<p>Here are some analogies, of increasing complexity, to try and describe to a non-technical person why we have different coding languages.</p>

<h2 id="the-orchestra"><a href="https://shkspr.mobi/blog/2020/01/why-do-we-have-different-programming-languages/#the-orchestra">The Orchestra</a></h2>

<p>A guitar and a violin are both stringed instruments, but they make very different noises.</p>

<p>You can hit a guitar with a drum stick, but playing a drum kit is easier and produces a wider range of percussion sounds.</p>

<p>Sometimes, you just want to do one thing and do it well. Playing the Triangle gives you one sound, consistently.</p>

<p>You can, of course, use a synthesiser to play more-or-less any instrument. But synthesisers require you to play everything on a keyboard, and they are complex instruments to understand and learn.</p>

<p>Different programming languages are usually specialised to particular tasks.  Sure, you can <a href="https://chandoo.org/forum/threads/3d-maze-in-excel.12055/">build a 3D adventure game in Excel</a>, but it is easier to use the right tool for the job.</p>

<h2 id="we-learn-and-evolve"><a href="https://shkspr.mobi/blog/2020/01/why-do-we-have-different-programming-languages/#we-learn-and-evolve">We learn and evolve</a></h2>

<p>In 1934, a young Alfred Hitchcock released "The Man Who Knew Too Much". A tense thriller which opened to worldwide acclaim. In 1956 he remade it.</p>

<p>The newer version doesn't just have a more technically advanced production - Technicolor! Hi-Fi sound! Widescreen! - it has 20 years more film-making experience behind it.</p>

<p>The same is true of programming languages. As we learn what computers can and can't do - and how humans like to work with them - we build new languages to take advantage of that knowledge.</p>

<h2 id="mans-monstrous-ego"><a href="https://shkspr.mobi/blog/2020/01/why-do-we-have-different-programming-languages/#mans-monstrous-ego">Man's monstrous ego</a></h2>

<p>Some people just want to create something in their own image.  Someone, somewhere, didn't like the way one programming language handled certain features - so they split and created a new language.</p>

<p>A cult can develop around a charismatic leader. Entire conferences can be dedicated to obscure languages which attract acolytes.  Each convinced they've found the "one true way" to program - and that everyone else is heretic scum.</p>

<p>Humans, eh?!</p>

<h2 id="a-counterpoint"><a href="https://shkspr.mobi/blog/2020/01/why-do-we-have-different-programming-languages/#a-counterpoint">A counterpoint</a></h2>

<p>But, you don't always need to use the right tool for the job.</p>

<p>My favourite example of this is colour recovery from black-and-white TV broadcasts. How would you take a B&amp;W film and <em>recover</em> the colour information from it? Not artificially add realistic colours.</p>

<p>Perhaps you'd use OpenCV? Experimental C++ bindings? Write some AI tool to burn through parallel GPUs?</p>

<p>Nope. A dedicated team built an accurate program <a href="https://stardot.org.uk/forums/viewtopic.php?t=16161">in 3,400 lines of BASIC</a>!</p>

<h2 id="because-the-world-is-round"><a href="https://shkspr.mobi/blog/2020/01/why-do-we-have-different-programming-languages/#because-the-world-is-round">Because the world is round</a></h2>

<p>Is poetry more romantic in French?  Is Shakespeare best performed <a href="https://www.shakespeare.org.uk/explore-shakespeare/blogs/shakespeare-klingon/">in the original Klingon</a>? Is demon summoning most effective in ancient Latin or Sumerian?</p>

<p>Some of these are a matter of taste. Some are just what we are used to. And some are just tradition.</p>

<p>Computer languages are an abstraction. We don't want to deal with the messy business of flinging electrons around circuit boards.  Different people have different preferences for how they like to code.</p>

<p>Perhaps, once everyone has finished rewriting their websites in flavour-of-the-month JavaScript frameworks, we'll see a renaissance in hand-crafted bits and bytes.</p>

<p>Or, just perhaps, the next generation <em>will</em> rewrite everything in Scratch!</p>
<img src="https://shkspr.mobi/blog/wp-content/themes/edent-wordpress-theme/info/okgo.php?ID=33482&HTTP_REFERER=RSS" alt="" width="1" height="1" loading="eager">]]></content:encoded>
					
					<wfw:commentRss>https://shkspr.mobi/blog/2020/01/why-do-we-have-different-programming-languages/feed/</wfw:commentRss>
			<slash:comments>6</slash:comments>
		
		
			</item>
		<item>
		<title><![CDATA[Falsehoods programmers believe about flags]]></title>
		<link>https://shkspr.mobi/blog/2019/06/falsehoods-programmers-believe-about-flags/</link>
					<comments>https://shkspr.mobi/blog/2019/06/falsehoods-programmers-believe-about-flags/#comments</comments>
				<dc:creator><![CDATA[@edent]]></dc:creator>
		<pubDate>Sat, 01 Jun 2019 11:04:50 +0000</pubDate>
				<category><![CDATA[/etc/]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[falsehoods]]></category>
		<category><![CDATA[flags]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[usability]]></category>
		<guid isPermaLink="false">https://shkspr.mobi/blog/?p=32239</guid>

					<description><![CDATA[(For more about the &#34;Falsehoods&#34; meme - read the big list of falsehoods programmers believe.)  Do You Want To Phone A Friend?  A popular website asked me to confirm my phone number.  It &#34;helpfully&#34; pre-filled the country-code with +1.  And proudly displayed the Stars and Stripes.    Except, of course, the USA isn&#039;t the only country to use +1 - our friends in the Great White North also use +1.   …]]></description>
										<content:encoded><![CDATA[<p>(For more about the "Falsehoods" meme - read the <a href="https://github.com/kdeldycke/awesome-falsehood">big list of falsehoods programmers believe</a>.)</p>

<h2 id="do-you-want-to-phone-a-friend"><a href="https://shkspr.mobi/blog/2019/06/falsehoods-programmers-believe-about-flags/#do-you-want-to-phone-a-friend">Do You Want To Phone A Friend?</a></h2>

<p>A popular website asked me to confirm my phone number.  It "helpfully" pre-filled the country-code with <code>+1</code>.  And proudly displayed the Stars and Stripes.</p>

<img src="https://shkspr.mobi/blog/wp-content/uploads/2019/05/USA-Flag.png" alt="A dropdown box showing the flag of the USA next to a plus 1." width="683" height="285" class="aligncenter size-full wp-image-32241">

<p>Except, of course, the USA isn't the only country to use <code>+1</code> - our friends in the Great White North also use <code>+1</code>.</p>

<img src="https://shkspr.mobi/blog/wp-content/uploads/2019/05/Canada-Flag.png" alt="A dropdown box showing the flag of Canada next to a plus 1." width="683" height="285" class="aligncenter size-full wp-image-32240">

<p>Thanks to the <a href="https://en.wikipedia.org/wiki/North_American_Numbering_Plan">North American Numbering Plan</a>, a full 25 countries or territories use <code>+1</code>.  From  Anguilla 🇦🇮 to Turks and Caicos Islands 🇹🇨.  OK… their flags look pretty similar! But they're obviously different from 🇺🇸!</p>

<p>Canada 🇨🇦 and Jamaica 🇯🇲 have very different flags - and climates - but they both use <code>+1</code>.</p>

<p>I <em>suspect</em> that the website designers were expecting people to look at the flag and realise that it didn't represent their home country, and then change it.  However, for the majority of <code>+1</code> countries which aren't part of the United States, it looks a little crass.</p>

<p>My home country, the United Kingdom 🇬🇧, uses the <code>+44</code> code. As do Guernsey 🇬🇬, Jersey 🇯🇪, and the Isle of Man 🇮🇲.</p>

<p>The UK is comprised of Scotland 🏴󠁧󠁢󠁳󠁣󠁴󠁿, England 🏴󠁧󠁢󠁥󠁮󠁧󠁿, Wales 🏴󠁧󠁢󠁷󠁬󠁳󠁿, and N.I. (with a more <a href="https://en.wikipedia.org/wiki/Flag_of_Northern_Ireland">complicated flag status</a>!)</p>

<p>People can have a complicated relationship with flags. Your glorious banner of home might be my symbol of a conquering despot.</p>

<p>Flags change. <a href="https://en.wikipedia.org/wiki/Flag_of_Afghanistan#Historical_flags">Afghanistan's</a> flag has changed 4 times since the year 2000.</p>

<p>Some <a href="https://commons.wikimedia.org/wiki/Flags_of_unrecognized_states">flags are not recognised</a> by other countries.</p>

<p>Flags represent countries, states, territories, and pirate ships 🏴‍☠️ - but they do not represent international dialling codes!</p>

<h2 id="lingua-franca"><a href="https://shkspr.mobi/blog/2019/06/falsehoods-programmers-believe-about-flags/#lingua-franca">Lingua Franca</a></h2>

<p>Lots of countries speak English. But the majority of them don't have 🇬🇧 as their flag.</p>

<p>Indeed, lots of people in the UK don't speak English. So using a 🇬🇧 to indicate language choice may be confusing.</p>

<p>If you are in South Africa, there are <a href="https://southcoastherald.co.za/242725/what-are-the-11-official-languages-of-south-africa-how-many-do-you-know-2/">11 official languages</a>. Does 🇿🇦 represent Xhosa, Zulu, Afrikaans, English…?</p>

<p>Flags are for golf courses ⛳, motor-sports 🏁, and for Pride 🏳️‍🌈 - not for representing languages.</p>

<h2 id="do-you-have-a-flag"><a href="https://shkspr.mobi/blog/2019/06/falsehoods-programmers-believe-about-flags/#do-you-have-a-flag">Do You Have A Flag</a></h2>

<p>I'm pretty sure the law requires me to share this video…</p>

<iframe title="Eddie Izzard &quot;Do You Have a Flag?&quot; Sketch From &quot;Dress to Kill&quot;" width="620" height="465" src="https://www.youtube.com/embed/_9W1zTEuKLY?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen=""></iframe>
<img src="https://shkspr.mobi/blog/wp-content/themes/edent-wordpress-theme/info/okgo.php?ID=32239&HTTP_REFERER=RSS" alt="" width="1" height="1" loading="eager">]]></content:encoded>
					
					<wfw:commentRss>https://shkspr.mobi/blog/2019/06/falsehoods-programmers-believe-about-flags/feed/</wfw:commentRss>
			<slash:comments>3</slash:comments>
		
		
			</item>
	</channel>
</rss>
