<feed xmlns="http://www.w3.org/2005/Atom"><title>LPAR</title><link href="https://lpar.ATH0.com/index.xml" rel="self"/><link href="https://lpar.ATH0.com/"/><updated>2026-08-15T14:12:11-05:00</updated><id>https://lpar.ATH0.com/</id><author><name>mathew</name><email>meta@pobox.com</email></author><generator>Hugo -- gohugo.io</generator><entry><title type="html">The unknown unknowns</title><link href="https://lpar.ATH0.com/posts/2026/08/the-unknown-unknowns/"/><id>https://lpar.ATH0.com/posts/2026/08/the-unknown-unknowns/</id><published>2026-08-15T14:12:11-05:00</published><updated>2026-08-15T14:12:11-05:00</updated><summary>A fundamental problem with LLM chatbots that I think deserves greater attention.</summary><content type="html"><![CDATA[<p>There’s a problem with use of generative AI chatbots that I think isn’t getting enough attention.</p>
<p>Recently I saw someone had posted an issue against an open source project, saying that the maintainer’s use of generative AI to create code could lead to intellectual property issues. The maintainer did what you might expect — they asked their favorite cutting-edge AI chatbot for a summary of the situation.</p>
<p>I’m not going to name the project. I don’t want to be responsible for brigading, because this is happening <em>everywhere</em>. The identity of the project and maintainer also aren’t relevant to the point I’m about to make. It’s not even about software, particularly, that’s just the example I happened to see.</p>
<p>Anyway, the bot did what LLM bots do — it produced random text that looked statistically like a response to the question asked. It did this based on statistical analysis of text of the most common responses to similar questions found in its training set. The result looked very convincing. It said that work partially generated by AI can be protected by copyright if there is sufficient human input.</p>
<p>Unfortunately, it missed a critical detail. The US copyright office guidance is that you <em>must</em> state which parts of the work were AI generated, and explicitly exclude those from any copyright claim.</p>
<p>Quoting <em>Copyright Registration Guidance: Works Containing Material Generated by Artificial Intelligence</em>:</p>
<blockquote>
<p>Individuals who use AI technology in creating a work may claim copyright protection
for their own contributions to that work. They must use the Standard Application,
and in it identify the author(s) and provide a brief statement in the “Author Created”
field that describes the authorship that was contributed by a human.
[…]
AI-generated content that is more than <em>de minimis</em> should be explicitly excluded from the
[copyright] application.</p>
</blockquote>
<p>I’ve not seen any projects actually do this. They all seem to be trying to slap a blanket copyright license over everything, even AI-generated material that can’t be copyrighted. This is not a new problem, and not specific to software — companies have issued DVDs of out-of-copyright movies and tried to claim copyright on them; same with books.</p>
<p>Anyway, going back to the bot’s generated output, there’s no real mystery why this omission occurred. AI proponents are generally either unaware of the US Copyright Office position, or choose not to mention it because it’s inconvenient to them. Hence the bot’s training data either didn’t mention it anywhere, or mentioned it very rarely. Hence the bot’s output, which is based on picking the most probabilistically likely output for the given input, didn’t mention it.</p>
<hr>
<p>Back when I was at school we were taught how to summarize a piece of text. The first step is to read through the text carefully, and note which details <em>must</em> be included in the summary. This typically requires some domain knowledge, or at least everyday experience of the real world. In business, you need to know the target audience, and understand what they will need (and want) to know. These are not generally things that can be derived using pure probabilistic analysis; you need to understand the text, and need a mental model of the audience. I’ve seen it said that <a href="https://ea.rna.nl/2024/05/27/when-chatgpt-summarises-it-actually-does-nothing-of-the-kind/">LLMs don’t actually summarize text, they make it shorter</a>, and those are different things.</p>
<p>I do actually use the “summarize” feature of Apple Intelligence. When I bookmark something, I’ll take the text of the page and “summarize” into a short paragraph or two. This is good enough to help me find the bookmark again when I search, but I’m under no illusion that it actually represents the content accurately. (Pre-LLM summarization algorithms were no better in this respect.)</p>
<p>I also use local neural network models for image recognition, to produce short descriptions for my photos to help me find them again. Again, the output can be pretty inaccurate, but it doesn’t matter too much; it just needs to include enough of the words I’m likely to use when searching.</p>
<hr>
<p>I think we’re getting to the point where most people are aware that AI chatbots sometimes produce text that looks plausible, but is not in agreement with reality. Those who enthusiastically use AI will tell you that it’s OK, because they check the output. I don’t believe them, but let’s imagine they do. The problem is this: you can check the output for errors, but you can’t check for things that are missing unless you basically already know what the output should be. And if you know that, what’s the point of asking the AI for the answer?</p>
<p>As Donald Rumsfeld might have put it, the problem is the unknown unknowns. It doesn’t help if the bot provides exact citations for where it found the information, and it doesn’t help if you diligently check those citations. If the bot omits something entirely, you won’t know. It’s like the joke “Everyone who couldn’t make it to the meeting, please raise your hand”.</p>
<p>This issue of missing data in AI output is a problem for summaries of contracts and other legal documents. It’s a problem for AI analysis of email, documentation, scientific data, basically anything where you’re asking a bot for a non-trivial answer to a question you don’t already know the answer to.</p>
<p>It also doesn’t seem to me to be something that can be fixed using LLM technology. There are always going to be places where the training data doesn’t repeatedly emphasize something that a human would pick up on as being very important. This is particularly true when the subject matter has undergone a lot of changes in recent years.</p>
<p>So if you need an accurate answer, you’re going to have to ask a knowledgeable human. Or, you know, actually read some source material. Just checking the accuracy of a chatbot’s output doesn’t avoid the problem of incorrect answers.</p>
]]></content></entry><entry><title type="html">The problem factory</title><link href="https://lpar.ATH0.com/posts/2026/07/the-problem-factory/"/><id>https://lpar.ATH0.com/posts/2026/07/the-problem-factory/</id><published>2026-07-29T19:15:42-05:00</published><updated>2026-07-29T19:15:42-05:00</updated><summary>The tech industry has been failing to deal with a fundamental issue for decades.</summary><content type="html"><![CDATA[<p><em>Foreword: I’ve tried to make sure the numbers below are correct. However, if I (say) miscounted the number of instructions in the Z80 instruction set, please don’t feel obliged to let me know, as the precise numbers aren’t the point.</em></p>
<hr>
<p>A lot of people are talking about whether we should use generative AI to generate code. I want to talk about the valid reasons why people want to use it in the first place, because I see generative AI use as primarily a symptom of a much deeper problem.</p>
<h2 id="making-the-easy-things-hard">Making the easy things hard</h2>
<p>People often say that yes, genAI is bad for all the reasons you’ve already heard, but it’s good for generating tedious boilerplate.</p>
<p>As someone who spent years writing Java, I’m certainly familiar with what tedious boilerplate looks like. Once you need to (say) access a database, things get ugly quickly. That’s why the pain of writing SQL plus JDBC wrapper code led to the creation of the Java Persistence API. JPA lets you avoid SQL entirely, and fetch data from the database in a typesafe way. Assuming you have the dependencies set up in Maven via a few dozen lines of XML, you can create a <code>Session</code> from a <code>SessionFactory</code>, create a <code>CriteriaBuilder</code> for the session, create a <code>CriteriaQuery</code> from that, create <code>Expression</code> objects from the criteria builder, apply them to the query, pass that to the session, and get the list of results. Repeat for every database-querying function. And that’s why people want to use LLMs.</p>
<p>All the library code doesn’t come for free, of course. A few years ago I tried building a “hello world” web application in Jakarta EE using the lightest available application server, and it needed 160 MiB of RAM to run. You’re probably thinking 160 MiB is nothing, and that’s a problem too — our ideas of what is a reasonable amount of resource usage are in need of adjustment now that disk space and RAM are no longer cheap.</p>
<p>The semantic complexity of modern programming languages themselves is also an issue. A couple of decades ago I saw an estimate that it takes 5 years to become a proficient C++ developer, and I expect it’s significantly harder now. While it’s an imperfect measure of complexity, the latest C++ standard has 92 keywords and 34 operators, and the actual language standard is a document with 1,853 pages. Meanwhile, JavaScript has fewer keywords at 46, but 44 operators, and the behavior encoded is so complex that <a href="https://github.com/denysdovhan/wtfjs">it has become a running joke</a>. Its standard is about as many pages as C, around 800.</p>
<p>New languages aren’t necessarily any better; Rust seems to be aimed at people who think C++ is great apart from the lack of memory safety, and it has <a href="https://doc.rust-lang.org/book/appendix-02-operators.html">56 operators</a> and at least half a dozen types of string. Is it any surprise that the Rust community loves using chatbots to deal with all that syntax and the corresponding semantics?</p>
<p>Yet in spite of modern programming languages being packed with features, conceptually trivial tasks can require ludicrous amounts of code. Consider <a href="https://whitep4nth3r.com/blog/how-to-format-dates-for-rss-feeds-rfc-822/#using-javascript-to-build-an-rfc-822-date">formatting a date in RFC2822 format in JavaScript</a>, for example. This leads to projects relying on libraries to ease the pain, and those libraries rely on libraries to ease their pain, and before long you have a trivial JavaScript web application with <a href="https://blog.appsignal.com/2020/05/14/javascript-growing-pains-from-0-to-13000-dependencies.html">over 13,000 dependencies</a>.</p>
<p>Very few programming languages make any attempt to avoid complexity; in fact, the trend is generally in the opposite direction.  I used to write Perl code to solve problems in a quick and dirty fashion, but I was never really completely happy with it. Then Larry Wall announced that Perl 6 was going to happen, and I thought at last it would be a chance to clean things up. Maybe we could have one way to define objects rather than 4 different OO options in CPAN? Then I saw an early version of the <a href="https://www.ozonehouse.com/mark/periodic/">Periodic Table of the Operators</a> for Perl 6, and realized nothing was going to improve. I ran away to Ruby, where everything is an object, there’s one syntax for defining objects, and operators are just optional syntactic sugar for methods.</p>
<p>It’s difficult to avoid having your programming language get complex. People get angry at the Go team because of the simplicity of the language. Why doesn’t it have optionals and unions? Where’s the macro preprocessor? Can we add checked exceptions? Why can’t we control exactly when the GC runs? Can’t the compiler just infer argument types? It must be tempting to just add everything people ask for so that they’ll stop complaining, but if you do that then you end up with C++ again.</p>
<p>Features should not be a goal when developing a programming language. Making it able to solve problems should be the goal. Adding features is a necessary evil towards that goal. But egotistical developers love complex programming languages where they can show off how clever they are, so there’s always a community out there requesting more features.</p>
<p>Code is also not the goal of programming. Generally the less code the better, as every line of code is an opportunity for a bug to hide. The best commits are the ones that remove code, and the ideal amount of code is no code at all. Code quantity should be reduced down to the point at which it starts to become unclear or fails to solve the problem.</p>
<p>Kotlin is an example of a language I initially liked but moved away from. It has one killer feature — it solves Java’s <code>NullPointerException</code> problem. Unfortunately I found myself writing clever and terse code, rather than clear code. Writing clever code is certainly fun; there’s definitely something satisfying about packing the largest amount of computation into the smallest possible amount of code. It’s a logic puzzle, a game. It’s also terrible for code maintainability. But verbosity is bad too; those years writing Java taught me that. A <code>final</code> cluttering every method parameter, repeated catching and throwing of exceptions, <code>String</code> and <code>StringBuffer</code> conversions everywhere.</p>
<p>What is needed is code <em>simplicity</em>. That’s not the same as conciseness, and I don’t think anyone has really worked out how to measure it. It’s an instinct you get with years of programming — I hope. Reviewing code, I had a rule of thumb that if I had to look at a few lines of code for more than about 10 seconds, the code wasn’t clear and simple enough. How would I automate that? I’ve no idea.</p>
<h2 id="works-for-me">Works for me</h2>
<p>Once you’ve written your software, you have to worry about distributing it. With so many dependencies and so many components, for a lot of projects it’s no longer a matter of sending out a zip file. It doesn’t work? Well, it works on my machine, so I’ll just ship you the software setup from my machine in a container. Installation is a nightmare? I’ll ship it preinstalled in a container. It needs a database? Another container.</p>
<p>Seems like a win, except that studies suggest <a href="https://www.techmonitor.ai/technology/cybersecurity/software-container-vulnerabilities-study">the average container contains code with over 600 known vulnerabilities</a>, with nearly half of them being in code that’s more than 2 years old. Containers are basically collateralized technical debt obligations. And now you need a container manager to run the software in the containers, and maybe an orchestrator to make sure they run at the right times and connect to each other properly.</p>
<p>Or you could use a cloud platform to run the containers. AWS offers over 500 different services, so there are definitely ones that will help you run your application. Or there’s Azure, which has a few more. Naturally both of them have AI bots to help you work out what on earth is going on.</p>
<h2 id="doing-what-i-want">Doing what I want</h2>
<p>Another reason people give for using GenAI, specifically for “vibe coding”, is that it lets them develop custom software for their own use — either personal use, or in their business.</p>
<p>Once upon a time we had deterministic tools for that. In the 8 bit era when you switched the computer on it typically dropped into BASIC in under a second. BASIC wasn’t a great programming language, but it was good enough that many people wrote their own <a href="https://www.gamedeveloper.com/game-platforms/commodore-64-kept-running-for-25-years----in-a-polish-auto-shop">bespoke business software</a> — not to mention utilities and games. If you wanted to draw something on the screen, typically it was a handful of lines:</p>
<pre tabindex="0"><code>10 MODE 2
20 MOVE 200,100:DRAW 300,200:DRAW 100,200:PLOT 85,200,100
</code></pre><p>Now you have a square. Compare that with <a href="https://www.dgp.toronto.edu/~ah/csc418/fall_1999/tut/square">OpenGL</a> as found at the start of the 2000s.</p>
<p>Later in the 80s we moved to 16 bit computers, then 32 bit. HyperCard let Mac users build their own mini databases, games, utilities and interactive systems mostly visually, by dragging and dropping text fields, buttons and other controls. In the 90s, Visual BASIC let Windows users do a lot of the same things. Meanwhile, Lotus Notes would let businesses build secure groupware by pasting controls on a page, and the result would feature digital signatures and encryption. You could build custom applications for your use in an afternoon. Sure, the results could be pretty ugly, but they worked, and were good enough — just like modern LLM-generated applications.</p>
<p>And now? Apple estimates that it takes <a href="https://developer.apple.com/tutorials/app-dev-training">over 16 hours</a> to learn the basics of developing an application using Xcode. On the way you’ll need to learn about state management, events and lifecycles, and navigation hierarchies. Yes, you can get a lot further with Xcode than with BASIC, but most people aren’t going to spend half a dozen hours getting to “Hello, world”. They’ll give up before they get to the complex stuff.</p>
<p>To quote Alan Kay, “Simple things should be simple, complex things should be possible.” We seem to have lost the first part of that principle.</p>
<h2 id="the-bug-factory">The bug factory</h2>
<p>With projects built using languages as complex as C++ and JavaScript, with hundreds (or even thousands) of dependencies, the shape of <a href="https://www.cvefind.com/en/cve-statistic-date.html">the graph of CVEs by year</a> isn’t a huge surprise.</p>
<p>A lot of CVEs aren’t remotely exploitable, and there’s significant CVSS inflation with reporters hyping up severity. At the same time, software maintainers are facing a deluge of low effort or outright bogus AI-generated vulnerability reports. Still, it looks like security issues are getting more frequent and more severe, even if you assume AI has increased the percentage that get found; and the trend started before AI got good at finding security issues.</p>
<p>It’s not just security issues either. Microsoft GitHub is now <a href="https://mrshu.github.io/github-statuses/">so unreliable</a> that customers are starting to migrate away. One recent bug <a href="https://www.thestack.technology/github-bug-messed-up-customer-code-coo-plays-down-incident/">deleted code from over 2,000 projects</a>.</p>
<h2 id="the-web-duopoly">The web duopoly</h2>
<p>The median web page size is now <a href="https://httparchive.org/reports/page-weight">2.6 MB on mobile, 3 MB on desktop</a>, spread over 70 separate requests. If you look at the amount of HTML, though — the text of the page, often the part you actually care about — that’s an average of 35 KB, meaning the page is 99% bloat. To pick a real example, I went to read the text of a news story on CNN. 19.7 MB downloaded and 52 tracking cookies, for 12.5 KB of article text. (And no cookie banner with opt-out, which means they’re breaking state law.)</p>
<p>The trackers and ads don’t help, but modern web development is part of the problem too. Once upon a time you’d <a href="https://www.w3.org/MarkUp/html-spec/html-spec.html">refer to the HTML 2 spec</a> (179 KB) and write your HTML; now you’ve got a <a href="https://html.spec.whatwg.org">15 MB HTML 5 spec</a>, plus a thousand pages of CSS specs. Not that most web developers write HTML — they’re all writing React and generating div soup. That is, instead of writing HTML and CSS, they write JavaScript, embed HTML in the JavaScript, import CSS into the JavaScript as modules, and if they want a bit of JavaScript on the page they <a href="https://react.dev/learn/javascript-in-jsx-with-curly-braces">embed JavaScript in the HTML that’s embedded in the JavaScript</a>. Instead of updating the actual page via the browser’s object model, they update a separate virtual object model based on the real one, so React can work out the differences before and after, and then apply those differences to the actual page. It’s slower than just making the updates directly using JavaScript and native <code>DocumentFragment</code> and <code>HTMLTemplateElement</code>, and it uses more memory, but approximately nobody doing web development cares about that. It makes life easier, I’m told, and you only need to add 531 KB of bundled React runtime to your web page.</p>
<p>Parsing all the HTML, JavaScript and CSS on a modern web page, and running the JavaScript quickly, is a tricky task. Once you add in all the web APIs for things like background tasks, push notifications, and local database storage, it becomes a massive undertaking. As a result, we’re now at the point where the web is controlled by two corporations — Google and Apple — because they control the two rendering engines every popular browser uses. (Firefox is no longer a popular browser, Mozilla having managed to drive it down to 3.3% market share.)   If Google and Apple decide everyone needs <a href="https://cybernews.com/privacy/google-qr-code-recaptcha-requires-approved-phone/">a device they’ve approved</a> in order to access the web, then that’s what happens.</p>
<h2 id="were-going-to-need-a-reinforced-desk">We’re going to need a reinforced desk</h2>
<p>Desktop software is going the same route as web applications. In many cases, literally — many popular desktop applications are now built using Electron, bundling an entire web browser engine and developing the application in JavaScript, HTML and CSS. Sometimes a Node.js runtime is bundled as well. The result is that you can easily end up chewing up 2 GiB of RAM to edit a text file. Text chat via Discord can eat 1-4 GiB.</p>
<p>Microsoft Office also wants 4 GiB of RAM these days, but at least you get a full word processor. More than full, in fact. It now offers <a href="https://featurebloat.com/case-studies">around 1,500 commands</a>, with the average user touching fewer than 20 of them. People used to love Word, but now for many people the first draft of a document happens somewhere else, often in Markdown.</p>
<p>Word-style feature bloat isn’t a new problem. My first Unix text editor was Emacs, but I struggled with it. When I began running Minix on my Atari, it didn’t have the RAM for Emacs, so I ended up trying vi (well, Elvis). I soon switched to vi everywhere, because I could get by comfortably with what I could remember of vi’s 100 keystroke commands. I’m sure Emacs is great for people who can deal with its 1,900 key bindings, but I’m not one of those people. I avoid word processors too.</p>
<p>Just as code is not the goal of programming, and features are not the goal of implementing programming languages, so features should not be the goal of application software development. Solving a problem is the goal. The ideal piece of software has just enough features to solve the problem, and no more. Software should generally avoid trying to solve multiple problems, unless they are problems that usually occur together and don’t occur elsewhere. For example, it makes sense for a web browser to also be a bookmark manager; it doesn’t make sense for it to be a VPN client — that belongs with general networking setup. It’s reasonable for a word processor to also be an outliner, because outlining is part of the writing process; it’s less reasonable for a word processor to also have features for making graphs from tables of data.</p>
<p>People into hi-fi understand this. You pick a good amplifier, and if you want to play vinyl you connect it to a turntable. If you want to play CDs, you connect a CD player. Generally, the more high end the amplifier, the fewer controls it has. You <em>can</em> buy an amplifier, turntable and CD player in a single unit, but it probably won’t be very good. The company that makes the best amplifiers probably won’t be the one that makes the best turntables. You want pieces that solve one problem and work together. That was the key lesson from the success of early versions of Unix.</p>
<p>Every option your program has is a clue that maybe you have lost the plot. GNU <code>ls</code> has 58 options. Fifty eight! And the problem is just “list the files in a directory”! macOS has nearly as many. <code>ls -bloat</code>, <code>ls -complex</code> — both valid commands. And as applications become more laden with feature bloat, they also become harder to test, and <a href="https://support.microsoft.com/en-US/Support/known-issues/fixes-or-workarounds-for-recent-issues-in-excel-for-windows">more bugs creep in</a>.</p>
<p>Look at some SaaS examples. What do people want Zoom for? Video chat. What did Zoom decide everyone wanted? A “workplace” with word processing, messaging, email, a calendar, a spreadsheet, presentation software, and the obligatory chatbot. I’ve never used any of those things, they’re just junk clutting up the UI. How did Airtable become successful? They built a database simple enough for ordinary people to use like a spreadsheet. What did they decide everyone wanted? A “platform” with portals, project planning, agents, customer relationship management, image processing, and of course a chatbot.</p>
<p>Unfortunately many people have learned to choose things based on how many features they have. Partly this is because more features seems to mean more value, and partly it’s speculation that one day those other features might be useful. Often the people choosing which product to buy are senior management and have no idea what the day-to-day ground level problems actually are, so they go for bloated “platform” solutions that claim to solve <em>every</em> problem.</p>
<p>Feature-based purchasing and feature-based product development are also how we ended up with Internet-connected fridges. Meanwhile, here’s the entire control panel from the garage freezer I bought:</p>
<p>
  <img src="IMG_0923.jpg" alt="Dial with “OFF”, “Cold”, “Recommended”, “Coldest”">

</p>
<p>The problem is to keep frozen food frozen. The solution is a box that makes things cold. It needs a control to adjust the coldness. To keep things simple, it defrosts itself automatically. There are no other controls, because they aren’t needed to solve the problem of keeping things frozen.</p>
<p>Simple solutions exist, but we have to want them, and avoid being seduced by features.</p>
<h2 id="the-two-video-game-companies">The two video game companies</h2>
<p>There was a time when video game companies would build their own game engines, but if you play a modern video game the chances are the loading screen or credits will either mention Unreal Engine or Unity. There are a few other pro game engines like Source and CRYENGINE, but the industry seems to be moving to a duopoly. Putting graphics on a computer screen is now such a complex task that there’s a shortage of people with the necessary knowledge to build and maintain game engines, particularly those sophisticated enough for AAA games.</p>
<p>When Unity changed their licensing to try to squeeze more money out of game developers, people got angry. The company <a href="https://www.polygon.com/23885373/unity-technologies-install-fee-pricing-change/">backed off</a>, but it’s only a matter of time before they try the squeeze again, or Epic tries the same thing for Unreal Engine. In the mean time, Unity have rolled out updated terms of service that prohibit you from training LLMs on their content. They’re allowed to use <em>your</em> data to improve <em>their</em> service, of course.</p>
<h2 id="its-not-just-the-software">It’s not just the software</h2>
<p>My own experience of complexity as the enemy started with CPUs. BASIC on the TRS-80 wasn’t fast enough to do what I wanted to do, so I began trying to learn Z80 machine code. I didn’t have a great deal of luck, but a year or so later I got a different computer with a 6052 CPU, and I took to that immediately.</p>
<p>The difference? The Z80 has 158 different types of instruction, and 16  registers (plus flags, stack pointer and program counter). Meanwhile, the 6502 has only 56 instructions, and only 3 registers.</p>
<p>Back in 1965, Gordon Moore — later co-founder of Intel — had noted that the number of transistors that could be crammed onto an integrated circuit roughly doubled every two years. But just because you <em>can</em> doesn’t mean you <em>should</em>.</p>
<p>Intel’s original Pentium contained 3.1 million transistors, double the number in the 486. Perhaps unsurprisingly, a bug crept in, leading the chip to compute some floating point division incorrectly. Intel performed a recall. But to get better and better performance when running compiled code, CPUs continued to get more and more complicated. Features like speculative execution were introduced — when there’s a branch in the code, the CPU will either guess which one will run, or run both in parallel and throw away the one that turns out not to be needed. These sorts of tricks did speed up software, but they also made the behavior of the CPUs hard to reason about. Eventually people worked out how to exploit the behavior to break security, with attacks like Spectre and Meltdown.</p>
<p>For a while it did look as if things might get simpler. The ARM2 only had 30,000 transistors compared to the 80386’s 275,000, but was twice as fast. Unfortunately these days an Apple ARM CPU has about as many billions of transistors as an Intel CPU.</p>
<h2 id="so-whats-my-point">So what’s my point?</h2>
<p>I’ve digressed a lot, so let me summarize.</p>
<p>When I run through a list of things that are terrible about computers, I notice a common factor:</p>
<ul>
<li>
<p>Google controls the web. Why? Complexity.</p>
</li>
<li>
<p>Web pages are slow and clunky on mobile devices. Why? Complexity.</p>
</li>
<li>
<p>Software is full of security holes? Complexity again.</p>
</li>
<li>
<p>Applications are bloated and use up multiple gigabytes of RAM? Complexity.</p>
</li>
<li>
<p>Your office software is barely usable? Complexity from feature creep.</p>
</li>
<li>
<p>A couple of companies control video game development? Complexity.</p>
</li>
<li>
<p>People use the wrong tools? The right tools are too complex.</p>
</li>
<li>
<p>People use LLMs to write code? Languages are too complex, libraries and frameworks are too complex, APIs are too complex.</p>
</li>
</ul>
<p>It seems to me that the computer industry has been utterly failing to address complexity for decades, and the signs are everywhere.</p>
<p>The difficulty of developing secure, efficient software is a symptom of the underlying sickness: complexity. Now we’re using LLMs to make it quick and easy to generate complex and voluminous code. We’re treating the symptom, and making the problem worse by doing so. (Every problem has a simple and obvious solution that will make things worse.)</p>
<p>At the same time, it seems to me that simplicity isn’t valued. A commit which adds a feature using 3,000 lines of code will impress management. A commit that removes an unnecessary feature by deleting 3,000 lines of code generally won’t. We know that “lines of code” is a terrible metric, but we have to measure something, and other things are hard to measure. We don’t really know how to measure complexity in general. We can measure cyclomatic complexity of a given piece of code, but that doesn’t tell us anything about the complexity of the user interface or the conceptual complexity of the design as a whole.</p>
<p>I don’t have a quick fix, because simplicity is hard. Any moderately capable programmer can build a complex piece of software to meet a business need. What’s much harder is to build a <em>simple</em> piece of software to meet that same need. For starters, it means spending a lot more time up front on design, and being willing to throw away work you later discover you don’t need.</p>
<p>Maybe you don’t have a choice any more. Maybe you’re at a company that has decreed that you’re not allowed to write code, you’re only allowed to examine and touch up generated code. If so then you have my sympathy, but please try to fight against complexity in your spare time. You really don’t need those Internet-connected light bulbs.</p>
]]></content></entry><entry><title type="html">The vi family</title><link href="https://lpar.ATH0.com/posts/2026/05/the-vi-family/"/><id>https://lpar.ATH0.com/posts/2026/05/the-vi-family/</id><published>2026-05-04T16:08:34-05:00</published><updated>2026-05-04T16:08:34-05:00</updated><summary>The last text editor you’ll ever need to learn.</summary><content type="html"><![CDATA[<p>Polls of Linux users suggest that <code>vi</code> family editors are the most popular. The <code>vi</code> editor is a terminal-based text editor which dates back to 1977. If you’re wondering why so many people would choose to use a fifty year old text editor with a notoriously steep initial learning curve, it’s because once you learn it, you can be ruthlessly efficient with your editing. There’s also the benefit that it’s basically everywhere, so you don’t have to keep re-learning how to edit — most IDEs have <code>vi</code> key bindings as an option, including VS Code, IntelliJ IDEA, and XCode.</p>
<p>The <code>vi</code> 2.0 release (1979) was a very large piece of software for the time, and in the 1980s it was only available to people with a commercial UNIX® license from AT&amp;T. For this reason, multiple people created free clones of <code>vi</code> to run on 80s personal computers.</p>
<p>There are now many <code>vi</code> clones and derivatives to choose from, and I couldn’t find a good comprehensive list of all of them with links, so here’s mine. Dates are release dates, to the best of my ability to track them down. Some of the projects are no doubt defunct, but it can be hard to tell as they can also go years between releases.</p>
<p>I’m not going to list all the IDEs that have <code>vi</code> key bindings as an option, but other than that suggested additions are welcome.</p>
<h2 id="original-exvi-1977-2017">Original ex/vi (1977-2017?)</h2>
<p>The original 2.11BSD vi. There are many forks available, including the following:</p>
<ol>
<li>
<p><a href="https://ex-vi.sourceforge.net">https://ex-vi.sourceforge.net</a> (last release 2007), extended for multibyte Unicode characters (UTF-8).</p>
</li>
<li>
<p><a href="https://github.com/n-t-roff/heirloom-ex-vi">https://github.com/n-t-roff/heirloom-ex-vi</a> (last release 2016), sourced from 1 above but with additional bugfixes. The same Microsoft Github account has <a href="https://github.com/n-t-roff?tab=repositories">other versions of vi</a> available.</p>
</li>
<li>
<p><a href="https://github.com/edeemer/ex-vi">https://github.com/edeemer/ex-vi</a> (no releases, last updated 2021), a fork ported to use <code>malloc</code> instead of <code>sbrk</code> so that it will build on Linux.</p>
</li>
</ol>
<h2 id="stevie-19871989">STevie (1987–1989)</h2>
<p><a href="https://nosuch.com/tjt/STevie/">https://nosuch.com/tjt/STevie/</a></p>
<p>A clone for the Atari ST and Amiga. If you don’t have an ST or Amiga you don’t want this. If you <em>do</em> have an ST or Amiga, you probably still don’t want this, as there are better options available to you. Vim (see below) descends from STevie.</p>
<h2 id="calvin-19881997">Calvin (1988–1997)</h2>
<p><a href="https://www.guckes.net/calvin/">https://www.guckes.net/calvin/</a></p>
<p>A small <code>vi</code> clone for 16 bit MS-DOS systems. Main limitation is a lack of regex support.</p>
<h2 id="mks-vi-1989">MKS vi (1989–)</h2>
<p>A POSIX.2 standard <code>vi</code> clone for 16-bit MS-DOS (and later, Windows). Originally sold as a standalone product, now part of the <a href="https://www.mkssoftware.com">MKS Toolkit</a>. Current versions support UTF-8.</p>
<h2 id="elvis-19902024">Elvis (1990–2024?)</h2>
<p><a href="https://github.com/mbert/elvis">https://github.com/mbert/elvis</a></p>
<p>One of the earliest free software <code>vi</code> clones, built to run on MS-DOS, Minix, and other systems of the early 1990s.</p>
<p><a href="https://htmlpreview.github.io/?https://github.com/mbert/elvis/blob/master/README.html">Elvis added improvements</a> including multiple edit buffers, multiple windows, and syntax coloring. Unlike STevie, it used a file buffer for editing, so it could deal with files larger than available memory. It was used for the 80386 port of BSD Unix.</p>
<h2 id="xvi-19922017">xvi (1992–2017?)</h2>
<p><a href="https://martinwguy.github.io/xvi/">https://martinwguy.github.io/xvi/</a></p>
<p>A STevie derivative which adds multiple windows and buffers. Probably the smallest <code>vi</code> clone.</p>
<h2 id="vile-1991">Vile (1991–)</h2>
<p><a href="https://invisible-island.net/vile/">https://invisible-island.net/vile/</a></p>
<p>Originally derived from Microemacs, given <code>vi</code> style editing, but with <em>more</em> modes. Adds infinite undo, UTF-8 support, syntax highlighting, and more.</p>
<h2 id="vim-1991">Vim (1991–)</h2>
<p><a href="https://www.vim.org">https://www.vim.org</a></p>
<p>Probably the most used <code>vi</code> clone. Derived from STevie. Adds windows, multiple buffers, assorted scripting options, and UTF-8 support. Handles very large files (GB in size).</p>
<p>Now incorporating LLM-generated code. Forked as <a href="https://codeberg.org/evi-editor/evi">Evi</a> and <a href="https://vim-classic.org">Vim Classic</a>, both without LLM-generated code. Evi is based on Vim 9, Vim Classic on Vim 8.</p>
<h2 id="nvi-1994">nvi (1994–)</h2>
<p><a href="https://repo.or.cz/nvi.git">https://repo.or.cz/nvi.git</a></p>
<p><a href="https://sites.google.com/a/bostic.com/keithbostic/the-berkeley-vi-editor-home-page">https://sites.google.com/a/bostic.com/keithbostic/the-berkeley-vi-editor-home-page</a></p>
<p>Based on Elvis. Written by Keith Bostic to be the reference implementation of <code>vi</code> for POSIX.2, and eventually <a href="https://pubs.opengroup.org/onlinepubs/7908799/xcu/vi.html">incorporated into the Single Unix Specification</a> (SUS).</p>
<p>Intended to be identical in core behavior to the original <code>vi</code> <a href="https://ex-vi.sourceforge.net/viin/paper.html">as described by Bill Joy</a>. Adds support for additional scripting languages (Perl and Tcl), and additional features such as multi-level undo and multiple file editing that don’t break historical behavior.</p>
<p>Introduced use of a database for storing file data. It’ll open files of about a GB in size but will complain about DB page sizes. Also unfortunately still doesn’t fully support UTF-8 text beyond a Latin-1 subset.</p>
<p>Used for the 4BSD Unix release; currently used by FreeBSD and NetBSD.</p>
<h2 id="openbsd-vi--openvi-1994">OpenBSD vi / OpenVi (1994—)</h2>
<p><a href="https://github.com/johnsonjh/OpenVi">https://github.com/johnsonjh/OpenVi</a></p>
<p>A derivative of <code>nvi</code>. Extensively cleaned up, but still doesn’t support UTF-8 text. Also missing macros, scripting, syntax highlighting. Forked for portability to other OSs.</p>
<h2 id="busybox-vi-2001">BusyBox vi (2001–)</h2>
<p><a href="https://busybox.net">https://busybox.net</a></p>
<p>BusyBox includes a tiny incomplete (but usable) implementation of <code>vi</code>. You’ll encounter it in Alpine Linux and embedded systems. There’s a fork extracted from BusyBox at <a href="https://github.com/brentr/viless">https://github.com/brentr/viless</a></p>
<h2 id="illumos-vi-2005">IllumOS vi (2005–)</h2>
<p><a href="https://github.com/illumos/illumos-gate/tree/master/usr/src/cmd/vi">https://github.com/illumos/illumos-gate/tree/master/usr/src/cmd/vi</a></p>
<p>AT&amp;T UNIX® <code>vi</code> from SVR4, open-sourced as part of OpenSolaris in 2005.</p>
<h2 id="nvi2-2011">nvi2 (2011–)</h2>
<p><a href="https://github.com/lichray/nvi2">https://github.com/lichray/nvi2</a></p>
<p>Adds UTF-8 support to nvi, as well as various CJK encodings. Requires <code>libdb1</code> (Berkeley DB version 1), which unfortunately makes it hard to build on modern Linux.</p>
<h2 id="neovim-2014">neovim (2014–)</h2>
<p><a href="https://neovim.io">https://neovim.io</a></p>
<p>Cleans up Vim by removing support for ancient platforms. Adds LSP support, a built-in terminal emulator, Lua scripting to replace VimScript, and many other features.</p>
<p>Now incorporating LLM-generated code.</p>
<h2 id="evi-2026">EVi (2026–)</h2>
<p><a href="https://codeberg.org/evi-editor/evi">https://codeberg.org/evi-editor/evi</a></p>
<p>A fork of Vim from before it began gaining LLM-generated code.</p>
<h2 id="vim-classic-2026">Vim Classic (2026–)</h2>
<p><a href="https://vim-classic.org">https://vim-classic.org</a></p>
<p>A fork of Vim from version 8.3 (pre LLM code), aiming for long term support by humans.</p>
<h2 id="toybox-vi-2027">ToyBox vi (2027?)</h2>
<p><a href="https://codeberg.org/landley/toybox">https://codeberg.org/landley/toybox</a></p>
<p>ToyBox, the non-GPL BusyBox clone, <a href="https://codeberg.org/landley/toybox/src/branch/master/toys/pending/vi.c">may be getting its own</a> tiny <code>vi</code> implementation.</p>
<hr>
<p>Also, some things which aren’t really vi, but…</p>
<h2 id="viper-1995">Viper (1995–)</h2>
<p><a href="https://www.gnu.org/software/emacs/manual/html_mono/viper.html">https://www.gnu.org/software/emacs/manual/html_mono/viper.html</a></p>
<p>A set of <code>vi</code> key bindings for Emacs.</p>
<h2 id="kakoune-2012">Kakoune (2012–)</h2>
<p><a href="http://kakoune.org">http://kakoune.org</a></p>
<p>A modal editor inspired by <code>vi</code>, but with <a href="https://raw.githubusercontent.com/mawww/kakoune/refs/heads/master/VIMTOKAK">slightly different key bindings</a>. Designed to be minimal, calls external programs for some features.</p>
<h2 id="evil-2013">Evil (2013–)</h2>
<p><a href="https://github.com/emacs-evil/evil">https://github.com/emacs-evil/evil</a></p>
<p>Another implementation of <code>vi</code> modal editing on top of Emacs.</p>
<h2 id="vis-2015">vis (2015–)</h2>
<p><a href="https://github.com/martanne/vis">https://github.com/martanne/vis</a></p>
<p>Like <code>vi</code>, but with structural regular expressions and other features taken from <code>sam</code>, the Plan 9 editor. (Sam is a graphical editor, so isn’t in this list.)</p>
<h2 id="neatvi-2015">neatvi (2015–)</h2>
<p><a href="https://github.com/aligrudi/neatvi">https://github.com/aligrudi/neatvi</a></p>
<p>Another vi clone. Supports RTL as well as UTF-8. ISC license.</p>
<h2 id="viw-20162017">viw (2016–2017)</h2>
<p><a href="https://github.com/lpan/viw">https://github.com/lpan/viw</a></p>
<p>“VI Worsened”, a small vi clone.</p>
<h2 id="nextvi-2020">nextvi (2020–)</h2>
<p><a href="https://github.com/kyx0r/nextvi">https://github.com/kyx0r/nextvi</a></p>
<p>A rewrite/extension of neatvi.</p>
<h2 id="helix-2021">Helix (2021–)</h2>
<p><a href="https://github.com/helix-editor/helix">https://github.com/helix-editor/helix</a></p>
<p>Another new modal editor, inspired by Kakoune and Vim. Again, <a href="https://github.com/helix-editor/helix/wiki/Differences-from-other-editors#vim">key bindings are different</a>.</p>
<h2 id="eh-2024">eh (2024–)</h2>
<p><a href="https://codeberg.org/SirWumpus/eh">https://codeberg.org/SirWumpus/eh</a></p>
<p>“Edit Here”. Originally <a href="https://www.ioccc.org/2024/howe/index.html">a winner of the 2024 International Obfuscated C Code Contest</a> (IOCCC); a tiny vi clone by Anthony C Howe. An incomplete implementation of vi, but it’s UTF-8 capable and only 2,112 lines long.</p>
<p>Based on…</p>
<h2 id="ae-19911993">ae (1991–1993)</h2>
<p><a href="https://github.com/SirWumpus/ioccc-ae">https://github.com/SirWumpus/ioccc-ae</a></p>
<p><a href="https://www.ioccc.org/1991/ant/index.html">IOCCC 1991 Best Utility winner</a>, a vi clone in less than 1536 bytes of source code. No UTF-8 support, since it predates UTF-8.</p>
<p>The enhanced 1993 version was used for a while as Debian’s emergency floppy disk editor, before being replaced by Nano.</p>
]]></content></entry><entry><title type="html">Notes on infrasonic data center noise</title><link href="https://lpar.ATH0.com/hdc/"/><id>https://lpar.ATH0.com/hdc/</id><published>2026-03-26T18:44:00-05:00</published><updated>2026-03-26T18:44:00-05:00</updated><summary/><content type="html"><![CDATA[<p>The problem:</p>
<ul>
<li>Hyperscale data centers are a major source of noise pollution.</li>
<li>A lot of the noise is very low frequency noise or infrasound — noise that is below the measured range of human hearing.</li>
<li>Infrasound can still have negative effects on the human body, and some people seem to be very sensitive to it.</li>
<li>Minnesota’s standards for noise pollution specify dB(A), A-weighted decibels, as the way to measure noise.</li>
<li>dB(A) applies a large negative adjustment to low frequency noise.</li>
<li>This is an inappropriate measure for evaluating low frequency noise pollution according to ISO, the World Health Organization, and other expert groups.</li>
<li>More appropriate measurements are available, including C-weighted and S-weighted decibels.</li>
</ul>
<p>Details below.</p>
<hr>
<p>A lot of the concern over health effects of data centers involves infrasound (0-20 Hz) and low frequency noise (10-250 Hz); see <em>Infrasound in Biology and Medicine: Insights into Mechanisms, Health Outcomes and Research Perspectives - A Narrative Review</em><sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup>.</p>
<p>Unfortunately, Minnesota’s noise pollution regulations seem to specify that only <em>audible</em> sound needs to be limited. The Minnesota Pollution Control Agency (MPCA) document <em>A Guide to Noise Control in Minnesota</em><sup id="fnref:2"><a href="#fn:2" class="footnote-ref" role="doc-noteref">2</a></sup> states that for residential housing areas (NAC 1), the legal limit for noise is 50 dB(A) at night time. This value is taken from the Minnesota Administrative Rules, chapter 7030.<sup id="fnref:3"><a href="#fn:3" class="footnote-ref" role="doc-noteref">3</a></sup></p>
<p>The Alternative Urban Areawide Review (AUAR) for the Hermantown data center project<sup id="fnref:4"><a href="#fn:4" class="footnote-ref" role="doc-noteref">4</a></sup> states:</p>
<blockquote>
<p>The Hermantown Zoning Code regulates mechanical noise associated with building operation by the standards set by the MPCA. All future development will be required to comply with these requirements.</p>
</blockquote>
<p>The unit dB(A) in the MPCA document refers to A-weighted decibels. A-weighting is the process of adjusting measured values to account for the sensitivity of the human ear. If you look at the graph on page 9 of the MPCA document, you can see that A-weighting reduces the measured sound level significantly below 100 Hz.</p>
<p>Here’s <a href="https://en.wikipedia.org/wiki/A-weighting">the same graph from Wikipedia</a>:</p>
<img src="curves.svg">
<p>You can see that below 50 Hz (generally agreed on as the lower limit of human hearing), noise is recorded as 30 dB or more below its true level. This is a problem when it comes to low frequency and infrasonic data center noise pollution.</p>
<p>According to <em>Review of evaluation criteria for infrasound and low frequency noise in the general environment</em><sup id="fnref:5"><a href="#fn:5" class="footnote-ref" role="doc-noteref">5</a></sup>, multiple cited studies have shown that this A-weighted curve is unsuitable for evaluating effects of low frequency noise (LFN).</p>
<p>One cited study is <em>Low Frequency Noise and Annoyance</em><sup id="fnref:6"><a href="#fn:6" class="footnote-ref" role="doc-noteref">6</a></sup>, which states:</p>
<blockquote>
<p>Conventional methods of assessing annoyance, typically based on A-weighted equivalent level, are inadequate for low frequency noise and lead to incorrect decisions by regulatory authorities.</p>
</blockquote>
<p>That study mentions the World Health Organization <em>Guidelines for Community Noise</em> <sup id="fnref:7"><a href="#fn:7" class="footnote-ref" role="doc-noteref">7</a></sup>, the result of an expert task force. A quote from that document:</p>
<blockquote>
<p>When prominent low-frequency components are present, noise measures based on A-weighting are inappropriate. The difference between dB(C) and dB(A) will give crude information about the presence of low-frequency components in noise, but if the difference is more than 10 dB, it is recommended that a frequency analysis of the noise be performed. It should be noted that a large proportion of low-frequency components in noise may increase considerably the adverse effects on health.</p>
</blockquote>
<p>Also, according to the WHO document, 50-55 dB(A) outdoors in a living area constitutes a “moderate annoyance” or “serious annoyance”.</p>
<p>Another study is <em>Low frequency noise enhances cortisol among noise sensitive subjects during work performance</em> (Waye, Bengtsson, Rylander, Hucklebridge, Evans and Clow, 2002)<sup id="fnref:8"><a href="#fn:8" class="footnote-ref" role="doc-noteref">8</a></sup>. In this study, subjects were exposed to just over 2 hours of LFN at 40 dB(A) in an office-like situation. Subjects susceptible to noise were found to have disrupted circadian cortisol levels (which might lead to disrupted sleep), higher reported stress levels, and lower task performance. The data center noise will of course be continuous, rather than for two hours at a time.</p>
<p>The international standard for how to measure infrasound, <a href="https://www.iso.org/standard/13813.html">ISO 7196:1995</a>, specifies a G-weighted curve rather than A-weighted. The G curve includes measurement of frequencies between 0.2 and 20 Hz, and doesn’t reduce measured values by 30 dB until the frequency is as low as 2 Hz.</p>
<p>For recorded examples of low frequency noise, and further explanation for why db(A) isn’t a good measurement, there’s <a href="https://invc.com/noise-control/tonalysis-adding-simple-low-frequency-tonal-analysis-to-dba/">a good article from the UK Industrial Noise and Vibration Center</a>. (Use headphones rather than laptop speakers when listening to the noise, as laptop speakers typically have poor bass output.)</p>
<p>My overall conclusion is that the proposed sound limits for the data center are based on inappropriate measurement methods. It’s entirely plausible, given available experimental results, that infrasound from the data center could meet proposed dB(A) limits, but still be loud enough at low frequencies to result in disrupted sleep, increased stress, and other negative health effects in the surrounding neighborhood. The proposed limits will also dramatically under-measure low frequency noise, which travels long distances.</p>
<p>I strongly suggest that the project should be held to a contractual requirement to hold sound levels below 50-55 dB(C), <em>not</em> dB(A), in accordance with WHO guidelines.</p>
<p>Ideally, Minnesota administrative rules would also be updated to mandate appropriate measurement of low frequency noise and infrasound.</p>
<p>The New York Times recently carried <a href="https://www.nytimes.com/2026/06/17/us/data-centers-noise-pollution.html?unlocked_article_code%3D1.q1A.RIpU.gRDU-GOBgz7C%26smid%3Dnytcore-ios-share">an article about data center noise</a> that mentions the issue:</p>
<blockquote>
<p>Most communities set their standards using an A-weighted decibel scale, which was designed to mimic human hearing in a quiet environment and significantly discounts, or ignores, low-frequency sounds emitted from data centers, experts said.</p>
<p>In contrast, the C-weighted scale is intended to capture low-frequency noise.</p>
<p>That distinction is especially critical when measuring data center noise, which is dominated by low-frequency hums from massive cooling fans and equipment, [professor of environmental health sciences] Dr. Neitzel said.</p>
<p>Consequently, Mr. Blomberg said, a noise source that clearly dominates a listener’s ear might not register as an issue on a standard decibel meter.</p>
</blockquote>
<p>For a less formal look at the problem, musician and science enthusiast <a href="https://www.youtube.com/@BennJordan">Benn Jordan</a> has been carrying out <a href="https://www.youtube.com/watch?v=_bP80DEAbuo">investigations into data center noise</a>. As part of his investigation into infrasound he tested its effect on groups of (consenting) people — without telling them if they were in the exposed group, of course — and found that it seemed to lead to tingling sensations, nausea, dizziness, anxiety, eye irritation, and other negative health effects.</p>
<div class="footnotes" role="doc-endnotes">
<hr>
<ol>
<li id="fn:1">
<p><em><a href="https://pmc.ncbi.nlm.nih.gov/articles/PMC12818516/">Infrasound in Biology and Medicine: Insights into Mechanisms, Health Outcomes and Research Perspectives - A Narrative Review</a></em> (Kapoor, Yadav, Agrawal, Gaur &amp; Arora, 2025), DOI: 10.4103/nah.nah_136_25&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:2">
<p><em><a href="https://www.pca.state.mn.us/sites/default/files/p-gen6-01.pdf">A Guide to Noise Control in Minnesota</a></em>, MPCA document p-gen6-01&#160;<a href="#fnref:2" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:3">
<p><em><a href="https://www.revisor.mn.gov/rules/7030.0040/">7030.0040 Noise Standards</a></em>, Minnesota Administrative Rules&#160;<a href="#fnref:3" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:4">
<p><em><a href="https://hermantownmn.com/wp-content/uploads/2025/09/2025-09-09-Hermantown-Industrial-Final-AUAR.pdf">Hermantown Industrial AUAR for the data center</a></em>, City of Hermantown, September 2025&#160;<a href="#fnref:4" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:5">
<p><em><a href="https://www.ciop.pl/CIOPPortalWAR/file/95674/2022111512226&amp;R_3_Article_Pawlaczyk_Review_OK.pdf">Review of evaluation criteria for infrasound and low frequency noise in the general environment</a></em> (Pawlaczyk-Łuszczyńska &amp; Dudarewicz, 2022), DOI: 10.54215/Noise_Control_2022_A_Digital_Monograph_Pawlaczyk-Luszczynska_M_Dudarewicz_A&#160;<a href="#fnref:5" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:6">
<p><em><a href="https://journals.lww.com/nohe/fulltext/2004/06230/low_frequency_noise_and_annoyance.6.aspx">Low Frequency Noise and Annoyance</a></em> (Leventhall, 2004), PubMed PMID: 15273024&#160;<a href="#fnref:6" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:7">
<p><em><a href="https://www.who.int/publications/i/item/a68672">Guidelines for community noise</a></em>, WHO team on Environment, Climate Change and Health, reference a68672&#160;<a href="#fnref:7" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:8">
<p><em><a href="https://www.researchgate.net/profile/Kerstin-Persson-Waye/publication/11526537_Low_frequency_noise_enhances_cortisol_among_noise_sensitive_subjects_during_work_performance/links/5cee915b92851c539572b89f/Low-frequency-noise-enhances-cortisol-among-noise-sensitive-subjects-during-work-performance.pdf">Low frequency noise enhances cortisol among noise sensitive subjects during work performance</a></em> (Waye, Bengtsson, Rylander, Hucklebridge, Evans and Clow, 2002), PMID: 11833738, DOI: 10.1016/s0024-3205(01)01450-3&#160;<a href="#fnref:8" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
</ol>
</div>
]]></content></entry><entry><title type="html">IPv6 address assignment</title><link href="https://lpar.ATH0.com/posts/2026/02/ipv6-address-assignment/"/><id>https://lpar.ATH0.com/posts/2026/02/ipv6-address-assignment/</id><published>2026-02-03T17:05:35-06:00</published><updated>2026-02-03T17:05:35-06:00</updated><summary>IPv6, SLAAC, and how obtaining an address is different on an IPv6 network.</summary><content type="html"><![CDATA[<p>In the 1990s it became clear that the world would run out of IP addresses. A new version of the Internet Protocol was developed, known as IP version 6, or IPv6 for short. Starting in 1995 it began to be published as a series of draft RFCs, and vendors began to implement it. <a href="https://www.rfc-editor.org/rfc/rfc5211.html">RFC 5211</a>, <em>An Internet Transition Plan</em> (2008), called for a switch over to IPv6 between January 2010 and December 2011.</p>
<p>In 2011 World IPv6 Day was held to mark the final year of the planned transition period. Also that year, the world ran out of IPv4 addresses. Unfortunately, even in 2026 IPv6 deployment is a long way from complete. <a href="https://www.google.com/intl/en/ipv6/statistics.html">Around 47% of Google users have IPv6</a>, but the percentage varies a lot between countries — France has 85% coverage, but Spain has less than 12%.</p>
<p>You might have IPv6 Internet; you can find out by going to <a href="https://test-ipv6.com">https://test-ipv6.com</a>. If your computer has a globally routable address it will be in the <code>2000::/3</code> range. Some address blocks in that range are reserved for special purposes, however. Whether you have a global IPv6 address or not, you almost certainly have IPv6 on your local network. In addition, all mobile Internet in the US is exclusively IPv6 — IPv4 support is provided by tunneling it over IPv6 using short-lived IPv4 addresses. It’s therefore worth learning how IPv6 works.</p>
<p>When IPv6 was developed it was designed with completely new mechanisms for obtaining an IP address. They are still unfamiliar to many people who operate networks, and they have also changed in recent years; there are now over two dozen RFCs that relate to the process. This article attempts to summarize how it works today.</p>
<p>First, though, a brief summary of the problem.</p>
<h2 id="the-address-assignment-problem">The address assignment problem</h2>
<p>In the early years of TCP/IP there was no mechanism to automatically assign IP addresses to computers and other network devices. Instead, each node on the network would be configured with a static IP address. It would be up to the network administrator to track address assignments and ensure no two systems had the same address. As local area networks were deployed more widely and more devices were added to them, it quickly became clear that a better more automated solution was needed, and several were introduced.</p>
<p>The first attempt to tackle the problem of IP address assignment was <a href="https://www.rfc-editor.org/rfc/rfc903.html">RFC 903</a>, <em>A Reverse Address Resolution Protocol</em> (1984). In this scheme, a client computer connecting to the network would send out a broadcast Ethernet packet with the standard ARP EtherType of <code>ADDRESS_RESOLUTION</code> (<code>0x0806</code>), and an opcode of <code>03</code>. A RARP server somewhere on the network would see the packet, look up the MAC address of the source, and respond directly to the client with another ARP packet, opcode 4. This packet would contain the hardware address and IP address of the server, and the hardware address and IP address for the client.</p>
<p>
  <img src="RARP.svg" alt="RARP sequence diagram">

</p>
<p>RARP was typically set up by having a <code>rarpd</code> server with a list of machines in the <code>/etc/ethers</code> configuration file:</p>
<pre tabindex="0"><code>bf:0a:fa:5f:45:20  192.168.1.101
5c:bd:c4:4f:f3:8f  192.168.1.103
</code></pre><p>Maintaining this file was still a manual process, but it did at least avoid the need to manually configure each network node. Unfortunately the use of Ethernet packets meant that it only worked on Ethernet networks, and that a separate RARP server was needed for every subnet.</p>
<p>RARP was quickly followed by BOOTP, the Bootstrap Protocol, defined in <a href="https://www.rfc-editor.org/rfc/rfc951.html">RFC 951</a>, <em>Bootstrap Protocol</em> (1985). This replaced the raw Ethernet packets used in RARP with UDP packets, so that a single server could provide addresses across multiple subnets. The packet used two reserved port numbers, 67 for the server and 68 for the client. The reply contained the client’s assigned IP address, the server’s IP address, and the client’s MAC.</p>
<p>
  <img src="BOOTP.svg" alt="BOOTP sequence diagram">

</p>
<p>In cases where the client knew its IP address and/or the server’s IP address (perhaps from a previous BOOTP query), unicast packets could be used in place of broadcast.</p>
<p>BOOTP had additional fields to allow for additional functionality. For example, it allowed the server to provide a named boot image to the client, to allow machines to boot an operating system provided by the network. The protocol quickly got extended to supply other information client machines would need, such as DNS server addresses and domain names.</p>
<p>Eventually BOOTP was replaced with <a href="https://www.rfc-editor.org/rfc/rfc1531.html">RFC 1531</a>, <em>Dynamic Host Configuration Protocol</em> (1993), or DHCP for short. It was designed to be backward-compatible with BOOTP, so that it could provide services to existing BOOTP clients. It standardized the common extensions and added the ability to assign addresses from a pool, rather than needing a configuration file listing the address for each client. As memory got cheaper, routers began tracking which addresses they had leased out to which devices, to reduce the need for devices to change IP address.</p>
<p>DHCP remains the way most devices obtain IPv4 addresses. Your home Internet router has a DHCP server that tells each device connected to Wi-Fi or Ethernet what its IP address is, where to find the DNS server, and so on.</p>
<h2 id="an-imperfect-solution">An imperfect solution</h2>
<p>In the 1980s, the International Organization for Standardization (ISO) published standard <a href="https://www.itu.int/rec/T-REC-X.200/en">X.200</a>, the Open Systems Interconnection (OSI) model of network communication. The model divided network communication into 7 layers of abstraction, from the basic hardware up to the application program:</p>
<p>
  <img src="7layers.webp" alt="The OSI 7-layer model">

</p>
<p>This standard was very influential at the time, but unfortunately TCP/IP and its common protocols don’t fit the model very well. For example, HTTPS is an application protocol, but it also defines various data formats and compression schemes and handles session control, so it straddles layers 5, 6 and 7.</p>
<p>Similarly, DHCP operates over UDP (layer 6), but it requires details of MAC addresses (layer 2). This lack of clean separation between TCP/IP and the underlying network came to be seen as undesirable, as people wanted to transport TCP/IP over other types of network connection such as Frame Relay, HDLC, or dial-up modem, which lack MAC addresses.</p>
<p>The IPv4 approach also requires that each client machine broadcast a request to the entire subnet it is connected to. When Ethernet networks ran at 10Mbps, unnecessary broadcast traffic was a problem for large subnets.</p>
<p>Another issue for large subnets is that the DHCP server has to be stateful in order to track lease offers and manage the address pool. The need for a server can also be a problem for situations where it’s desirable to have an ad-hoc client-only local network.</p>
<p>In situations where a network segment has multiple internet links available, IPv4 DHCP offers no way to associate multiple IPv4 addresses with a single MAC in order to allow devices to be gracefully allocated new addresses when the network switches link.</p>
<p>IPv6 attempts to deal with all of these issues.</p>
<h2 id="ipv6-and-slaac">IPv6 and SLAAC</h2>
<p>IPv6 introduces a new address assignment protocol known as SLAAC (pronounced ‘slack’),
originally defined in <a href="https://www.rfc-editor.org/rfc/rfc1971.html">RFC 1971</a>, <em>IPv6 Stateless Address Auto Configuration</em> (1996). The RFC set out key goals for the new protocol:</p>
<ul>
<li>No need for manual configuration of client machines.</li>
<li>No need for a stateful server or router on the network.</li>
<li>Devices can gracefully be given new network addresses without breaking connectivity.</li>
<li>If there is a router, it can tell clients whether to use SLAAC or some other mechanism.</li>
</ul>
<h3 id="ipv6-addresses">IPv6 addresses</h3>
<p>As a quick reminder, IPv6 addresses are 128 bits wide, and can be divided into three pieces:</p>
<ul>
<li>48 or more bits of network identifier (also known as the subscriber prefix)</li>
<li>16 or fewer bits of subnet identifier</li>
<li>64 bits of interface identifier</li>
</ul>
<p>The network ID indicates how to route data between the customer network and the rest of the Internet. The network ID plus subnet ID always total 64 bits. ISPs <em>may</em> allocate each customer a 64 bit network ID, but they’re encouraged to give each customer a 48 bit ID to allow for subnet numbering.</p>
<p>The top 64 bits are generally referred to as the LAN prefix, or just “prefix”, and identify the route to a specific subnet. The interface ID identifies the device on that subnet.</p>
<p>For example, with a 16 bit subnet of <code>0001</code>:</p>
<p>
  <img src="addrcomp.svg" alt="IPv6 address component illustration">

</p>
<h3 id="step-1-calculating-a-link-local-address">Step 1: Calculating a link-local address</h3>
<p>Suppose a new device joins an existing network and wishes to obtain an IPv6 address via SLAAC and become a network node.</p>
<p>The first stage is that the new node must obtains a link-local address. This is unique only to a particular network link — the network it is joining — and so only valid for a specific network interface.</p>
<p>The address block <code>fe80::/10</code> is reserved for link-local addresses. You can see a machine’s link-local addresses if you run <code>ip addr</code> (Linux), <code>ifconfig</code> (Mac) or <code>ipconfig</code> (Windows). An example:</p>
<pre><code>fe80::18a3:6bcc:e0c8:49be%en0
</code></pre>
<p>Here the <code>fe80::</code> prefix indicates that it’s a link-local address. The trailing <code>%en0</code> indicates that this address is only unique and valid for the subnet attached to the <code>en0</code> interface link. It’s unlikely, but possible, that <code>fe80::18a3:6bcc:e0c8:49be</code> could also be part of a link-local address on a network connected to a different interface; if that’s the case, <code>fe80::18a3:6bcc:e0c8:49be</code> alone would be ambiguous. So for link-local addresses, commands like <code>ping</code> require that the interface be specified.</p>
<p>It’s important to understand that link-local addresses are valid usable addresses, as long as the connecting systems are on the same subnet. All mainstream operating systems now set up link-local IPv6 addresses by default, so you likely have machines on your network that are reachable by IPv6 even if you have never done anything to set up IPv6.</p>
<p>Originally <a href="https://www.rfc-editor.org/rfc/rfc1972.html">RFC 1972</a>, <em>A Method for the Transmission of IPv6 Packets over Ethernet Networks</em> (1996), specified that for Ethernet, the link-local address should be obtained by taking the MAC address (EUI-48) of the interface card and using that as an “interface token”. The top 10 bits of the link-local address address were then the top ten bits of <code>fe80</code>, and the remaining 118 bits were the interface token left-padded with zeros. For example, a MAC address of <code>e5:ea:5c:dc:5b:d7</code> would become <code>fe80::e5ea:5cdc:5bd7</code>. (EUI-48 MACs were later expanded to EUI-64.)</p>
<p>Unfortunately, on today’s networks MAC addresses aren’t unique. More than one hardware vendor has shipped multiple units with the same MAC address, and many people who use virtual machines will make copies of them without changing their MAC addresses.</p>
<p>Deriving the link-local address from the hardware MAC address was also bad for privacy and security: it meant that every host would have a fixed address that could be tracked between networks, and that device addresses would be within predictable subnets, making mass device scanning plausible.</p>
<p>An attempt to fix the privacy and security problem was made in <a href="https://www.rfc-editor.org/rfc/rfc3041.html">RFC 3041</a>, <em>Privacy Extensions for Stateless Address Autoconfiguration in IPv6</em> (2001), which specified that hosts should generate pseudo-random interface tokens using a hashing algorithm.</p>
<p>The randomization approach was refined in <a href="https://www.rfc-editor.org/rfc/rfc7217.html">RFC 7217</a>, catchily named <em>A Method for Generating Semantically Opaque Interface Identifiers with IPv6 Stateless Address Autoconfiguration (SLAAC)</em> (2014). It specifies using a network ID and secret key as input to a pseudo-random number algorithm, so that the link-local address can be stable for any given network, but will be random across networks. This scheme is now the recommended approach per <a href="https://www.rfc-editor.org/rfc/rfc8064.html">RFC 8064</a>, <em>Recommendation on Stable IPv6 Interface Identifiers</em> (2017), and has been implemented in operating systems including iOS and macOS.</p>
<p>In short: for most devices, MAC addresses and link-local addresses are generated randomly, once, for each new network they connect to.</p>
<h3 id="step-2-link-local-duplicate-address-detection-dad">Step 2: Link-local Duplicate Address Detection (DAD)</h3>
<p>Whatever method is used to obtain a link-local address, the next step is to perform duplicate address detection to check whether a device already on the network has picked the same link-local address. It’s fairly unlikely that two nodes will pick the same address, given that the interface token is at least 48 bits wide, but definitely possible, particularly for older systems still basing link-local addresses on fixed MAC addresses.</p>
<p>Duplicate Address Detection relies on an IPv6 protocol known as Neighbor Discovery Protocol (NDP), or just Neighbor Discovery (ND), originally defined in <a href="https://www.rfc-editor.org/rfc/rfc1970.html">RFC 1970</a>, <em>Neighbor Discovery for IP Version 6 (IPv6)</em> (1996). This in turn relies on IPv6 multicast addresses, originally defined in <a href="https://www.rfc-editor.org/rfc/rfc1884.html">RFC 1884</a>, <em>IP Version 6 Addressing Architecture</em> (1995).</p>
<p>Each generated link-local address has a related solicited-node multicast address (SNMA), generated from the least significant bits of the link-local address. The solicited-node multicast address therefore includes a subset of nodes on the network that <em>may</em> have the same link-local address. All hosts are expected to listen to their solicited-node multicast address. In addition, there’s a single all-hosts multicast address every node is expected to listen to.</p>
<p>The solicited-node address was originally computed from the least significant 32 bits of the link-local address, but this was reduced to 24 bits in <a href="https://www.rfc-editor.org/rfc/rfc2373.html">RFC 2373</a> to reduce the potential scope of multicasts.</p>
<p>
  <img src="solicited.svg" alt="Solicited node address calculation">

</p>
<p>The device checking for duplicate addresses sends a Neighbor Solicitation message — ICMP type 135 — to the solicited-node multicast address, with an unspecified source address, and a payload consisting of the full link-local address it has calculated and plans to use.</p>
<p>Devices listening to the same solicited-node multicast address are expected to check Neighbor Solicitation messages. If they see one that contains their link-local address as a tentative address, they reply by sending a Neighbor Advertisement message — ICMP type 136 — to the all-nodes multicast address, <code>ff02::1</code>.</p>
<p>If the device checking for duplicate addresses sees a Neighbor Advertisement address from another node with the link-local address it has calculated, it knows it can’t use that address.</p>
<p>This can be imagined as a conversation:</p>
<ul>
<li>“Hey, everyone with an address ending <code>f8:5335</code>, I’m planning to use <code>fe80::c6ab:08f8:5335</code> as my link-local address.”</li>
<li>“Hey, everyone on the network, I’m already using <code>fe80::c6ab:08f8:5335</code>.”</li>
</ul>
<p>What happens next depends on how the new node is calculating its link-local addresses. If it is using a fixed interface token such as a hardware MAC address, it may be unable to connect to the network. If it’s using randomized interface tokens, it can generate a new one, compute a new tentative link-local address, and try again.</p>
<p>Note that while the Neighbor Discovery message is sent to a subset of hosts, the Neighbor Advertisement must be sent to all hosts because the new node performing Duplicate Address Detection doesn’t yet have a valid IP address. Since address collisions are expected to be extremely rare given the way link-local addresses are generated, this is still an improvement over IPv4.</p>
<p>In the case of an ad-hoc network, once the new node has a link-local address it simply uses that address on the network. For a network connected to the Internet, the process continues.</p>
<h3 id="step-3-locating-a-router">Step 3: Locating a router</h3>
<p>The next step, locating a router, relies on two more ICMPv6 messages, and is more straightforward.</p>
<p>IPv6 routers are expected to advertise their presence on the subnet periodically, by sending a Router Advertisement (RA) message to the all-hosts link-local multicast address <code>ff02::1</code>. If the new node has seen a Router Advertisement message, then it has the address of a router. If not, it can send a Router Solicitation message to the all-routers link-local multicast address <code>ff02::2</code> to request that a router identify itself.</p>
<h3 id="step-4-calculating-a-routable-address">Step 4: Calculating a routable address</h3>
<p>The Router Advertisement message contains the routing prefix of the network, including any appropriate subnet ID. At this point the new node knows that it has a link-local address that’s unique on the subnet, which means it has an interface token that’s unique. It can use the routing prefix and subnet ID to form the top bits of the IP address, and its interface token to form the bottom bits. It now has what <em>should</em> be a valid globally routable IPv6 address.</p>
<p>Getting a working IP address without needing a special server is good, but there’s something else a computer generally needs in order to be useful: a DNS server. Initially SLAAC offered no solution to this problem, and it was expected that IPv6 systems would have manually configured DNS. However <a href="https://www.rfc-editor.org/rfc/rfc5006.html">RFC 5006</a>, <em>IPv6 Router Advertisement Option for DNS Configuration</em> (2007), added a field to the RA packet that contains the address of a recursive DNS server.</p>
<p>So the overall process looks like this:</p>
<p>
  <img src="SLAAC.svg" alt="SLAAC sequence diagram">

</p>
<p>As you’ve probably noticed, the entire SLAAC process is lengthier than requesting an address from a DHCP server. To speed it up, <a href="https://www.rfc-editor.org/rfc/rfc4429.html">RFC 4429</a> <em>Optimistic Duplicate Address Detection (DAD) for IPv6</em> (2006) introduced a modification. In this variant of DAD, tentative addresses are instead labeled “optimistic”, and used until some other suitable address is available. (Recall that address collisions are expected to be very rare.) When DAD eventually completes, the address either becomes “preferred” and is used, or is marked “deprecated” (expired).</p>
<h2 id="the-return-of-dhcp">The return of DHCP</h2>
<p>Before RFC 5006 added a DNS server field to Router Advertisements, people had drafted and deployed DHCPv6 to solve the problem. It’s detailed in <a href="https://www.rfc-editor.org/rfc/rfc3315.html">RFC 3315</a>, <em>Dynamic Host Configuration Protocol for IPv6 (DHCPv6)</em> (2003).</p>
<p>DHCPv6 can work alongside SLAAC, distributing additional information such as domain suffixes for address resolution, NTP server addresses, boot image locations, and so on. When used for this purpose it can be run as stateless DHCPv6, avoiding the need to track every IPv6 node on the network.</p>
<p>Network administrators who prefer to run a stateful DHCPv6 server can configure routers to send Router Advertisements with the M bit (for Managed) set, to indicate that DHCPv6 should be used to obtain addresses instead of SLAAC.</p>
<p>One situation where DHCPv6 is preferable to SLAAC is when hosts are to be given Unique Local Addresses (ULAs), the equivalent of the <a href="https://www.rfc-editor.org/rfc/rfc1918.html">RFC 1918</a> addresses used by most home NAT routers. Since one of the key benefits of IPv6 is not needing NAT, this is a fairly rare scenario.</p>
<h2 id="address-renegotiation">Address renegotiation</h2>
<p>The Privacy Extensions for SLAAC defined in <a href="https://www.rfc-editor.org/rfc/rfc3041.html">RFC 3041</a> aren’t just applicable to obtaining an initial address. Even with a randomized interface token and random link-local address, if the eventual globally routable IPv6 remains constant, it could be used to track a web browser across multiple websites. If a device uses a hardware ID, its address could even be used to track it across different networks.</p>
<p>For this reason, the major operating systems now expire IPv6 addresses and obtain new ones using the same SLAAC protocol. The old addresses for the interface are labeled “deprecated” and eventually expired once any remaining traffic is expected to have completed.</p>
<p>Some ISPs also rotate customers’ IPv6 prefixes for privacy reasons. Unfortunately, if a device on the local network doesn’t support IPv6 Privacy Extensions and connects to the Internet, it <a href="https://doi.org/10.1145/3544912.3544915">can end up providing a tracking identifier for all devices on the network</a>.</p>
<h2 id="slaac-security">SLAAC security</h2>
<p>As originally standardized, SLAAC is susceptible to spoofed Router Advertisement messages. Any system on the same subnet can send RA messages and potentially get accepted as a router, at which point it can redirect traffic. (This attack <a href="https://www.techradar.com/pro/security/ipv6-networking-feature-hit-by-hackers-to-hijack-software-updates">was carried out by a Chinese threat actor starting in 2022</a>, targeting victims in China, Hong Kong, the Philippines, and UAE.)</p>
<p>Combining spoofed RA messages with the RFC 5006 extensions could allow for DNS spoofing as well.</p>
<p>To attempt to combat this, <a href="https://www.rfc-editor.org/rfc/rfc2462.html">RFC 2462</a> (1998) updated the specification for Neighbor Discovery, suggesting that IPsec could be used to secure it. Unfortunately, IPsec is complicated to deploy and didn’t see much upkeep outside of enterprise environments. For this reason, <a href="https://www.rfc-editor.org/rfc/rfc3971.html">RFC 3971</a>, <em>SEcure Neighbor Discovery (SEND)</em> (2005), introduced a dedicated cryptographic authentication protocol for ND.</p>
<p>It’s worth remembering that IPv4 DHCP is also susceptible to spoofing, which led to <a href="https://www.rfc-editor.org/rfc/rfc3118.html">RFC 3118</a> defining a mechanism for DHCP authentication.</p>
<p>Another potential issue is that a network device can respond with Neighbor Advertisement packets for every Neighbor Discovery it sees. This will effectively block any device from completing Duplicate Address Detection, hence blocking SLAAC from completing. Preventing this attack is a current research topic; for example, see:</p>
<ul>
<li><em><a href="https://doi.org/10.1080/03772063.2024.2350931">Optimized Duplicate Address Detection for the Prevention of Denial-of-Service Attacks in IPv6 Network</a></em>.</li>
<li><em><a href="https://doi.org/10.1002/dac.70135">Hamming Distance Based Duplicate Address Detection in IPv6 Network</a></em>.</li>
<li><em><a href="https://doi.org/10.1002%2Fcpe.8131">IPv6 addressing with hidden duplicate address detection to mitigate denial of service attacks in the internet of drone</a></em>.</li>
</ul>
<h2 id="summary">Summary</h2>
<ul>
<li>
<p>IPv6 allows for address assignment and DNS configuration without needing a DHCP server and without needing any static configuration; all that’s needed is an IPv6 router.</p>
</li>
<li>
<p>Ad-hoc networks with no server or router of any kind can autoconfigure IPv6 link-local addresses to allow nodes to communicate with each other.</p>
</li>
<li>
<p>IPv6 Privacy Extensions rotate addresses periodically to prevent persistent user tracking.</p>
</li>
<li>
<p>IPv6 addresses can be cleanly reassigned if the upstream network connection changes.</p>
</li>
<li>
<p>DHCPv6 is available as a way to provide additional information beyond IP, router, and DNS, or as an alternative for managed networks.</p>
</li>
</ul>
<h2 id="links">Links</h2>
<p>Since a number of the RFCs mentioned above have been obsoleted, here is a graph of the key SLAAC standards in each area, with the current version as of February 2026 shown with a double border. Associated RFCs that update the standards are connected by dotted lines.</p>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 892.02 573.1" xmlns:v="https://vecta.io/nano"><style>.B{stroke:#000}.C{text-anchor:middle}.D{font-family:Arial}.E{font-size:14px}.F{fill:#000}.G{fill:none}.H{stroke-dasharray:1,5}.I{fill:#87cefa}.J{fill:#ff0}.K{fill:#98fb98}.L{fill:salmon}</style><g transform="matrix(1 0 0 1 4 569.0969)"><path fill="#fff" stroke="transparent" d="M-4 4v-573.097h892.019V4H-4z"/><text x="36.51" y="-542.897" class="C D E F">SLAAC</text><a href="https://www.rfc-editor.org/rfc/rfc1971" xlink:title="IPv6 Stateless Address Autoconfiguration" xlink:href="https://www.rfc-editor.org/rfc/rfc1971"><circle fill="plum" cx="36.51" cy="-460.587" r="32.519" class="B"/><text x="36.51" y="-456.387" class="C D E F">1971</text></a><text x="328.51" y="-542.897" class="C D E F">ND</text><a href="https://www.rfc-editor.org/rfc/rfc1970" xlink:title="Neighbor Discovery for IP Version 6 (IPv6)" xlink:href="https://www.rfc-editor.org/rfc/rfc1970"><circle cx="328.51" cy="-460.587" r="32.519" class="B I"/><text x="328.51" y="-456.387" class="C D E F">1970</text></a><text x="492.51" y="-542.897" class="C D E F">Ethernet</text><a href="https://www.rfc-editor.org/rfc/rfc1972" xlink:title="A Method for the Transmission of IPv6 Packets over Ethernet Networks" xlink:href="https://www.rfc-editor.org/rfc/rfc1972"><circle cx="492.51" cy="-460.587" r="32.519" class="B K"/><text x="492.51" y="-456.387" class="C D E F">1972</text></a><text x="664.51" y="-542.897" class="C D E F">Addressing</text><a href="https://www.rfc-editor.org/rfc/rfc1884" xlink:title="IP Version 6 Addressing Architecture" xlink:href="https://www.rfc-editor.org/rfc/rfc1884"><circle cx="664.51" cy="-460.587" r="32.519" class="B J"/><text x="664.51" y="-456.387" class="C D E F">1884</text></a><text x="756.51" y="-542.897" class="C D E F">Privacy</text><a href="https://www.rfc-editor.org/rfc/rfc3041" xlink:title="Privacy Extensions for Stateless Address Autoconfiguration in IPv6" xlink:href="https://www.rfc-editor.org/rfc/rfc3041"><circle fill="orange" cx="756.51" cy="-460.587" r="32.519" class="B"/><text x="756.51" y="-456.387" class="C D E F">3041</text></a><text x="847.51" y="-542.897" class="C D E F">RA</text><a href="https://www.rfc-editor.org/rfc/rfc5006" xlink:title="IPv6 Router Advertisement Option for DNS Configuration" xlink:href="https://www.rfc-editor.org/rfc/rfc5006"><circle cx="847.51" cy="-460.587" r="32.519" class="B L"/><text x="847.51" y="-456.387" class="C D E F">5006</text></a><a href="https://www.rfc-editor.org/rfc/rfc2464" xlink:title="Transmission of IPv6 Packets over Ethernet Networks" xlink:href="https://www.rfc-editor.org/rfc/rfc2464"><g class="B"><circle cx="492.51" cy="-355.568" r="32.518" class="K"/><circle cx="492.51" cy="-355.568" r="36.519" class="G"/></g><text x="492.51" y="-351.368" class="C D E F">2464</text></a><a href="https://www.rfc-editor.org/rfc/rfc6085" xlink:title="Address Mapping of IPv6 Multicast Packets on Ethernet" xlink:href="https://www.rfc-editor.org/rfc/rfc6085"><circle cx="457.51" cy="-246.548" r="32.519" class="B K"/><text x="457.51" y="-242.348" class="C D E F">6085</text></a><path d="M481.339-320.774l-13.83 43.077" class="B G H"/><a href="https://www.rfc-editor.org/rfc/rfc8064" xlink:title="Recommendation on Stable IPv6 Interface Identifiers" xlink:href="https://www.rfc-editor.org/rfc/rfc8064"><circle cx="540.51" cy="-246.548" r="32.519" class="B K"/><text x="540.51" y="-242.348" class="C D E F">8064</text></a><g class="B G"><path d="M507.303-321.969l20.009 45.446" class="H"/><path d="M492.51-427.934v25.686"/></g><use href="#B" class="B"/><a href="https://www.rfc-editor.org/rfc/rfc4862" xlink:title="IPv6 Stateless Address Autoconfiguration" xlink:href="https://www.rfc-editor.org/rfc/rfc4862"><g class="B"><circle fill="plum" cx="36.51" cy="-246.548" r="32.518"/><circle cx="36.51" cy="-246.548" r="36.519" class="G"/></g><text x="36.51" y="-242.348" class="C D E F">4862</text></a><a href="https://www.rfc-editor.org/rfc/rfc7527" xlink:title="Enhanced Duplicate Address Detection" xlink:href="https://www.rfc-editor.org/rfc/rfc7527"><circle fill="plum" cx="79.51" cy="-137.529" r="32.519" class="B"/><text x="79.51" y="-133.329" class="C D E F">7527</text></a><path d="M49.997-212.353l17.528 44.44" class="B G H"/><a href="https://www.rfc-editor.org/rfc/rfc2462" xlink:title="IPv6 Stateless Address Autoconfiguration" xlink:href="https://www.rfc-editor.org/rfc/rfc2462"><circle fill="plum" cx="36.51" cy="-355.568" r="32.519" class="B"/><text x="36.51" y="-351.368" class="C D E F">2462</text></a><g class="B"><use href="#C" class="G"/><use href="#B" x="-456" y="4.028"/><use href="#D" class="G"/><use href="#B" x="-456" y="108.793"/></g><a href="https://www.rfc-editor.org/rfc/rfc4429" xlink:title="Optimistic Duplicate Address Detection (DAD) for IPv6" xlink:href="https://www.rfc-editor.org/rfc/rfc4429"><circle fill="plum" cx="123.51" cy="-246.548" r="32.519" class="B"/><text x="123.51" y="-242.348" class="C D E F">4429</text></a><path d="M111.253-216.18L91.7-167.734" class="B G H"/><a href="https://www.rfc-editor.org/rfc/rfc4291" xlink:title="IP Version 6 Addressing Architecture" xlink:href="https://www.rfc-editor.org/rfc/rfc4291"><g class="B"><circle cx="664.51" cy="-137.529" r="32.518" class="J"/><circle cx="664.51" cy="-137.529" r="36.519" class="G"/></g><text x="664.51" y="-133.329" class="C D E F">4291</text></a><a href="https://www.rfc-editor.org/rfc/rfc7346" xlink:title="IPv6 Multicast Address Scopes" xlink:href="https://www.rfc-editor.org/rfc/rfc7346"><circle cx="622.51" cy="-32.51" r="32.519" class="B J"/><text x="622.51" y="-28.31" class="C D E F">7346</text></a><path d="M650.874-103.432l-16.213 40.539" class="B G H"/><a href="https://www.rfc-editor.org/rfc/rfc7371" xlink:title="Updates to the IPv6 Multicast Addressing Architecture" xlink:href="https://www.rfc-editor.org/rfc/rfc7371"><circle cx="705.51" cy="-32.51" r="32.519" class="B J"/><text x="705.51" y="-28.31" class="C D E F">7371</text></a><path d="M677.821-103.432l15.827 40.539" class="B G H"/><a href="https://www.rfc-editor.org/rfc/rfc2373" xlink:title="IP Version 6 Addressing Architecture" xlink:href="https://www.rfc-editor.org/rfc/rfc2373"><circle cx="664.51" cy="-355.568" r="32.519" class="B J"/><text x="664.51" y="-351.368" class="C D E F">2373</text></a><g class="B"><use href="#C" x="628" class="G"/><use href="#B" x="172" y="4.028"/></g><a href="https://www.rfc-editor.org/rfc/rfc3513" xlink:title="Internet Protocol Version 6 (IPv6) Addressing Architecture" xlink:href="https://www.rfc-editor.org/rfc/rfc3513"><circle cx="664.51" cy="-246.548" r="32.519" class="B J"/><text x="664.51" y="-242.348" class="C D E F">3513</text></a><g class="B"><path d="M664.51-322.858v33.613" class="G"/><use href="#B" x="172" y="112.994"/><use href="#D" x="628" y="109.019" class="G"/><use href="#B" x="172" y="217.812"/></g><a href="https://www.rfc-editor.org/rfc/rfc4861" xlink:title="Neighbor Discovery for IP version 6 (IPv6)" xlink:href="https://www.rfc-editor.org/rfc/rfc4861"><g class="B"><circle cx="328.51" cy="-246.548" r="32.518" class="I"/><circle cx="328.51" cy="-246.548" r="36.519" class="G"/></g><text x="328.51" y="-242.348" class="C D E F">4861</text></a><path d="M292.835-238.653c-42.947 10.501-116.281 31.665-172.325 64.614-6.245 3.671-12.395 8.38-17.957 13.188" class="B G H"/><a href="https://www.rfc-editor.org/rfc/rfc6980" xlink:title="Security Implications of IPv6 Fragmentation with IPv6 Neighbor Discovery" xlink:href="https://www.rfc-editor.org/rfc/rfc6980"><circle cx="162.51" cy="-137.529" r="32.519" class="B I"/><text x="162.51" y="-133.329" class="C D E F">6980</text></a><path d="M295.806-229.928c-25.891 13.706-62.524 34.337-92.296 55.889-5.868 4.248-11.865 9.191-17.398 14.043" class="B G H"/><a href="https://www.rfc-editor.org/rfc/rfc5942" xlink:title="IPv6 Subnet Model: The Relationship between Links and Subnet Prefixes" xlink:href="https://www.rfc-editor.org/rfc/rfc5942"><circle cx="245.51" cy="-137.529" r="32.519" class="B I"/><text x="245.51" y="-133.329" class="C D E F">5942</text></a><path d="M306.267-217.333l-41.004 53.858" class="B G H"/><a href="https://www.rfc-editor.org/rfc/rfc7048" xlink:title="Neighbor Unreachability Detection Is Too Impatient" xlink:href="https://www.rfc-editor.org/rfc/rfc7048"><circle cx="328.51" cy="-137.529" r="32.519" class="B I"/><text x="328.51" y="-133.329" class="C D E F">7048</text></a><path d="M328.51-209.943v39.751" class="B G H"/><a href="https://www.rfc-editor.org/rfc/rfc8425" xlink:title="IANA Considerations for IPv6 Neighbor Discovery Prefix Information Option Flags" xlink:href="https://www.rfc-editor.org/rfc/rfc8425"><circle cx="411.51" cy="-137.529" r="32.519" class="B I"/><text x="411.51" y="-133.329" class="C D E F">8425</text></a><path d="M350.752-217.333l41.004 53.858" class="B G H"/><a href="https://www.rfc-editor.org/rfc/rfc9131" xlink:title="Gratuitous Neighbor Discovery: Creating Neighbor Cache Entries on First‑Hop Routers" xlink:href="https://www.rfc-editor.org/rfc/rfc9131"><circle cx="494.51" cy="-137.529" r="32.519" class="B I"/><text x="494.51" y="-133.329" class="C D E F">9131</text></a><path d="M361.213-229.928c25.891 13.706 62.524 34.337 92.297 55.889 5.868 4.248 11.865 9.191 17.398 14.043" class="B G H"/><a href="https://www.rfc-editor.org/rfc/rfc9685" xlink:title="Listener Subscription for IPv6 Neighbor Discovery Multicast and Anycast Addresses" xlink:href="https://www.rfc-editor.org/rfc/rfc9685"><circle cx="577.51" cy="-137.529" r="32.519" class="B I"/><text x="577.51" y="-133.329" class="C D E F">9685</text></a><path d="M362.055-231.472c16.021 6.942 35.562 15.038 53.454 21.433 52.834 18.883 71.988 8.69 121 36 6.328 3.526 12.512 8.176 18.08 12.972" class="B G H"/><a href="https://www.rfc-editor.org/rfc/rfc2461" xlink:title="Neighbor Discovery for IP Version 6 (IPv6)" xlink:href="https://www.rfc-editor.org/rfc/rfc2461"><circle cx="328.51" cy="-355.568" r="32.519" class="B I"/><text x="328.51" y="-351.368" class="C D E F">2461</text></a><g class="B"><use href="#C" x="292" class="G"/><use href="#B" x="-164" y="4.028"/><use href="#D" x="292" class="G"/><use href="#B" x="-164" y="108.793"/></g><a href="https://www.rfc-editor.org/rfc/rfc8981" xlink:title="Temporary Address Extensions for Stateless Address Autoconfiguration in IPv6" xlink:href="https://www.rfc-editor.org/rfc/rfc8981"><g class="B"><circle fill="orange" cx="756.51" cy="-246.548" r="32.518"/><circle cx="756.51" cy="-246.548" r="36.519" class="G"/></g><text x="756.51" y="-242.348" class="C D E F">8981</text></a><a href="https://www.rfc-editor.org/rfc/rfc4941" xlink:title="Privacy Extensions for Stateless Address Autoconfiguration in IPv6" xlink:href="https://www.rfc-editor.org/rfc/rfc4941"><circle fill="orange" cx="756.51" cy="-355.568" r="32.519" class="B"/><text x="756.51" y="-351.368" class="C D E F">4941</text></a><g class="B"><use href="#C" x="720" class="G"/><use href="#B" x="264" y="4.028"/><use href="#D" x="720" class="G"/><use href="#B" x="264" y="108.793"/></g><a href="https://www.rfc-editor.org/rfc/rfc8106" xlink:title="IPv6 Router Advertisement Options for DNS Configuration" xlink:href="https://www.rfc-editor.org/rfc/rfc8106"><g class="B"><circle cx="847.51" cy="-246.548" r="32.518" class="L"/><circle cx="847.51" cy="-246.548" r="36.519" class="G"/></g><text x="847.51" y="-242.348" class="C D E F">8106</text></a><a href="https://www.rfc-editor.org/rfc/rfc7559" xlink:title="Packet-Loss Resiliency for Router Solicitations" xlink:href="https://www.rfc-editor.org/rfc/rfc7559"><circle cx="847.51" cy="-137.529" r="32.519" class="B L"/><text x="847.51" y="-133.329" class="C D E F">7559</text></a><path d="M847.51-209.943v39.751" class="B G H"/><a href="https://www.rfc-editor.org/rfc/rfc6106" xlink:title="IPv6 Router Advertisement Options for DNS Configuration" xlink:href="https://www.rfc-editor.org/rfc/rfc6106"><circle cx="847.51" cy="-355.568" r="32.519" class="B L"/><text x="847.51" y="-351.368" class="C D E F">6106</text></a><g class="B"><use href="#C" x="811" class="G"/><use href="#B" x="355" y="4.028"/><use href="#D" x="811" class="G"/><use href="#B" x="355" y="108.793"/></g></g><defs ><path id="B" d="M496.01-402.229l-3.5 10-3.5-10h7z"/><path id="C" d="M36.51-427.934v29.657"/><path id="D" d="M36.51-322.858v29.306"/></defs></svg>

<hr>
<p>Cake photo by <a href="https://visualhunt.co/a7/0050e6ef">Keithius</a> on <a href="https://visualhunt.com/re10/403d44f4">VisualHunt</a></p>
]]></content></entry><entry><title type="html">IPv4 history</title><link href="https://lpar.ATH0.com/posts/2026/01/ipv4-history/"/><id>https://lpar.ATH0.com/posts/2026/01/ipv4-history/</id><published>2026-01-19T14:47:08-06:00</published><updated>2026-01-19T14:47:08-06:00</updated><summary>How we came to run out of IP addresses.</summary><content type="html"><![CDATA[<p>You’re probably very familiar with IP addresses, the unique numbers used to route information to and from your Internet-connected computer. You’ll have seen addresses like this:</p>
<pre><code>198.51.100.42
</code></pre>
<p>You might also have seen addresses in this format:</p>
<pre><code>2001:db8:9b40:204f:1c56:d4eb:2848:5c5e
</code></pre>
<p>Those are IPv6 addresses, as opposed to the familiar IPv4 addresses. IPv6 is a newer standard, still in the process of being rolled out in many countries. Why the new standard? Because, unfortunately, we ran out of IPv4 addresses in 2011.</p>
<p>The idea that we ran out of Internet addresses might seem ridiculous. You’re probably wondering why the designers of the Internet didn’t allow for more addresses. To really understand the answer requires going back to early Internet history.</p>
<h2 id="the-arpanet-and-ncp">The ARPANET and NCP</h2>
<p>The Internet grew out of the ARPA Computer Network, also known as ARPANET, an experimental network project started in 1966 by the Defense Advanced Research Projects Agency (DARPA). The first computers were connected in 1969.</p>
<p>At that time, computers were large. The cheapest computer available was the DEC PDP-8, which was the size of a refrigerator and a bargain at just $18,500 — equivalent to around $190,000 in 2026 dollars.</p>
<p>
  <figure>
    <img src="pdp10.webp" alt="Control panel of a PDP-10">
    <figcaption>A PDP-10, which could run in PDP-8 mode</figcaption>
  </figure>

</p>
<p>A powerful scientific computer would be a mainframe system like an IBM System/360. The cheapest System/360 started at $133,000 or more, which translates to around $1.4 million in 2026 dollars. There were time-sharing systems for large mainframes that would allow multiple people to share the resources of a single large computer by using multiple terminals or teletypes.</p>
<p>
  <figure>
    <img src="vt100.webp" alt="A DEC VT100 terminal">
    <figcaption>A DEC VT100 terminal, typical of 1980</figcaption>
  </figure>

</p>
<p>Still, many organizations that wanted to use computers couldn’t afford them, or couldn’t afford one that was powerful enough for the work they wanted to do. DARPA technicians set out to solve this problem by building a network that would allow research organizations to share the use of their computers. The network would connect a small number of large computers, each with many users. Each computer would run multiple available services — file transfer, interactive text editing, batch processing of data, email, and so on.</p>
<p>The network protocol became known as NCP, Network Control Protocol. As described in <a href="https://www.rfc-editor.org/rfc/rfc33.html">RFC 33</a> in 1970, it used an 8-bit number (from 0 to 255) to specify which computer to connect to. Another 8-bit number specified the port (service) being connected to. Finally, a 24-bit number specified the user making the connection, allowing for around 16.8 million users. This seems like a strange system now, but at the time it made sense. There weren’t expected to be many computers, but eventually tens of thousands of researchers might want to use them, and like Social Security Numbers, you wouldn’t want to reuse user numbers.</p>
<p>All the computers on the network were given 8-character names, and files were distributed listing each computer’s address from 0 to 256, along with its hostname. You can see an example in <a href="https://www.rfc-editor.org/rfc/rfc229.html">RFC 229</a> — UCLA had two computers at addresses 1 and 65, CMU was at address 14, McClellan Air Force Base had the address 22, and so on.</p>
<p>
  <img src="arpanet_march_1977.png" alt="A map of the entire ARPANET as of March 1977">

</p>
<p>If your organization wanted to put a computer on the network, you would write to <a href="https://en.wikipedia.org/wiki/Jon_Postel">Jon Postel</a>. He would assign your computer a unique address from 0 to 255 and include it the next time he distributed a list of the computers on the network.</p>
<h2 id="the-switch-to-tcpip">The switch to TCP/IP</h2>
<p>By the mid 1970s the computer industry was starting to change rapidly, as integrated circuits were introduced and it became possible to put an entire CPU on a few integrated circuits (ICs), or even just one. DEC started using the technology for their popular PDP series computers, and soon you could buy a computer for thousands of dollars rather than tens of thousands. It became clear that eventually every organization would be able to have a computer.</p>
<p>Clearly the NCP protocol wasn’t going to work for this new world, so work began on a new system that became known as Internet Protocol (IP). The plan was to connect multiple existing networks, including ARPANET, via internetwork links. The overall network made up of all the joined-together networks would be called the Internet.</p>
<p>The first draft of the new standard was <a href="https://www.rfc-editor.org/rfc/rfc675.html">RFC 675</a>, <em>Specification of Internet Transmission Control Program</em>, published in 1974. It used 4 bits for the destination network and another 16 bits for the destination system on that network, allowing for 16 networks and up to 65,536 computers per network. This greatly expanded the number of computers that the system would be able to support, but was still built on the assumption that only a small number of organizations would be joining their networks together. (This was also the first document to use the term “internet”, shorthand for “internetwork”.)</p>
<p>In 1978 an incomplete draft of <em>Internetwork Protocol Specification Version 2</em> was published as <a href="https://www.rfc-editor.org/ien/ien28.pdf">IEN 28</a>. This would have allowed network addresses to be of variable length, up to 16 bytes. A competing <em>Specification of Internetwork Transmission Control Program (TCP) Version 3</em> was also published around the same time, as <a href="https://www.rfc-editor.org/ien/ien21.pdf">IEN 21</a>. It also used a variable address length.</p>
<p>
  <img src="ien21tcp3.webp" alt="The cover and an inner page from IEN 21">

</p>
<p>However, in 1978 researchers decided the whole approach of versions 2 and 3 was wrong. The standard was becoming overly complex because it tried to handle everything from simply sending bytes across the network to handling complex connections to services. Instead, it was decided to split the standard into two pieces. The Internet Protocol (IP) would describe how raw packets of data traveled across the network, and the Transmission Control Protocol (TCP) would build on that to support connections to services.</p>
<p>June 1978 saw the publication of <a href="https://www.rfc-editor.org/ien/ien40.pdf">IEN 40</a>, <em>Transmission Control Protocol Version 4</em>. It noted:</p>
<blockquote>
<p>All addressing information (including port identification) has been eliminated and is expected to be carried in the internet protocol.</p>
</blockquote>
<p>Document <a href="https://www.rfc-editor.org/ien/ien44.pdf">IEN 44</a>, published alongside it, described the revised IP data format. The header now had fixed address widths — 8 bits for the network and 24 for the address on that network.</p>
<p>In 1979, <a href="https://www.rfc-editor.org/ien/ien81.pdf">IEN 81</a> was published. This <em>also</em> claimed to be <em>Transmission Control Protocol Version 4</em>. Two more drafts followed, then in 1980 the final versions of IP version 4 and TCP version 4 were published as <a href="https://www.rfc-editor.org/rfc/rfc760.html">RFC 760</a> and <a href="https://www.rfc-editor.org/rfc/rfc761.html">RFC 761</a>. In 1981 <a href="https://www.rfc-editor.org/rfc/rfc791.html">RFC 791</a> replaced RFC 760, but the details of network addresses weren’t changed.</p>
<p>In November 1981, <a href="https://www.rfc-editor.org/rfc/rfc801.html">RFC 801</a> described a plan for how the entire ARPANET would switch from NCP to TCP/IP (which was then called IP/TCP). The switchover was officially completed on January 1, 1983.</p>
<h2 id="tcpip-version-4">TCP/IP version 4</h2>
<p>The final IPv4 specification in <a href="https://www.rfc-editor.org/rfc/rfc760.html">RFC 760</a> dropped the separate network identifier that had been present in earlier documents and specified that the source and destination addresses would simply be 32-bit numbers (see <a href="https://www.rfc-editor.org/rfc/rfc760.html#section-3.1">section 3.1</a>). For convenience, these would be divided up into four 8-bit numbers, written in decimal, separated by dots. Hence the familiar IP address format:</p>
<pre><code>192.0.2.17
</code></pre>
<p>However, you can still write IPv4 addresses as plain 32-bit numbers. For example:</p>
<pre><code>ping 2130706433
PING 2130706433 (127.0.0.1): 56 data bytes
64 bytes from 127.0.0.1: icmp_seq=0 ttl=64 time=0.070 ms
</code></pre>
<p>Theoretically, 32-bit addresses would give us over 4 billion possible IP addresses. However, blocks of addresses are reserved for special uses. For example, all the addresses starting with <code>127.</code> loop back to the same machine, and addresses starting with <code>224.</code> are used for broadcasting to multiple machines on the same network.</p>
<p>With the reserved address space removed, there are just over 3.7 billion public IPv4 addresses. That’s still a lot, but there was also quite a bit of waste — organizations would be allocated blocks of addresses, and it would then be up to them how to use them. For example, the Ford Motor Company was given a block of 16.7 million IP addresses. I don’t know how many computers Ford had on the Internet in the 1980s, but I’d put money on it being a lot less than 16 million.</p>
<h2 id="an-unexpected-problem-surfaces">An unexpected problem surfaces</h2>
<p>For a few years, TCP/IP version 4 was a great success. Before long every major US university was on the Internet, along with many big technology companies and military facilities.</p>
<p>However, in 1989 the first commercial Internet Service Provider started. It turned out that some ordinary people might want to connect their personal computers to the Internet. By the 1990s millions of people were doing so, and it became clear that 3.7 billion addresses weren’t going to be enough.</p>
<p>So now back to the key question: why was the IPv4 address space limited to 32 bits, particularly since the earlier proposals allowed for much longer addresses? To understand the decision, you need to look at what the world was like in 1980.</p>
<h3 id="the-computer-world-in-1980">The computer world in 1980</h3>
<p>In 1980 the most powerful computer in the world was the $7.9 million Cray-1S, which used 24-bit addresses to handle up to 32 MB of RAM.</p>
<p>
  <figure>
    <img src="cray1.webp" alt="A Cray-1S">
    <figcaption>A Cray-1S</figcaption>
  </figure>

</p>
<p>IBM’s most powerful mainframe, the 3081, also used 24-bit addresses and handled up to 32 MB of RAM.</p>
<p>
  <figure>
    <img src="IBM3081.webp" alt="IBM 3081">
    <figcaption>An IBM 3081 mainframe</figcaption>
  </figure>

</p>
<p>The routers that connected systems to the ARPANET were known as Interface Message Processors or IMPs. They were based on a 16-bit Honeywell computer design from 1969, and the CPU registers could only handle 16 bits at once. This meant that just reading a 32-bit address required multiple instructions. Processing addresses longer than 32 bits would have slowed down handling of network data, particularly if the addresses had been of variable length like in the early IP drafts.</p>
<p>
  <figure>
    <img src="imp.webp" alt="Front panel of an IMP">
    <figcaption>The front panel of an IMP</figcaption>
  </figure>

</p>
<p>In 1992, <a href="https://www.rfc-editor.org/rfc/rfc1338.html">RFC 1338</a> discussed the “[g]rowth of routing tables in Internet routers beyond the ability of current software (and people) to effectively manage”, so the added cost in CPU and memory from going beyond 32 bit addresses would have been a real issue.</p>
<p>It’s also worth remembering what <em>didn’t</em> exist in 1980.</p>
<p>Firstly, there was no standardized commercial Ethernet. Offices generally didn’t have local networks; people typically shared data by passing floppy disks around.</p>
<p>
  <figure>
    <img src="floppy.webp" alt="An 8&quot; floppy disk">
    <figcaption>A floppy disk — 100 KiB of storage in just 8 inches</figcaption>
  </figure>

</p>
<p>Even when businesses started to use office LANs in the mid 1980s, it wasn’t clear that TCP/IP would become the standard. IBM had a system called Token Ring, Novell had a protocol called IPX/SPX, Microsoft and 3Com had LAN Manager, and Apple had AppleTalk. Windows didn’t even ship with TCP/IP support built in until Windows NT in 1993.</p>
<p>There were no mobile phones. The first would be the brick-sized DynaTAC, released in 1983. It was entirely analog, so it couldn’t have connected to the Internet anyway. Digital mobile phones didn’t appear until 1991. The idea of a handheld computer connected to a wireless network was science fiction alien technology, like in the Hitchhiker’s Guide to the Galaxy.</p>
<p>
  <figure>
    <img src="dynatac.webp" alt="A Motorola DynaTAC">
    <figcaption>A Motorola DynaTAC mobile phone</figcaption>
  </figure>

</p>
<p>The closest thing to email that most businesses had was Telex, which ran over regular telephone wires at a speed of about 10 characters per second. Businesses such as banks that needed to transmit data quickly used X.25, run by the telecom companies.</p>
<p>
  <figure>
    <img src="telex.webp" alt="A Telex machine">
    <figcaption>A Telex machine</figcaption>
  </figure>

</p>
<p>The most popular home computers were the Commodore PET, Radio Shack TRS-80, and Apple II. They were all 8-bit computers, using 16-bit addresses, and limited to 64 KiB of memory. A total of <a href="https://arstechnica.com/features/2005/12/total-share/">just under 1 million personal computers</a> had been sold.</p>
<p>As far as dial-up services go, CompuServe was brand new in 1980. A service called The Source had existed for about a year — for those who could afford to pay $200 for a modem, $100 for a subscription, and $2.75 per hour while using the service. In 2026 dollars, that’s nearly $1,000 for the modem, $390 to join, and about $10 an hour for the service, so as you can imagine very few computer users signed up. Also, The Source wasn’t connected to the Internet, and nor were CompuServe, AOL or Prodigy when they eventually appeared — there was no dial-up Internet until 1989.</p>
<p>
  <img src="trs80modem.webp" alt="Ad for a TRS-80 modem that could access The Source">

</p>
<h2 id="the-conclusion">The conclusion</h2>
<p>So to go back to the question of why IPv4 addresses didn’t have more bits: when TCP/IP version 4 was designed, less than half of one percent of people in the US had personal computers. None of those computers were on networks, hardly anyone had a modem, there were no mobile digital devices, and even when businesses started deploying office networks a few years later those weren’t TCP/IP!</p>
<p>Given that context, I think it’s understandable that the designers of TCP/IP didn’t foresee that we would each want to connect a phone, a computer, and often a TV to what was at the time an experimental research network. They can be similarly excused for not guessing that one day we would connect our fridges, washing machines, wrist watches and light bulbs to their network as well.</p>
<p>In addition, making IPv4 addresses longer would have slowed down processing by the routers used at the time, and making the addresses variable length would have slowed things even more. (In fact, one of the benefits of IPv6 is that it has fixed size headers.)  Like so many decisions we come to regret in the world of computers, the limited address space of IPv4 can be viewed as a performance tradeoff.</p>
<p>At the start of this article I mentioned that we ran out of IPv4 addresses in 2011. That being the case, you might wonder how the Internet continues to function. The answer is that starting in the 1990s, a number of short-term workarounds were implemented to delay the inevitable. One that you might be familiar with is Network Address Translation or NAT, the thing that sometimes ruins your online gaming. The large blocks of addresses were also broken up, and companies were encouraged to return address space that they weren’t using.</p>
<p>The real solution, however, is IPv6. Every mainstream operating system now supports it by default — Linux, macOS and Windows, iOS and Android. If your ISP supports it, you have it right now, even if you don’t know it. In fact, even if your ISP <em>doesn’t</em> support IPv6 you still have it on your home network, but that’s another story…</p>
<hr>
<p><strong>Image credits</strong></p>
<ul>
<li>Apple II: <a href="https://www.pexels.com/photo/vintage-circuit-board-with-microprocessors-and-components-34920249/">Nicolas Foster</a>.</li>
<li>Cray-1: <a href="https://images.nasa.gov/details/ARC-1981-AC81-0712">NASA</a> Ames Research Center, 1981.</li>
<li>DynaTAC: <a href="https://visualhunt.co/a7/72e0cf87">mikek</a> via <a href="https://visualhunt.com/re10/acd6828d">VisualHunt</a>.</li>
<li>IBM 3081: Norsk Teknisk Museum, <a href="https://creativecommons.org/licenses/by-sa/3.0">CC BY-SA 3.0</a>, via Wikimedia Commons.</li>
<li>IMP: <a href="https://www.flickr.com/photos/fastlizard4/6294438012/">Andrew Adams</a>, <a href="https://creativecommons.org/licenses/by-sa/2.0/">CC BY-SA 2.0</a>.</li>
<li>Telex: <a href="https://www.flickr.com/photos/ajmexico/">ajmexico on Flickr</a>, <a href="https://creativecommons.org/licenses/by/2.0/">CC BY 2.0</a>.</li>
<li>Terminal: <a href="https://www.flickr.com/photos/54568729@N00/9636183501">Jason Scott on Flickr</a>, <a href="https://creativecommons.org/licenses/by/2.0/">CC BY 2.0</a>.</li>
</ul>
]]></content></entry><entry><title type="html">AWS S3: An error occurred (ExpiredToken)… The provided token has expired</title><link href="https://lpar.ATH0.com/posts/2024/03/aws-s3-an-error-occurred-expiredtoken-the-provided-token-has-expired/"/><id>https://lpar.ATH0.com/posts/2024/03/aws-s3-an-error-occurred-expiredtoken-the-provided-token-has-expired/</id><published>2024-03-12T12:56:17-05:00</published><updated>2024-03-12T12:56:17-05:00</updated><summary>A mysterious error from AWS when you’re not even using tokens, and how to fix it.</summary><content type="html"><![CDATA[<p>The problem:</p>
<p>You’re trying to access AWS S3 using the CLI utility, via (say) <code>aws s3 ls</code>. You’re supplying credentials via <code>AWS_ACCESS_KEY_ID</code> and <code>AWS_SECRET_ACCESS_KEY</code>. You get an error:</p>
<pre tabindex="0"><code>An error occurred (ExpiredToken) when calling the ListBuckets operation:
The provided token has expired.
</code></pre><p>The solution:</p>
<p>You need to set <code>AWS_SESSION_TOKEN</code> to an empty string. Otherwise the AWS CLI grabs a session token from who knows where and tries to use that.</p>
<p>This problem also seems to affect <code>s3cmd</code>, presumably because it uses Amazon’s AWS libraries.</p>
]]></content></entry><entry><title type="html">Language wish list</title><link href="https://lpar.ATH0.com/posts/2023/12/language-wish-list/"/><id>https://lpar.ATH0.com/posts/2023/12/language-wish-list/</id><published>2023-12-23T19:19:16-06:00</published><updated>2023-12-23T19:19:16-06:00</updated><summary>Or: why I’m not going to use your favorite programming language.</summary><content type="html"><![CDATA[<p>I’ve written code in well over a dozen programming languages. I’m always ready to learn another, and there’s always someone eager to sell me on their favorite.</p>
<p>However, if I’m going to learn a new language at this point, it has to be a better fit for me than the ones I’m already using and the ones I’ve already tried and abandoned. No language is perfect, and I could criticize even my favorites, but some are a better match to my needs and desires than others.</p>
<p>So to save time, here’s what I’m looking for in any new programming language, with examples to try to clarify what I mean.</p>
<h3 id="platform-support">Platform support</h3>
<p>Unix family, specifically including macOS and Linux.</p>
<p>AMD64, ARM and RISC-V.</p>
<p>I don’t care about Windows.</p>
<h3 id="licensing">Licensing</h3>
<p>Open source with a free software license, so it can’t suddenly be destroyed by a malicious corporation.</p>
<h3 id="syntax">Syntax</h3>
<p>I have a hard time remembering syntax, so I want something that’s simple. Ideally it should also be clean and easy to read, with a minimum of sigils and operators.</p>
<p>Good: Scheme, Go, Ruby<br>
Adequate: Java, Swift<br>
Horrible: C++, Perl, Rust</p>
<h3 id="library">Library</h3>
<p>I want the standard library to have good coverage of POSIX APIs. Again, I don’t care about Windows. The standard library should have support for TCP/IP connections, UDP, Unix domain sockets, Unix permissions, standard cryptographic algorithms, JSON and XML and base64, Unicode, and so on, or else it’s just a toy language.</p>
<p>I also want a standard package manager. Just one, maybe two tops.</p>
<p>Good: Ruby, Go<br>
Adequate: Java<br>
Horrible: Scheme, JavaScript</p>
<h3 id="interoperability">Interoperability</h3>
<p>Since I’m not going to be able to find <em>everything</em> for this new language, I need to have the option of occasionally using code written in something else. That means I want some reasonable FFI option.</p>
<p>Good: C, Zig, Kotlin.<br>
Adequate: Go.<br>
Horrible: Java.</p>
<h3 id="language-features">Language features</h3>
<p>These are in approximate descending importance:</p>
<ul>
<li>
<p>Basic types: unsigned bytes, 32 and 64 bit unsigned integers, signed integers, strings, variable-length arrays, hashes/maps.</p>
</li>
<li>
<p><em>Decimal</em> floating point numbers (decimal64 and decimal128).</p>
</li>
<li>
<p>UTF-8 support throughout the entire language.</p>
</li>
<li>
<p>Static typing with compile-time type checking.</p>
</li>
<li>
<p>Lexical scoping.</p>
</li>
<li>
<p>Object-orientation through composition.</p>
</li>
<li>
<p>Automatic memory management, either through a fast garbage collector or through some sort of unintrusive and robust reference-counting system. (Examples: Go, Rust.)</p>
</li>
<li>
<p>First-class functions.</p>
</li>
<li>
<p>Functions that can return tuples. (Examples: Ruby, JavaScript, Go.)</p>
</li>
<li>
<p>Fast compile times. (Example: Go. Horrible: C++.)</p>
</li>
<li>
<p>Trivially easy cross-compilation. And by trivially easy, I mean “set one option on the compile command and you’re done” easy. (Example: Go.)</p>
</li>
<li>
<p>More advanced types: arbitrary precision integers, arbitrary precision decimal floating point numbers, rationals.</p>
</li>
<li>
<p>Immutability by default. (Examples: Scala, Haskell.)</p>
</li>
<li>
<p>Tail-call elimination.</p>
</li>
<li>
<p>Function overloading.</p>
</li>
<li>
<p>Parametric polymorphism.</p>
</li>
<li>
<p>Facilities to make safe concurrency easier, such as CSP structures. (Examples: Go, Kotlin.)</p>
</li>
<li>
<p>Small binaries and a lightweight runtime. (Examples: Zig, C.)</p>
</li>
<li>
<p>A good native GUI option for macOS and Linux.</p>
</li>
<li>
<p>One defined standard set of formatting conventions, and a formatter to implement them. (Example: Go.)</p>
</li>
</ul>
<h3 id="unimportant">Unimportant</h3>
<p>Things I don’t particularly want or care about but I’m OK with them:</p>
<ul>
<li>
<p>OO class inheritance.</p>
</li>
<li>
<p>Ubiquitous type inference. (I prefer to state my types, thanks.)</p>
</li>
<li>
<p>Multiple implementations.</p>
</li>
<li>
<p>Option types.</p>
</li>
<li>
<p>Binary floating point numbers.</p>
</li>
</ul>
<h3 id="undesirable">Undesirable</h3>
<p>Things I don’t want, but I’m willing to put up with them:</p>
<ul>
<li>
<p>Pointers.</p>
</li>
<li>
<p>Null (used to represent an absent value, like in SQL).</p>
</li>
<li>
<p>Nil (a zero value, like in Go).</p>
</li>
</ul>
<h3 id="deal-killers">Deal killers</h3>
<p>There are some things I’m just not willing to put up with:</p>
<ul>
<li>
<p>Semantic whitespace. (Examples: Python, YAML.)</p>
</li>
<li>
<p>A de facto requirement for containers or virtual environments. (Examples: Python, JavaScript.)</p>
</li>
<li>
<p>A required special IDE. (Examples: Smalltalk.)</p>
</li>
</ul>
]]></content></entry><entry><title type="html">Reading instance tags in Amazon EC2</title><link href="https://lpar.ATH0.com/posts/2020/11/reading-instance-tags-in-amazon-ec2/"/><id>https://lpar.ATH0.com/posts/2020/11/reading-instance-tags-in-amazon-ec2/</id><published>2020-11-11T16:21:53-06:00</published><updated>2020-11-11T16:21:53-06:00</updated><summary>A useful but underdocumented procedure.</summary><content type="html"><![CDATA[<p>One of the great things about Go as a cloud development language is that it’s very easy to ship everything as a single self-contained binary. At work we build a single cloud image which can be deployed in a number of configurations, depending on the functionality needed. It can be a staging server or a production server, eventually it’ll also support being a dedicated server or a self-hosted one; and of course, it can be run locally for development and debugging.</p>
<p>To handle this, the binary needs to look at its runtime metadata for information about what we expect it to do. While this is really easy on Cloud Foundry platforms — just look at environment variables — it turns out to be significantly more involved on Amazon Web Services (AWS) when running in Elastic Compute Cloud (EC2).</p>
<p>The first problem is picking an official SDK. There’s the official <a href="https://aws.amazon.com/sdk-for-go/">SDK for Go</a>, which at the time of writing is at v1.35.26; but there’s also the <a href="https://github.com/aws/aws-sdk-go-v2">developer preview of the v2 SDK</a>, which is confusingly tagged as v0.29.0. The v0.29.0 SDK “v2” is more recent than the v1.35.26 SDK, and at first glance has more functionality. Unfortunately, although it was released <a href="https://aws.amazon.com/blogs/developer/client-updates-in-the-preview-version-of-the-aws-sdk-for-go-v2/">back in 2017</a>, they’re still making <a href="https://github.com/aws/aws-sdk-go-v2/issues/820">breaking changes</a> in 2020. Documentation is missing or incorrect, examples don’t even compile. With that in mind, I decided to stick with the old SDK until things settle down. So, here’s how to get the tags for the running EC2 instance, using only the original AWS Go SDK.</p>
<p>I’ll start off by listing the libraries I used:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="kn">import</span><span class="w"> </span><span class="p">(</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="s">&#34;errors&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="s">&#34;fmt&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="s">&#34;github.com/aws/aws-sdk-go/aws&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="s">&#34;github.com/aws/aws-sdk-go/aws/ec2metadata&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="s">&#34;github.com/aws/aws-sdk-go/aws/session&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="s">&#34;github.com/aws/aws-sdk-go/service/ec2&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">)</span><span class="w">
</span></span></span></code></pre></div><p>The first step is to find out the region and instance ID of the running instance. It’s obvious enough why the instance ID is needed, but you might be wondering why the region. It turns out that the EC2 APIs don’t default to the current region; instead, they demand that you specify the current region explicitly for any operation, or else you get <code>MissingRegion: could not find region configuration</code> returned as an error.</p>
<p>The code actually works by connecting to the instance metadata service, which is available at http://169.254.169.254/ inside the instance. In the shell, you might query it via <code>curl</code>:</p>
<pre><code>curl http://169.254.169.254/latest/meta-data/instance-id
</code></pre>
<p>So I <em>could</em> have used Go’s HTTP client, but I wanted to do things the official way. The official Go equivalent of the above <code>curl</code> command looks like this:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="w">	</span><span class="nx">sess</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">session</span><span class="p">.</span><span class="nf">New</span><span class="p">()</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nx">svc</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">ec2metadata</span><span class="p">.</span><span class="nf">New</span><span class="p">(</span><span class="nx">sess</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="k">if</span><span class="w"> </span><span class="p">!</span><span class="nx">svc</span><span class="p">.</span><span class="nf">Available</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">		</span><span class="nb">panic</span><span class="p">(</span><span class="s">&#34;ec2metadata service not available&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nx">instance</span><span class="p">,</span><span class="w"> </span><span class="nx">err</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">svc</span><span class="p">.</span><span class="nf">GetMetadata</span><span class="p">(</span><span class="s">&#34;instance-id&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="k">if</span><span class="w"> </span><span class="nx">err</span><span class="w"> </span><span class="o">!=</span><span class="w"> </span><span class="kc">nil</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">		</span><span class="nb">panic</span><span class="p">(</span><span class="nx">fmt</span><span class="p">.</span><span class="nf">Errorf</span><span class="p">(</span><span class="s">&#34;can&#39;t get instance ID: %w&#34;</span><span class="p">,</span><span class="w"> </span><span class="nx">err</span><span class="p">))</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="p">}</span><span class="w">
</span></span></span></code></pre></div><p>The SDK uses an <code>aws/client</code> to make an HTTP call to get the info. The <code>ec2metadata.GetMetadata</code> call takes a string argument. It’s <a href="https://docs.aws.amazon.com/sdk-for-go/api/aws/ec2metadata/#EC2Metadata.GetMetadata">documented to be a path</a>, but as you can see it’s not simply the entire path you would use with a curl command. Fortunately the SDK is open source, and delving into the code reveals that it’s the part of the service path that comes after <code>/latest/meta-data/</code></p>
<p>Until quite recently, many people looked up the region by looking up the Availability Zone (AZ) and mapping that back to the region. That usually meant removing the last character — for example, AZ <code>us-east-1c</code> is region <code>us-east-1</code> — but of course, there was no guarantee that rule would continue to hold true, so I ruled that approach out.</p>
<p>Fortunately, a few months ago someone at Amazon got the developers to <a href="https://forums.aws.amazon.com/message.jspa?messageID=951372#951372">add an API call</a> to the <code>ec2metadata</code> service to fetch the region. It doesn’t look like there’s any documentation of it yet, but you can fetch the Region as <code>http://169.254.169.254/latest/meta-data/placement/region</code>, or by passing the path <code>placement/region</code> to ec2metadata.GetMetadata exactly as for <code>instance-id</code> above. So now we can write a utility function to get the region and instance ID:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="kd">func</span><span class="w"> </span><span class="nf">getRegionAndInstance</span><span class="p">()</span><span class="w"> </span><span class="p">(</span><span class="kt">string</span><span class="p">,</span><span class="w"> </span><span class="kt">string</span><span class="p">,</span><span class="w"> </span><span class="kt">error</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nx">sess</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">session</span><span class="p">.</span><span class="nf">New</span><span class="p">()</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nx">svc</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">ec2metadata</span><span class="p">.</span><span class="nf">New</span><span class="p">(</span><span class="nx">sess</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="k">if</span><span class="w"> </span><span class="p">!</span><span class="nx">svc</span><span class="p">.</span><span class="nf">Available</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">		</span><span class="k">return</span><span class="w"> </span><span class="s">&#34;&#34;</span><span class="p">,</span><span class="s">&#34;&#34;</span><span class="p">,</span><span class="w"> </span><span class="nx">errors</span><span class="p">.</span><span class="nf">New</span><span class="p">(</span><span class="s">&#34;ec2metadata service not available&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nx">instance</span><span class="p">,</span><span class="w"> </span><span class="nx">err</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">svc</span><span class="p">.</span><span class="nf">GetMetadata</span><span class="p">(</span><span class="s">&#34;instance-id&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="k">if</span><span class="w"> </span><span class="nx">err</span><span class="w"> </span><span class="o">!=</span><span class="w"> </span><span class="kc">nil</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">		</span><span class="k">return</span><span class="w"> </span><span class="s">&#34;&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;&#34;</span><span class="p">,</span><span class="w"> </span><span class="nx">fmt</span><span class="p">.</span><span class="nf">Errorf</span><span class="p">(</span><span class="s">&#34;can&#39;t get instance ID: %w&#34;</span><span class="p">,</span><span class="w"> </span><span class="nx">err</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nx">region</span><span class="p">,</span><span class="w"> </span><span class="nx">err</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">svc</span><span class="p">.</span><span class="nf">GetMetadata</span><span class="p">(</span><span class="s">&#34;placement/region&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="k">if</span><span class="w"> </span><span class="nx">err</span><span class="w"> </span><span class="o">!=</span><span class="w"> </span><span class="kc">nil</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">		</span><span class="k">return</span><span class="w"> </span><span class="s">&#34;&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;&#34;</span><span class="p">,</span><span class="w"> </span><span class="nx">fmt</span><span class="p">.</span><span class="nf">Errorf</span><span class="p">(</span><span class="s">&#34;can&#39;t get region: %w&#34;</span><span class="p">,</span><span class="w"> </span><span class="nx">err</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="k">return</span><span class="w"> </span><span class="nx">region</span><span class="p">,</span><span class="w"> </span><span class="nx">instance</span><span class="p">,</span><span class="w"> </span><span class="kc">nil</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span></code></pre></div><p>But there’s another way to do it. If you fetch the entire <a href="https://docs.aws.amazon.com/sdk-for-go/api/aws/ec2metadata/#EC2InstanceIdentityDocument">Instance Identity Document</a> using <code>ec2metadata.GetInstanceIdentityDocument</code>, it contains both the instance ID and the region:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="kd">func</span><span class="w"> </span><span class="nf">getRegionAndInstance2</span><span class="p">()</span><span class="w"> </span><span class="p">(</span><span class="kt">string</span><span class="p">,</span><span class="w"> </span><span class="kt">string</span><span class="p">,</span><span class="w"> </span><span class="kt">error</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nx">sess</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">session</span><span class="p">.</span><span class="nf">New</span><span class="p">()</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nx">svc</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">ec2metadata</span><span class="p">.</span><span class="nf">New</span><span class="p">(</span><span class="nx">sess</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="k">if</span><span class="w"> </span><span class="p">!</span><span class="nx">svc</span><span class="p">.</span><span class="nf">Available</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">		</span><span class="k">return</span><span class="w"> </span><span class="s">&#34;&#34;</span><span class="p">,</span><span class="s">&#34;&#34;</span><span class="p">,</span><span class="w"> </span><span class="nx">errors</span><span class="p">.</span><span class="nf">New</span><span class="p">(</span><span class="s">&#34;ec2metadata service not available&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nx">idd</span><span class="p">,</span><span class="w"> </span><span class="nx">err</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">svc</span><span class="p">.</span><span class="nf">GetInstanceIdentityDocument</span><span class="p">()</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="k">if</span><span class="w"> </span><span class="nx">err</span><span class="w"> </span><span class="o">!=</span><span class="w"> </span><span class="kc">nil</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">		</span><span class="k">return</span><span class="w"> </span><span class="s">&#34;&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;&#34;</span><span class="p">,</span><span class="w"> </span><span class="nx">fmt</span><span class="p">.</span><span class="nf">Errorf</span><span class="p">(</span><span class="s">&#34;can&#39;t get instance identity document: %w&#34;</span><span class="p">,</span><span class="w"> </span><span class="nx">err</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="k">return</span><span class="w"> </span><span class="nx">idd</span><span class="p">.</span><span class="nx">Region</span><span class="p">,</span><span class="w"> </span><span class="nx">idd</span><span class="p">.</span><span class="nx">InstanceID</span><span class="p">,</span><span class="w"> </span><span class="kc">nil</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span></code></pre></div><p>Is that better? On the plus side, the SDK only has to make a single HTTP request; on the minus side, it has to fetch and deserialize an entire JSON object into a struct, most of which we don’t need. For my usage, running it once when our web application starts up, it really doesn’t matter which we use, both are fast.</p>
<p>Whichever you choose, you should now have the region and instance ID, so it’s time to move on to the difficult part, fetching the tags as a map of strings.</p>
<p>The first trick is that although tags are metadata, you can’t get them using the <code>ec2metadata</code> service; you need to go in through the main <code>ec2</code> API instead, setting up the region first as mentioned above:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="w">	</span><span class="nx">sess</span><span class="p">,</span><span class="w"> </span><span class="nx">err</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">session</span><span class="p">.</span><span class="nf">NewSession</span><span class="p">(</span><span class="o">&amp;</span><span class="nx">aws</span><span class="p">.</span><span class="nx">Config</span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">		</span><span class="nx">Region</span><span class="p">:</span><span class="w"> </span><span class="nx">aws</span><span class="p">.</span><span class="nf">String</span><span class="p">(</span><span class="nx">region</span><span class="p">)},</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nx">svc</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">ec2</span><span class="p">.</span><span class="nf">New</span><span class="p">(</span><span class="nx">sess</span><span class="p">)</span><span class="w">
</span></span></span></code></pre></div><p>(Thanks to Claes Mogren for pointing me in the right direction.)</p>
<p>The next problem is that there isn’t a <code>GetInstanceTags</code> method. Instead, there’s a general purpose <code>DescribeTags</code> method to fetch information about any resource of any type, and you have to set up filters to restrict its output to the actual object you want. Those filters are specified as a field of a <code>DescribeTagsInput</code> object. After examining some examples, I arrived at the following code:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="w">	</span><span class="nx">input</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="o">&amp;</span><span class="nx">ec2</span><span class="p">.</span><span class="nx">DescribeTagsInput</span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">		</span><span class="nx">Filters</span><span class="p">:</span><span class="w"> </span><span class="p">[]</span><span class="o">*</span><span class="nx">ec2</span><span class="p">.</span><span class="nx">Filter</span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">			</span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">				</span><span class="nx">Name</span><span class="p">:</span><span class="w">   </span><span class="nx">aws</span><span class="p">.</span><span class="nf">String</span><span class="p">(</span><span class="s">&#34;resource-type&#34;</span><span class="p">),</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">				</span><span class="nx">Values</span><span class="p">:</span><span class="w"> </span><span class="p">[]</span><span class="o">*</span><span class="kt">string</span><span class="p">{</span><span class="nx">aws</span><span class="p">.</span><span class="nf">String</span><span class="p">(</span><span class="s">&#34;instance&#34;</span><span class="p">)},</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">			</span><span class="p">},</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">			</span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">				</span><span class="nx">Name</span><span class="p">:</span><span class="w">   </span><span class="nx">aws</span><span class="p">.</span><span class="nf">String</span><span class="p">(</span><span class="s">&#34;resource-id&#34;</span><span class="p">),</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">				</span><span class="nx">Values</span><span class="p">:</span><span class="w"> </span><span class="p">[]</span><span class="o">*</span><span class="kt">string</span><span class="p">{</span><span class="nx">aws</span><span class="p">.</span><span class="nf">String</span><span class="p">(</span><span class="nx">instance</span><span class="p">)},</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">			</span><span class="p">},</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">		</span><span class="p">},</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="p">}</span><span class="w">
</span></span></span></code></pre></div><p>All this complexity is so that you can have filters on any property of any object, using single or multiple values, or presumably even null (<code>nil</code>) values. Not really the Go way; it reminds me of LDAP or JNDI. But, that’s the way the v1 Go SDK needs it done.</p>
<p>Given that the input was a <code>DescribeTagsInput</code> object, you might have already guessed that what you get back from <code>DescribeTags</code> is a <code>DescribeTagsOutput</code> object, which also implements an overly general system of structs and pointers so that keys and values, and even the entire list of tags returned, can be allowed to be <code>nil</code>. So the final task is to run through that, and turn it into an idiomatic Go <code>map[string]string</code> of the non-nil values, so we can easily query or range over our tags:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="w">	</span><span class="nx">tags</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nb">make</span><span class="p">(</span><span class="kd">map</span><span class="p">[</span><span class="kt">string</span><span class="p">]</span><span class="kt">string</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="nx">result</span><span class="p">,</span><span class="w"> </span><span class="nx">err</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">svc</span><span class="p">.</span><span class="nf">DescribeTags</span><span class="p">(</span><span class="nx">input</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="k">if</span><span class="w"> </span><span class="nx">err</span><span class="w"> </span><span class="o">!=</span><span class="w"> </span><span class="kc">nil</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">		</span><span class="k">return</span><span class="w"> </span><span class="nx">tags</span><span class="p">,</span><span class="w"> </span><span class="nx">fmt</span><span class="p">.</span><span class="nf">Errorf</span><span class="p">(</span><span class="s">&#34;ec2.DescribeTags failed: %w&#34;</span><span class="p">,</span><span class="w"> </span><span class="nx">err</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="k">if</span><span class="w"> </span><span class="nx">result</span><span class="p">.</span><span class="nx">Tags</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="kc">nil</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	    </span><span class="k">return</span><span class="w"> </span><span class="nx">tags</span><span class="p">,</span><span class="w"> </span><span class="kc">nil</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="k">for</span><span class="w"> </span><span class="nx">_</span><span class="p">,</span><span class="w"> </span><span class="nx">t</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="k">range</span><span class="w"> </span><span class="nx">result</span><span class="p">.</span><span class="nx">Tags</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	    </span><span class="k">if</span><span class="w"> </span><span class="nx">t</span><span class="w"> </span><span class="o">!=</span><span class="w"> </span><span class="kc">nil</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">			</span><span class="nx">k</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">t</span><span class="p">.</span><span class="nx">Key</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">			</span><span class="nx">v</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">t</span><span class="p">.</span><span class="nx">Value</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">			</span><span class="k">if</span><span class="w"> </span><span class="nx">k</span><span class="w"> </span><span class="o">!=</span><span class="w"> </span><span class="kc">nil</span><span class="w"> </span><span class="o">&amp;&amp;</span><span class="w"> </span><span class="nx">v</span><span class="w"> </span><span class="o">!=</span><span class="w"> </span><span class="kc">nil</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">				</span><span class="nx">tags</span><span class="p">[</span><span class="o">*</span><span class="nx">k</span><span class="p">]</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="o">*</span><span class="nx">v</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">			</span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">		</span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">	</span><span class="p">}</span><span class="w">
</span></span></span></code></pre></div><p>Of course, if you need to support <code>nil</code> tag names and/or <code>nil</code> tag values, this won’t work for you, and you’ll have to deal with the <code>[]*TagDescription</code> in all its glory.</p>
<p>The final code, with both options for fetching the region and instance ID, is <a href="https://gist.github.com/lpar/f3836238961586b658c9295e86a31c78">in a gist</a>. I hope it saves you from the frustration I went through trying to find this stuff out.</p>
]]></content></entry><entry><title type="html">Farewell to scp</title><link href="https://lpar.ATH0.com/posts/2020/11/farewell-to-scp/"/><id>https://lpar.ATH0.com/posts/2020/11/farewell-to-scp/</id><published>2020-11-07T16:49:34-06:00</published><updated>2020-11-07T16:49:34-06:00</updated><summary>Don’t panic, there’s something much better.</summary><content type="html"><![CDATA[<p>I’ve seen some people upset about the fact that <code>scp</code> <a href="https://lwn.net/SubscriberLink/835962/ae41b27bc20699ad/">has been deprecated</a>. If you’ve never used <code>scp</code>, it basically tries to be a version of <code>cp</code> that works between computers, via an SSH connection. I haven’t used it in a long, long time, because I use <code>rsync</code> instead. While there will eventually be something that works like <code>scp</code> but using the SFTP protocol, I’d like to suggest that the far superior option is to learn <code>rsync</code> and switch to that, as I did a long time ago.</p>
<p>Here are some key benefits of <code>rsync</code>:</p>
<ul>
<li>By default, it only transfers files it needs to, and only transfers the parts of those files that aren’t already present at the destination. When dealing with things like huge log files and directories with thousands of files, this can save a lot of time.</li>
<li>If it fails part way through because of a network error, you can just run it again, and it will pick up where it left off.</li>
<li>It can verify that files are byte-for-byte identical after transfer.</li>
<li>It will preserve permissions, timestamps, and other file metadata.</li>
<li>It transfers all the data securely via SSH, just like <code>scp</code>.</li>
</ul>
<p>However, the <code>rsync</code> manual page is extremely long and has a ridiculous number of options listed, and I think a lot of people look at it and decide they don’t have time for all that. So, here’s my summary of everything you need to know to handle 99% of day-to-day file transfer tasks using <code>rsync</code>.</p>
<h2 id="move-one-file-from-here-to-there">Move one file from here to there</h2>
<p>Here’s an example incantation:</p>
<pre tabindex="0"><code>rsync -a path/to/file example.com:remote/path/to/file
</code></pre><p>The <code>-a</code> option is a shortcut for a bunch of individual options that you almost certainly want to ensure that the remote file ends up the same as the local file in terms of permissions, timestamps and ownership.</p>
<p>You might guess that you can add a <code>-v</code> flag to get verbose output, and you’d be right. Almost all my usage of <code>rsync</code> starts with <code>rsync -av</code>. (You can also do <code>rsync -a -v</code> of course.)</p>
<p>Either path can start with <code>/</code> if you want to specify an absolute path from the root directory. Otherwise, the local path starts from the current directory, and the remote path starts from your SSH login directory, as you’d expect:</p>
<pre tabindex="0"><code>rsync -a /home/steve/log.txt example.com:/tmp/steve-log.txt
</code></pre><h2 id="move-one-file-from-there-to-here">Move one file from there to here</h2>
<p>Exactly the same, but with the source and destination in the opposite order:</p>
<pre tabindex="0"><code>rsync -av example.com:Music/startup.mp3 ~/Music/start-me-up.mp3
</code></pre><p>This general principle works for all these examples, you can flip source and destination to move data the other way.</p>
<h2 id="move-any-number-of-files-into-a-remote-directory">Move any number of files into a remote directory</h2>
<p>Now comes the part that trips people up. The <code>rsync</code> program will also work on directories, but to get the results you probably expect, you’ll want to remember to put a trailing <code>/</code> on any path that points at a directory. For example:</p>
<pre tabindex="0"><code>rsync -av *.jpeg somemachine.local:/tmp/
</code></pre><p>Going the other way, you’ll need to use some quoting so that your shell doesn’t try to expand the wildcard:</p>
<pre tabindex="0"><code>rsync -avs &#34;remote.example.com:Pictures/*.jpg&#34; Pictures/
</code></pre><h2 id="copy-everything-from-one-directory-to-another">Copy everything from one directory to another</h2>
<p>This is why I love <code>rsync</code>. I can do this:</p>
<pre tabindex="0"><code>rsync -av Software/ newbox.local:Software/
</code></pre><p>Everything from the source directory will be transferred to the destination directory. Note the destination slash symbols on both directory paths. (The fish shell autocompletes the directories with the trailing slashes, by the way.)</p>
<p>If there are already files in the destination which aren’t in the source, they’ll be left alone. If you don’t want this, and want the destination to end up exactly like the source, the <code>--delete</code> flag will do the trick:</p>
<pre tabindex="0"><code>rsync -av --delete Software/ newbox.local:Software/
</code></pre><p>After this, the destination will hold exactly the same contents as the source.</p>
<h2 id="ssh-tweaks">SSH tweaks</h2>
<p>You might wonder how to handle it if you need to specify a username for the SSH connection. The answer is you can specify the SSH command to use via <code>-e</code>. For example:</p>
<pre tabindex="0"><code>rsync -av -e &#39;ssh -l myusername&#39; local/*.jpg remote.example.com:Photos/
</code></pre><p>If you use that remote system regularly, though, it’s probably easier to create an entry in your <code>~/.ssh/config</code> file so you don’t need to do that. You can also specify a port and IP address override the same way:</p>
<pre tabindex="0"><code>Host remote.example.com
    HostName 10.34.1.40
    User myusername
    Port 663
</code></pre><h2 id="additional-tips">Additional tips</h2>
<p>If you know that <code>rsync</code> is going to need to transfer entire files because they’re totally different from what’s in the destination, and if the computers and disks involved in the transfer are slow, you can save time by telling it that. The <code>-W</code> option (or <code>--whole-file</code>) says to copy whole files rather than using binary diffing to find the changes.</p>
<p>For the opposite situation, where the network is slow and the computers are fast, the <code>-z</code> option will compress all the data in transit and decompress it again at the far end.</p>
<p>By default, <code>rsync</code> uses a temporary file on the destination system, and then renames it into place when it’s fully transferred. This is to try to prevent other programs from seeing incomplete files, but if you don’t need that feature you can tell <code>rsync</code> to just go ahead and use the final filename rather than a temporary file, using the <code>--inplace</code> flag.</p>
<p>If the destination path has spaces in, the shell on the destination system can mess up the transfer. To avoid this, use the <code>-s</code> option to bypass the shell on the destination system. (This feature is missing from the default version of <code>rsync</code> supplied with macOS.)</p>
<p>If you add the <code>--dry-run</code> flag (<code>-n</code>), <code>rsync</code> won’t actually transfer or delete anything, it’ll just tell you what it <em>would</em> do.</p>
<p>If you don’t need all the details from <code>-v</code> but do want to know what it did, the <code>-i</code> or <code>--itemize-changes</code> option will make it print a concise list of updates.</p>
<h2 id="not-using-ssh-at-all">Not using SSH at all</h2>
<p>If you omit any hostname from the <code>rsync</code> command, no SSH connection is used. Instead, <code>rsync</code> works as a local copy command. This means you can use it for directory synchronization between local disks, for example making backups:</p>
<pre tabindex="0"><code>rsync -av ~/Photos/ /mnt/backup/Photos/
</code></pre><p>You can also use it with <code>--dry-run</code> to compare two directories and display which files are different.</p>
<h2 id="and-more">And more</h2>
<p>As I said at the start, <code>rsync</code> has a large number of options. Once you’ve mastered the basics, you’ll probably find that for any weird file transfer problem you have, there’s an <code>rsync</code> option that can help.</p>
<p>For example, one time I had a bunch of files on an MS-DOS FAT filesystem on a very slow USB device. I wanted to copy on some more and merge them into place, but I really wanted to avoid unnecessary data transfer. The solution involved telling rsync to trust that files were identical if their timestamps and sizes were identical, and to compare timestamps with 2 second resolution to allow for lack of accuracy on FAT filesystems.</p>
]]></content></entry><entry><title type="html">Final notes on Notes</title><link href="https://lpar.ATH0.com/posts/2020/10/final-notes-on-notes/"/><id>https://lpar.ATH0.com/posts/2020/10/final-notes-on-notes/</id><published>2020-10-03T18:30:25-05:00</published><updated>2020-10-03T18:30:25-05:00</updated><summary>The application people love to hate.</summary><content type="html"><![CDATA[<p>Now that I’m no longer working for IBM, I’m saying goodbye to the application formerly known as Lotus Notes, as well as the server known as Domino. Both have been sold off and are now products of an Indian company called HCL Technologies, but they were still in heavy use within IBM.</p>
<p>Mention Notes online and you’ll usually encounter derision, particularly from people who think it’s an e-mail program. It <em>was</em> all too often sold as one, but that was really something it could incidentally handle, not what it was designed for.</p>
<p>To understand what Notes is, and why it is the way it is, you have to know that it was inspired by PLATO Notes in 1973, and development started in 1984. It predates widespread e-mail, the web, home Internet service providers, and every application people disparagingly compare it to.</p>
<p>At the bottom, it’s a database engine which supports any number of distributed document-based key-value databases. Nowadays we’d call it NoSQL, and compare it to something like CouchDB or RocksDB — but Notes shipped in 1988! Each base level set of keys and values in the database is called a note, hence the name of the product.</p>
<p>On top of the database engine is a graphical form designer. It works like a word processor mail merge, giving you a rich text document that you can drop fields into. Each field can have one of a range of basic data types, including string, number, date, and user ID. Fields can also allow multiple values to be entered. When you save using a form, the data is stored in a note, along with information saying which form should be used to display or edit it, when it was saved, who saved it, and so on.</p>
<p>Once you have some documents, you can create one or more views. A view is basically a programmatic “smart group” that fishes a defined set of documents out of the database, and displays values from their key/value fields in table format.</p>
<p>The original Notes offered a spreadsheet-like formula language for scripting. Later on, when Visual BASIC was the new hotness, a VB-like language was added that was more capable. Later still, partial JavaScript support was added.</p>
<p>As well as the data, all of the application design — the forms, views, scripts, and everything else — was itself stored in the database as notes. So Notes was that it handled all kinds of things for you with very little effort:</p>
<ul>
<li>Replicating data and working either online or offline.</li>
<li>Fine-grained access control at database, document and individual field level.</li>
<li>Authentication via public key cryptography.</li>
<li>Document signing</li>
<li>Software distribution</li>
</ul>
<p>Combine this with the ease of creating forms and views, and with a bit of practice you could put together applications for secure distributed multi-user collaboration in an afternoon, and then iterate on it rapidly. The only thing I’ve seen that approaches the development velocity is Ruby on Rails. (And Rails also gets its fair share of robust criticism.)</p>
<p>Of course, Notes applications would rarely have a polished, professional user interface, because they were usually developed in house by large corporations, without much attention paid to design. So like Visual BASIC before it, Notes as a whole got a bad reputation.</p>
<p>There were also some product decisions that were just mistakes. To pick just one example, “folders” in Notes don’t work like real physical folders. When they were implemented, the developers apparently thought it would be more flexible if a single object could be part of any number of folders, rather than limiting it to one and having to copy things to put them in more than one folder. That is indeed great if you’re an information management nerd or a computer scientist, and can understand why deleting something from one folder would make it disappear from every other folder it’s in. Unfortunately ordinary people don’t expect desktop folders or e-mail folders to work like that.</p>
<p>In the mid 90s when the web started to become important, Lotus added a component called Domino that would take your Notes applications and (mostly) manage to serve them up as web sites, as long as they didn’t try to do anything too complicated. Over time this became a core feature of the Notes server, and the entire server became known as Domino.</p>
<p>Under IBM’s ownership, major changes continued. By 2007, basically the entire product had been rebuilt from the bottom up using Java and the Eclipse framework. With that done, it was possible to use Java code in your Domino web applications. In 2008, a framework called XPages was built on top of JSF, and that became the easiest way to produce cutting edge web applications using Domino.</p>
<p>You could build servlets and run them in Domino. You could use JDBC. You could call Java libraries bundled in your application database as jar files. You could script dynamic web form behavior in JavaScript.</p>
<p>At some point, though, IBM’s interest in the product seemed to wane. Notes and Domino 9 were released in 2013, but in 2018 the latest release was still 9.0.1 (fix/feature pack 10). The Domino engine wasn’t improved much, and Notes applications served up as web pages were a mess of nested tables. XPages also languished, as the rest of the Java world moved to JSF 2. The JavaScript engine remained basically the same as at the turn of the century. Overall, it became more and more painful to develop modern web sites with Domino as a foundation. So on the whole, I’m glad to be saying goodbye to Domino.</p>
<p>Now that HCL are developing the product, major updates are happening again. For example, there’s a new client to make it fast and easy to deploy a Notes application to iPads. There have been some tough decisions, though; XPages is probably a dead end, as the work to update it to JSF 2 would be prohibitive, so instead the new thinking is to develop your web application with something else (NodeJS is often suggested) and use Domino as a simple NoSQL database. That’s all very well, but there are a lot of other NoSQL database options, not to mention SQL databases, and if you’re not going to use the Notes and Domino features, why invest in the platform? It’s probably a good strategy for hanging on to existing customers, but it doesn’t seem like a good way to grow the customer base.</p>
<p>Will Notes and Domino remain viable platforms for groupware development? I don’t know. What I do know is that it’s no longer something I personally have to worry about.</p>
]]></content></entry><entry><title type="html">Go HTTP handler patterns</title><link href="https://lpar.ATH0.com/posts/2020/08/go-http-handler-patterns/"/><id>https://lpar.ATH0.com/posts/2020/08/go-http-handler-patterns/</id><published>2020-08-16T14:46:21-05:00</published><updated>2020-08-16T14:46:21-05:00</updated><summary>How to pass a sql.DB to your http.HandlerFunc.</summary><content type="html"><![CDATA[<p>Imagine you’re a beginner writing a Web Service or web application in Go.  Everything is going fairly smoothly, right up
until you realize your HTTP handlers are going to need to access a database.  The <code>http.HandlerFunc</code> interface is set by
the Go standard library:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="kd">type</span><span class="w"> </span><span class="nx">HandlerFunc</span><span class="w"> </span><span class="kd">func</span><span class="p">(</span><span class="nx">ResponseWriter</span><span class="p">,</span><span class="w"> </span><span class="o">*</span><span class="nx">Request</span><span class="p">)</span><span class="w">
</span></span></span></code></pre></div><p>There’s no obvious way to add more arguments, so what can we do?</p>
<p>I’m going to run through three different ways to solve the problem: the object-oriented approach, a more functional
approach, and a third variant using an interface and an adapter function.</p>
<p>First, though, let’s run through a simple example. Check out <a href="https://github.com/lpar/golang-handler-patterns/blob/main/global/global.go">global.go</a>, the code for a simple POST/GET/PUT Web Service for short messages.</p>
<p><em>Note that since this is an example, it’s written to be as short and straightforward as possible, rather than robust or
elegant. The error handling leaves a lot to be desired, there’s no MIME type checking, and in a real web service you’d
probably abstract out things like decoding the request.</em></p>
<p>The <code>main()</code> function is easy enough:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="kd">func</span><span class="w"> </span><span class="nf">main</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="kd">var</span><span class="w"> </span><span class="nx">err</span><span class="w"> </span><span class="kt">error</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nx">db</span><span class="p">,</span><span class="w"> </span><span class="nx">err</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="nx">sql</span><span class="p">.</span><span class="nf">Open</span><span class="p">(</span><span class="s">&#34;pgx&#34;</span><span class="p">,</span><span class="w"> 
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="s">&#34;postgres://localhost:5432/example?sslmode=disable&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="k">if</span><span class="w"> </span><span class="nx">err</span><span class="w"> </span><span class="o">!=</span><span class="w"> </span><span class="kc">nil</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nb">panic</span><span class="p">(</span><span class="nx">err</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nx">router</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nf">makeRouter</span><span class="p">()</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nx">err</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="nx">http</span><span class="p">.</span><span class="nf">ListenAndServe</span><span class="p">(</span><span class="s">&#34;:80&#34;</span><span class="p">,</span><span class="w"> </span><span class="nx">router</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nx">log</span><span class="p">.</span><span class="nf">Fatal</span><span class="p">(</span><span class="nx">err</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span></code></pre></div><p>In this example I’m using the excellent <a href="https://github.com/go-chi/chi">Chi</a> router to make decoding easier, and <a href="https://www.postgresql.org/">PostgreSQL</a> as the database,
but the same principles apply for any router or database. I’m also using the standard library’s SQL API to avoid any
confusing Postgres-specific features.</p>
<p>The <code>makeRouter</code> function is also easy enough:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="kd">func</span><span class="w"> </span><span class="nf">makeRouter</span><span class="p">()</span><span class="w"> </span><span class="nx">http</span><span class="p">.</span><span class="nx">Handler</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nx">r</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">chi</span><span class="p">.</span><span class="nf">NewRouter</span><span class="p">()</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nx">r</span><span class="p">.</span><span class="nf">Get</span><span class="p">(</span><span class="s">&#34;/msg/{id}&#34;</span><span class="p">,</span><span class="w"> </span><span class="nx">getMessage</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nx">r</span><span class="p">.</span><span class="nf">Put</span><span class="p">(</span><span class="s">&#34;/msg/{id}&#34;</span><span class="p">,</span><span class="w"> </span><span class="nx">putMessage</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nx">r</span><span class="p">.</span><span class="nf">Post</span><span class="p">(</span><span class="s">&#34;/msg&#34;</span><span class="p">,</span><span class="w"> </span><span class="nx">postMessage</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="k">return</span><span class="w"> </span><span class="nx">r</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span></code></pre></div><p>The individual handler functions then all follow the same pattern:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="kd">func</span><span class="w"> </span><span class="nf">getMessage</span><span class="p">(</span><span class="nx">w</span><span class="w"> </span><span class="nx">http</span><span class="p">.</span><span class="nx">ResponseWriter</span><span class="p">,</span><span class="w"> </span><span class="nx">r</span><span class="w"> </span><span class="o">*</span><span class="nx">http</span><span class="p">.</span><span class="nx">Request</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nx">id</span><span class="p">,</span><span class="w"> </span><span class="nx">err</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">strconv</span><span class="p">.</span><span class="nf">Atoi</span><span class="p">(</span><span class="nx">chi</span><span class="p">.</span><span class="nf">URLParam</span><span class="p">(</span><span class="nx">r</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;id&#34;</span><span class="p">))</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c1">// Do stuff with database and return HTTP response</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c1">// ...</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span></code></pre></div><p>There’s just one problem with this code, and it’s right at the top of the file:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="kd">var</span><span class="w"> </span><span class="nx">db</span><span class="w"> </span><span class="o">*</span><span class="nx">sql</span><span class="p">.</span><span class="nx">DB</span><span class="w">
</span></span></span></code></pre></div><p>It’s a global variable! Eww!</p>
<p>So, how do we get rid of the global variable, but still keep the code working?</p>
<h2 id="the-object-oriented-approach">The object-oriented approach</h2>
<p>I’m going to start off with the object-oriented answer to the problem, because I think it’s the simplest to understand.</p>
<p>First of all, we create an object (struct) type which we will use to hold our application-wide state:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="kd">type</span><span class="w"> </span><span class="nx">Application</span><span class="w"> </span><span class="kd">struct</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nx">db</span><span class="w"> </span><span class="o">*</span><span class="nx">sql</span><span class="p">.</span><span class="nx">DB</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span></code></pre></div><p>We then change our handlers to be methods on the <code>Application</code> object:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="kd">func</span><span class="w"> </span><span class="p">(</span><span class="nx">app</span><span class="w"> </span><span class="o">*</span><span class="nx">Application</span><span class="p">)</span><span class="w"> </span><span class="nf">getMessage</span><span class="p">(</span><span class="nx">w</span><span class="w"> </span><span class="nx">http</span><span class="p">.</span><span class="nx">ResponseWriter</span><span class="p">,</span><span class="w"> </span><span class="nx">r</span><span class="w"> </span><span class="o">*</span><span class="nx">http</span><span class="p">.</span><span class="nx">Request</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nx">id</span><span class="p">,</span><span class="w"> </span><span class="nx">err</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">strconv</span><span class="p">.</span><span class="nf">Atoi</span><span class="p">(</span><span class="nx">chi</span><span class="p">.</span><span class="nf">URLParam</span><span class="p">(</span><span class="nx">r</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;id&#34;</span><span class="p">))</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="c1">// ...</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nx">row</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">app</span><span class="p">.</span><span class="nx">db</span><span class="p">.</span><span class="nf">QueryRowContext</span><span class="p">(</span><span class="nx">r</span><span class="p">.</span><span class="nf">Context</span><span class="p">(),</span><span class="w"> </span><span class="o">...</span><span class="w"> </span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="c1">// ...</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span></code></pre></div><p>Because the handler is a method, it can now access the <code>sql.DB</code> as <code>app.db</code>.</p>
<p>The final changes are to remove the global, make <code>main</code> pass an <code>Application</code> to <code>makeRouter</code>, and have <code>makeRouter</code>
call the methods on the <code>Application</code> it is passed:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="kd">func</span><span class="w"> </span><span class="nf">main</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nx">db</span><span class="p">,</span><span class="w"> </span><span class="nx">err</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">sql</span><span class="p">.</span><span class="nf">Open</span><span class="p">(</span><span class="s">&#34;pgx&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;postgres://localhost:5432/meta?sslmode=disable&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="k">if</span><span class="w"> </span><span class="nx">err</span><span class="w"> </span><span class="o">!=</span><span class="w"> </span><span class="kc">nil</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nb">panic</span><span class="p">(</span><span class="nx">err</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nx">app</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="o">&amp;</span><span class="nx">Application</span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nx">db</span><span class="p">:</span><span class="w"> </span><span class="nx">db</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nx">router</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nf">makeRouter</span><span class="p">(</span><span class="nx">app</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nx">err</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="nx">http</span><span class="p">.</span><span class="nf">ListenAndServe</span><span class="p">(</span><span class="s">&#34;:80&#34;</span><span class="p">,</span><span class="w"> </span><span class="nx">router</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nx">log</span><span class="p">.</span><span class="nf">Fatal</span><span class="p">(</span><span class="nx">err</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">func</span><span class="w"> </span><span class="nf">makeRouter</span><span class="p">(</span><span class="nx">app</span><span class="w"> </span><span class="o">*</span><span class="nx">Application</span><span class="p">)</span><span class="w"> </span><span class="nx">http</span><span class="p">.</span><span class="nx">Handler</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nx">r</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">chi</span><span class="p">.</span><span class="nf">NewRouter</span><span class="p">()</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nx">r</span><span class="p">.</span><span class="nf">Get</span><span class="p">(</span><span class="s">&#34;/msg/{id}&#34;</span><span class="p">,</span><span class="w"> </span><span class="nx">app</span><span class="p">.</span><span class="nx">getMessage</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nx">r</span><span class="p">.</span><span class="nf">Put</span><span class="p">(</span><span class="s">&#34;/msg/{id}&#34;</span><span class="p">,</span><span class="w"> </span><span class="nx">app</span><span class="p">.</span><span class="nx">putMessage</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nx">r</span><span class="p">.</span><span class="nf">Post</span><span class="p">(</span><span class="s">&#34;/msg&#34;</span><span class="p">,</span><span class="w"> </span><span class="nx">app</span><span class="p">.</span><span class="nx">postMessage</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="k">return</span><span class="w"> </span><span class="nx">r</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span></code></pre></div><p>You can see the full code in <a href="https://github.com/lpar/golang-handler-patterns/blob/main/object/object.go">object.go</a>.</p>
<p>The advantage of this approach is that it makes for clean and uncomplicated code. Your application’s handler
functions might need a database pool, a logger, some templates, configuration information read from a file,
and all kinds of other runtime state, but the router code can remain simple as it’s all encapsulated in the
method receiver.</p>
<p>The downside, of course, is that the <code>Application</code> object can become a dumping ground, and there’s no way to
tell from the method signature which fields of the object any given handler might need. That, in turn, can make
it more problematic to write unit tests, and couple them to the implementation — do you set up a complete <code>Application</code>
with all its fields for every test, or just set up the fields you’ve worked out that the handler needs from reading
through all of its code?</p>
<p>Another pitfall is that you might also be tempted to code the database-opening logic into the object, perhaps via a
<code>NewApplication</code> constructor. I recommend not doing that – it’s better to do dependency injection, so the <code>Application</code>
doesn’t have to know or care what kind of database it’s passing around; a principle known as <a href="sep">separation of
concerns</a>.  That way you can easily pass in a mock <code>sql.DB</code> for your unit tests, or have the application support
multiple types of database chosen at run time.</p>
<p>I also suggest that you <em>don’t</em> try to make the object a <a href="https://en.wikipedia.org/wiki/Singleton_pattern">singleton</a>.  There’s a good chance you’ll want to
be able to construct multiple instances of it when writing unit tests; maybe not for database access, but for other
pieces of application-level state.</p>
<h2 id="the-functional-approach">The functional approach</h2>
<p>Now let’s look at a completely different way to tackle the problem.</p>
<p>This time we’re going to use <a href="partial">partial application</a> and a <a href="https://en.wikipedia.org/wiki/Closure_%28computer_programming%29">closure</a> to store the application-level state. Or
in less fancy terms, we’re going to write our handlers by writing functions which take some state and return handlers which
operate on that state.</p>
<p>So for each handler, we’ll transform from something like this:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="kd">func</span><span class="w"> </span><span class="nf">getMessage</span><span class="p">(</span><span class="nx">w</span><span class="w"> </span><span class="nx">http</span><span class="p">.</span><span class="nx">ResponseWriter</span><span class="p">,</span><span class="w"> </span><span class="nx">r</span><span class="w"> </span><span class="o">*</span><span class="nx">http</span><span class="p">.</span><span class="nx">Request</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="c1">// Have to use a global if you want db access here</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span></code></pre></div><p>to something like this:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="kd">func</span><span class="w"> </span><span class="nf">getMessage</span><span class="p">(</span><span class="nx">db</span><span class="w"> </span><span class="o">*</span><span class="nx">sql</span><span class="p">.</span><span class="nx">DB</span><span class="p">)</span><span class="w"> </span><span class="nx">http</span><span class="p">.</span><span class="nx">HandlerFunc</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="k">return</span><span class="w"> </span><span class="kd">func</span><span class="p">(</span><span class="nx">w</span><span class="w"> </span><span class="nx">http</span><span class="p">.</span><span class="nx">ResponseWriter</span><span class="p">,</span><span class="w"> </span><span class="nx">r</span><span class="w"> </span><span class="o">*</span><span class="nx">http</span><span class="p">.</span><span class="nx">Request</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c1">// Inside here we can still access the variable db from the outer function!</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span></code></pre></div><p>What we’re doing above is taking a function that really needs three arguments, and manually
turning it into a function which applies the first argument and returns a function which
will apply the remaining arguments.</p>
<p>Once we’ve done that, in the <code>makeRouter</code> function, we’ll swap this:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="w">  </span><span class="nx">r</span><span class="p">.</span><span class="nf">Get</span><span class="p">(</span><span class="s">&#34;/msg/{id}&#34;</span><span class="p">,</span><span class="w"> </span><span class="nx">getMessage</span><span class="p">)</span><span class="w">
</span></span></span></code></pre></div><p>for this:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="w">  </span><span class="nx">r</span><span class="p">.</span><span class="nf">Get</span><span class="p">(</span><span class="s">&#34;/msg/{id}&#34;</span><span class="p">,</span><span class="w"> </span><span class="nf">getMessage</span><span class="p">(</span><span class="nx">db</span><span class="p">))</span><span class="w">
</span></span></span></code></pre></div><p>The db variable can just be passed in from <code>main</code> as a regular argument to <code>makeRouter</code>.
The end result of the refactoring is in <a href="https://github.com/lpar/golang-handler-patterns/blob/main/function/function.go">function.go</a>.</p>
<p>The advantage of this approach is that everything is explicit. If your wrapped handler only needs a few pieces of
application state, the wrapper function can skip the rest. This is good for unit testing, and also for refactoring —
if I refactor a wrapped handler and it no longer use one of the state variables, my IDE will tell me I have an unused function
argument in the outer function and I can remove it.</p>
<p>The downside of this approach is the same: that everything is explicit. If you have eight pieces of application-level
runtime state and your handler needs all of them, you’ll have to pass them all as arguments.</p>
<p>You might also dislike the fact that every handler is now wrapped in an extra function, and be wondering if there isn’t
a way to avoid that extra code. Which brings me to the third approach..</p>
<h2 id="the-interface-extension-approach">The interface extension approach</h2>
<p>Imagine for a moment how easy this would all be if the <code>http.HandlerFunc</code> type included a <code>sql.DB</code> parameter. Well, we
can make that happen, or at least something like it. We start by defining our own extended version of the <code>HandlerFunc</code>
type, and giving it any extra arguments we want, in this case a <code>sql.DB</code>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="kd">type</span><span class="w"> </span><span class="nx">ExHandlerFunc</span><span class="w"> </span><span class="kd">func</span><span class="p">(</span><span class="nx">db</span><span class="w"> </span><span class="o">*</span><span class="nx">sql</span><span class="p">.</span><span class="nx">DB</span><span class="p">,</span><span class="w"> </span><span class="nx">w</span><span class="w"> </span><span class="nx">http</span><span class="p">.</span><span class="nx">ResponseWriter</span><span class="p">,</span><span class="w"> </span><span class="nx">r</span><span class="w"> </span><span class="o">*</span><span class="nx">http</span><span class="p">.</span><span class="nx">Request</span><span class="p">)</span><span class="w">
</span></span></span></code></pre></div><p>Now we can write each handler as an <code>ExHandlerFunc</code> instead of a <code>HandlerFunc</code>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="kd">func</span><span class="w"> </span><span class="nf">getMessage</span><span class="p">(</span><span class="nx">db</span><span class="w"> </span><span class="o">*</span><span class="nx">sql</span><span class="p">.</span><span class="nx">DB</span><span class="p">,</span><span class="w"> </span><span class="nx">w</span><span class="w"> </span><span class="nx">http</span><span class="p">.</span><span class="nx">ResponseWriter</span><span class="p">,</span><span class="w"> </span><span class="nx">r</span><span class="w"> </span><span class="o">*</span><span class="nx">http</span><span class="p">.</span><span class="nx">Request</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="c1">// Code as before</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span></code></pre></div><p>The only problem is that our router wants a <code>HandlerFunc</code> for each route. We solve that problem by writing an adapter:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="kd">func</span><span class="w"> </span><span class="nf">withDB</span><span class="p">(</span><span class="nx">db</span><span class="w"> </span><span class="o">*</span><span class="nx">sql</span><span class="p">.</span><span class="nx">DB</span><span class="p">,</span><span class="w"> </span><span class="nx">xhandler</span><span class="w"> </span><span class="nx">ExHandlerFunc</span><span class="p">)</span><span class="w"> </span><span class="nx">http</span><span class="p">.</span><span class="nx">HandlerFunc</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="k">return</span><span class="w"> </span><span class="kd">func</span><span class="p">(</span><span class="nx">w</span><span class="w"> </span><span class="nx">http</span><span class="p">.</span><span class="nx">ResponseWriter</span><span class="p">,</span><span class="w"> </span><span class="nx">r</span><span class="w"> </span><span class="o">*</span><span class="nx">http</span><span class="p">.</span><span class="nx">Request</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nf">xhandler</span><span class="p">(</span><span class="nx">db</span><span class="p">,</span><span class="w"> </span><span class="nx">w</span><span class="p">,</span><span class="w"> </span><span class="nx">r</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span></code></pre></div><p>The adapter takes a database pool and an extended handler, and returns a regular handler which calls the extended handler
with the database pool. The reason for the name is more obvious when we update the <code>makeRouter</code> code:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="kd">func</span><span class="w"> </span><span class="nf">makeRouter</span><span class="p">(</span><span class="nx">db</span><span class="w"> </span><span class="o">*</span><span class="nx">sql</span><span class="p">.</span><span class="nx">DB</span><span class="p">)</span><span class="w"> </span><span class="nx">http</span><span class="p">.</span><span class="nx">Handler</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nx">r</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">chi</span><span class="p">.</span><span class="nf">NewRouter</span><span class="p">()</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nx">r</span><span class="p">.</span><span class="nf">Get</span><span class="p">(</span><span class="s">&#34;/msg/{id}&#34;</span><span class="p">,</span><span class="w"> </span><span class="nf">withDB</span><span class="p">(</span><span class="nx">db</span><span class="p">,</span><span class="w"> </span><span class="nx">getMessage</span><span class="p">))</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nx">r</span><span class="p">.</span><span class="nf">Put</span><span class="p">(</span><span class="s">&#34;/msg/{id}&#34;</span><span class="p">,</span><span class="w"> </span><span class="nf">withDB</span><span class="p">(</span><span class="nx">db</span><span class="p">,</span><span class="w"> </span><span class="nx">putMessage</span><span class="p">))</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nx">r</span><span class="p">.</span><span class="nf">Post</span><span class="p">(</span><span class="s">&#34;/msg&#34;</span><span class="p">,</span><span class="w"> </span><span class="nf">withDB</span><span class="p">(</span><span class="nx">db</span><span class="p">,</span><span class="w"> </span><span class="nx">postMessage</span><span class="p">))</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="k">return</span><span class="w"> </span><span class="nx">r</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span></code></pre></div><p>The finished code is in <a href="https://github.com/lpar/golang-handler-patterns/blob/main/interface/interface.go">interface.go</a>.</p>
<p>This is really a variation on the function wrapper technique, we’re just generalizing the wrapper so that the handler
implementation doesn’t have to have it visible.</p>
<p>The advantage of this technique, as with the previous one, is that in the (extended) handler code, all the state is
explicitly supplied as arguments. When it comes to unit testing, there’s no <code>Application</code> object to create. There’s a
little more complexity in the router building code, but not much.</p>
<p>The downside is that this technique won’t work so well if your handlers need widely varying selections of application
state. You’ll either end up with lots of arguments you don’t always use, or you’ll have to define multiple extended
handlerfunc interfaces with different combinations of state variables as argument. Still, it’s a useful technique to be
aware of for some situations.</p>
<h2 id="conclusions">Conclusions</h2>
<p>So, three different ways to solve the same problem. Which is best? As is usual in software engineering, it depends — there
are advantages and disadvantages to each approach, and you’ll have to consider the tradeoffs and decide which is best for
your specific application.</p>
]]></content></entry><entry><title type="html">COBOL</title><link href="https://lpar.ATH0.com/posts/2020/04/cobol/"/><id>https://lpar.ATH0.com/posts/2020/04/cobol/</id><published>2020-04-09T14:13:29-05:00</published><updated>2020-04-09T14:13:29-05:00</updated><summary>Yes, it’s still around, there are reasons.</summary><content type="html"><![CDATA[<p>A story has been making the rounds about how New Jersey suddenly needs COBOL programmers to fix its unemployment claims processing system. People have expressed horror, amusement or incredulity that COBOL is still being used, and that the system is so obsolete (reportedly running on <a href="https://www.tomshardware.com/news/new-jersey-cobol-coders-mainframes-coronavirus">40 year old hardware</a>.)</p>
<p>I’m not a COBOL programmer and I don’t work in the mainframe division, but I’d like to point out a few things about this story.</p>
<p>First of all, assuming they really are using a 40 year old mainframe, they could start by upgrading the hardware. In 2002 an entry level z800 <a href="http://www.cpushack.com/2014/03/11/ibm-z800-mcm-mainframe-processor/">ran two cores, each at 625MHz</a> and started out at 80 MIPS (according to <a href="http://www.redbooks.ibm.com/pubs/pdfs/redbooks/sg246515.pdf">Technical Introduction: IBM eserver zSeries 800</a>.) That’s only 20 years ago, and according to the <a href="https://www-01.ibm.com/common/ssi/ShowDoc.wss?docURL=/common/ssi/rep_sm/2/897/ENUS2066-_h02/index.html&amp;lang=en&amp;request_locale=en">spec sheet</a> it was generally faster than the OS/390 systems that preceded it, so let’s assume their 40 year old mainframe can’t be any faster than that.</p>
<p>In comparison, a modern z14 mainframe (circa 2018) can run up to 170 processor cores, at 5.2GHz, and exceed 146,000 MIPS (again according to <a href="http://www.redbooks.ibm.com/abstracts/sg248451.html">the technical guide</a>).</p>
<p>Looking at I/O, the z800 had six 1GB/s STI links for all I/O. If I’m reading things correctly, the z14 can run 160 FICON Express16s cards each at 16GB/s. So that’s a leap from 6GB/s to 2560GB/s.</p>
<p>So sure, claims are up by <a href="https://www.nj.com/coronavirus/2020/04/nj-unemployment-delays-caused-by-1600-surge-in-calls-during-coronavirus-crisis.html">1,600%</a>. But upgrading hardware could give them a machine thats 182,500% faster, if they really need it.</p>
<p>That’s not all, though. Compiler technology has also improved a lot in the last 40 years; or more specifically, optimizer technology has. You can get a standalone optimizer for your existing legacy COBOL binaries that will reoptimize the code, giving you <a href="https://www.ibm.com/developerworks/community/blogs/invisiblethread/entry/Put_your_COBOL_applications_into_HYPERDRIVE_on_z14_without_having_to_recompile_a_single_line_of_source?lang=en">an average 47% CPU load reduction</a>.</p>
<p>I think the real story is revealed in <a href="https://www.cnbc.com/2020/04/06/new-jersey-seeks-cobol-programmers-to-fix-unemployment-system.html">CNBC’s coverage</a>:</p>
<blockquote>
<p>New Jersey plans to ask for volunteers with a variety of skills, including technologists</p>
</blockquote>
<p>Key word: <em>volunteers</em>. Looks to me like it’s not really a <em>technical</em> problem, more of a <em>money</em> problem, with a side order of bad timing.</p>
<p>If you’re wondering why COBOL is still used for things like unemployment claim processing (and air flight booking and tax return processing and invoicing and and and…) the answer is that COBOL <a href="https://medium.com/@bellmar/is-cobol-holding-you-hostage-with-math-5498c0eb428b">uses accurate decimal arithmetic for computation</a> <em>by default</em>. Sure, Java has BigDecimal, but it’s ugly to use, whereas COBOL gets the math right with no coding overhead. That’s important to big companies, tax offices, and the Federal Reserve.</p>
]]></content></entry><entry><title type="html">Building a Kotlin fat JAR with IntelliJ IDEA</title><link href="https://lpar.ATH0.com/posts/2019/06/building-a-kotlin-fat-jar-with-intellij-idea/"/><id>https://lpar.ATH0.com/posts/2019/06/building-a-kotlin-fat-jar-with-intellij-idea/</id><published>2019-06-20T17:18:06-05:00</published><updated>2019-06-20T17:18:06-05:00</updated><summary>…and with Kotlin scripting, not Groovy.</summary><content type="html"><![CDATA[<p>Here are my initial assumptions:</p>
<ul>
<li>You want to build a command-line tool or server task.</li>
<li>You want to use Kotlin for as much of the project as possible.
<ul>
<li>You might use some Java-based libraries</li>
<li>Your main <code>main()</code> binary will be in Kotlin.</li>
</ul>
</li>
<li>You want building the binary to be as quick and easy as possible.</li>
<li>You want to end up with a single <a href="https://stackoverflow.com/questions/19150811/what-is-a-fat-jar">fat jar file</a> you can deploy to any JVM.</li>
<li>You’re using IntelliJ IDEA, or possibly the community edition aimed at Android developers.</li>
</ul>
<p>First of all, don’t set up a new <em>Kotlin</em> project using IntelliJ IDEA. If you do
that, the project will be set up to have IDEA build the code, which will make
your life harder. In fact, if you want to (say) use <code>kotlinx.serialization</code>
it’ll make your life impossible. Yes, there’s a plugin to build Kotlin code
with IDEA, but think of that as a set of training wheels to get newbies writing
Kotlin without needing to know about build tasks.</p>
<p>I say this because I tried to use Kotlin without Gradle being involved. I’d had
a few bad experiences involving Android development, and really didn’t want to
repeat them. However, eventually I just had to give in and start using Gradle,
and when I did… it actually wasn’t that bad. Gradle’s pretty speedy these
days.</p>
<p>But to get to that point, you need to tell IDEA to set up a <em>Gradle</em> project,
but <em>targeting</em> Kotlin/JVM. At that point I was faced with a small but
significant checkbox: “Kotlin DSL build script”. I checked the box.</p>
<p>Gradle is traditionally scripted with Groovy, a scripting language modeled on
Ruby. Groovy has a bit of a troubled history – it started off as a project of
G2One, who were bought by SpringSource, who were bought by VMware. VMware were
bought by EMC, Pivotal was spun off and given Groovy to look after, EMC were
bought by Dell, and Pivotal gave Groovy to the Apache Software Foundation,
which tends to be a bit of a software hospice ward. The JSR document for
standardizing Groovy was set to dormant in 2012 after 8 years of inactivity.
Not auspicious, and I don’t feel like investing time in learning Groovy.</p>
<p>The downside of using Kotlin for scripting Gradle is that almost all the
how-to information out on the Internet assumes you’re using Groovy – even for
building Kotlin applications, because Kotlin scripting of Gradle only hit 1.0
in 2018.</p>
<h2 id="directory-structure">Directory structure</h2>
<p>So, I told IDEA to set me up a Gradle project targeting Kotlin/JVM with Kotlin DSL build script. I gave it a group ID and project name, it churned away for a while and set me up a new project:</p>
<pre><code>.gradle/
.idea/
gradle/
src/
  main/
    java/
    kotlin/
    resources/
  test/
    java/
    kotlin/
    resources/
build.gradle.kts
gradle.properties
gradlew
gradlew.bat
settings.gradle
</code></pre>
<p>It also enabled the Gradle integration in IDEA, which added an editor pane listing the available Gradle tasks so I could just double-click to (say) build a jar.</p>
<p>I dropped a couple of Kotlin files into src/main/kotlin and was able to build a jar. It didn’t run, though – no main class in manifest.</p>
<h2 id="adding-a-manifest">Adding a manifest</h2>
<p>Gradle with the Kotlin DSL has an <code>application</code> plugin. I thought that might do the trick, so I added it to the <code>plugins</code> stanza in the <code>build.gradle.kts</code> file:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-kotlin" data-lang="kotlin"><span class="line"><span class="cl"><span class="n">plugins</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="n">kotlin</span><span class="p">(</span><span class="s2">&#34;jvm&#34;</span><span class="p">)</span> <span class="n">version</span> <span class="s2">&#34;1.3.40&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="n">application</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>…and added a stanza specifying options, including the main class name:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-kotlin" data-lang="kotlin"><span class="line"><span class="cl"><span class="n">application</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="n">mainClassName</span> <span class="p">=</span> <span class="s2">&#34;myapp.MainKt&#34;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>No luck. It turns out the <code>application</code> plugin is to make it easy to run the application from inside your IDE. However, it’s not too hard to change how the jar file is generated to add the manifest info, and take it from the application options so you don’t have to specify the class name twice:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-kotlin" data-lang="kotlin"><span class="line"><span class="cl"><span class="n">tasks</span><span class="p">.</span><span class="n">withType</span><span class="p">&lt;</span><span class="n">Jar</span><span class="p">&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="n">manifest</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">attributes</span><span class="p">[</span><span class="s2">&#34;Main-Class&#34;</span><span class="p">]</span> <span class="p">=</span> <span class="n">application</span><span class="p">.</span><span class="n">mainClassName</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>I now had a Hello World application that would build, run, build into a jar, and run as a jar.</p>
<h2 id="adding-dependencies">Adding dependencies</h2>
<p>I’d already decided I wanted to use tinylog with its Kotlin API. That turns out to be simple enough. I opened up the <code>build.gradle.kts</code> file again and found the <code>dependencies</code> section and added to it:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-kotlin" data-lang="kotlin"><span class="line"><span class="cl"><span class="n">dependencies</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="c1">// Improved Kotlin stdlib using JDK 8 features
</span></span></span><span class="line"><span class="cl">    <span class="n">implementation</span><span class="p">(</span><span class="n">kotlin</span><span class="p">(</span><span class="s2">&#34;stdlib-jdk8&#34;</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">    <span class="n">implementation</span><span class="p">(</span><span class="s2">&#34;org.tinylog:tinylog-api-kotlin:2.0.0-M4.3&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">implementation</span><span class="p">(</span><span class="s2">&#34;org.tinylog:tinylog-impl:2.0.0-M4.3&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>I added some logging calls and ran a new build. As expected, I got a jar with my code in, but it would no longer run because the library classes weren’t found.</p>
<h2 id="fat-jar">Fat Jar</h2>
<p>I found a bunch of contradictory suggestions for how to build a fat JAR file. The method that works, which is <a href="https://github.com/JetBrains/kotlin/blob/master/build.gradle.kts">the one JetBrains use themselves</a>, is to use the <a href="https://imperceptiblethoughts.com/shadow/">Gradle Shadow Jar plugin</a>.</p>
<p>The documentation for Gradle Shadow tells you how to use it if you’re scripting in Groovy, but not if you’re scripting in Kotlin. Turns out the incantation is as shown here:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-kotlin" data-lang="kotlin"><span class="line"><span class="cl"><span class="n">plugins</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="n">kotlin</span><span class="p">(</span><span class="s2">&#34;jvm&#34;</span><span class="p">)</span> <span class="n">version</span> <span class="s2">&#34;1.3.40&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="n">application</span>
</span></span><span class="line"><span class="cl">    <span class="n">id</span><span class="p">(</span><span class="s2">&#34;com.github.johnrengelman.shadow&#34;</span><span class="p">)</span> <span class="n">version</span> <span class="s2">&#34;5.0.0&#34;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>There’s a catch, though. The Shadow plugin only works with Gradle 5 and up, whereas IDEA bundles an older version of Gradle. I downloaded and unpacked a binary distribution of Gradle 5 point something, and navigated through IDEA preferences, Build Execution Deployment, Build Tools, Gradle. There I chose “use local Gradle distribution” and pointed it at the directory I’d just unpacked.</p>
<p>The machine did mysterious things for a worrying amount of time, then rebuilt the project using Gradle 5.</p>
<h2 id="one-last-thing">One last thing</h2>
<p>I had one more problem, which was that my dependencies soon grew to request two different versions of the same package — <code>kotlin-reflect</code>. The solution was to add an explicit dependency to force a particular version:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-kotlin" data-lang="kotlin"><span class="line"><span class="cl"><span class="n">dependencies</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="n">implementation</span><span class="p">(</span><span class="n">kotlin</span><span class="p">(</span><span class="s2">&#34;stdlib-jdk8&#34;</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">    <span class="n">implementation</span><span class="p">(</span><span class="s2">&#34;org.jetbrains.kotlin:kotlin-reflect:1.3.40&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">implementation</span><span class="p">(</span><span class="s2">&#34;org.tinylog:tinylog-api-kotlin:2.0.0-M4.3&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">implementation</span><span class="p">(</span><span class="s2">&#34;org.tinylog:tinylog-impl:2.0.0-M4.3&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>With that, I had a new set of tasks under <code>shadow</code>. I double-clicked <code>shadowJar</code> and IDEA started Gradle, which built me a fat jar that worked.</p>
]]></content></entry><entry><title type="html">About</title><link href="https://lpar.ATH0.com/about/"/><id>https://lpar.ATH0.com/about/</id><published>2019-02-28T00:00:00+00:00</published><updated>2019-02-28T00:00:00+00:00</updated><summary>Who is this guy?</summary><content type="html">&lt;p>No idea.&lt;/p>
</content></entry><entry><title type="html">Go and SQL memory leaks</title><link href="https://lpar.ATH0.com/posts/2018/10/go-and-sql-memory-leaks/"/><id>https://lpar.ATH0.com/posts/2018/10/go-and-sql-memory-leaks/</id><published>2018-10-24T10:02:10-05:00</published><updated>2018-10-24T10:02:10-05:00</updated><summary>Detecting when you fail to close sql.Rows.</summary><content type="html"><![CDATA[<p>The scenario: You’ve got some Go code. You can run the unit tests individually, but when you try <code>go test -v ./...</code> or try to run continuous integration, the tests fall over from lack of memory.</p>
<p>There are lots of things that could be causing the problem, but one you should definitely check for is unclosed SQL database statements and connections.</p>
<p>You’re probably aware that the general pattern for SQL queries in Go, assuming you have a <code>sql.DB</code> connection pool in the variable <code>db</code>, is something like this:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="nx">rows</span><span class="p">,</span><span class="w"> </span><span class="nx">err</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">db</span><span class="p">.</span><span class="nf">Query</span><span class="p">(</span><span class="s">&#34;select * from tablename where id = ?&#34;</span><span class="p">,</span><span class="w"> </span><span class="nx">id</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="k">if</span><span class="w"> </span><span class="nx">err</span><span class="w"> </span><span class="o">!=</span><span class="w"> </span><span class="kc">nil</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="k">return</span><span class="w"> </span><span class="nx">fmt</span><span class="p">.</span><span class="nf">Errorf</span><span class="p">(</span><span class="s">&#34;can&#39;t query tablename for %d: %v&#34;</span><span class="p">,</span><span class="w"> </span><span class="nx">id</span><span class="p">,</span><span class="w"> </span><span class="nx">err</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="k">defer</span><span class="w"> </span><span class="kd">func</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nx">err</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">rows</span><span class="p">.</span><span class="nf">Close</span><span class="p">()</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="k">if</span><span class="w"> </span><span class="nx">err</span><span class="w"> </span><span class="o">!=</span><span class="w"> </span><span class="kc">nil</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nx">fmt</span><span class="p">.</span><span class="nf">Fprintf</span><span class="p">(</span><span class="nx">os</span><span class="p">.</span><span class="nx">Stderr</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;warning: failed to close SQL statement\n&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}()</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="k">for</span><span class="w"> </span><span class="nx">rows</span><span class="p">.</span><span class="nf">Next</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="c1">// process returned data</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span></code></pre></div><p>The problem is what happens if you forget that deferred <code>rows.Close()</code> (or it fails for some reason). Some or all of the retrieved data sits around in memory, and the SQL statement stays open. Depending on the database, that may even prevent Go from being able to close the database, keeping all the database connection structures stuck in memory too. (I believe MariaDB will let you close a database connection even if there are unclosed statements, but DB2 most definitely will not.)</p>
<p>The end result? Database structures and data collect in memory every time that piece of code is called.</p>
<p>For this reason, it’s a good idea to make your unit tests which involve database operations check for unclosed DB connections and statements.</p>
<p>The main hurdle is that you need to write your own <code>TestMain</code> method in any unit test file that performs database operations. Here’s what it will look like:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="kd">var</span><span class="w"> </span><span class="nx">db</span><span class="w"> </span><span class="o">*</span><span class="nx">sql</span><span class="p">.</span><span class="nx">DB</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">func</span><span class="w"> </span><span class="nf">TestMain</span><span class="p">(</span><span class="nx">m</span><span class="w"> </span><span class="o">*</span><span class="nx">testing</span><span class="p">.</span><span class="nx">M</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="c1">// Get test database </span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nx">db</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="nx">testutils</span><span class="p">.</span><span class="nf">GetTestDatabase</span><span class="p">()</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="c1">// Tell Go to return closed DB connections to the pool </span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="c1">// rather than leaving them idle</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nx">db</span><span class="p">.</span><span class="nf">SetMaxIdleConns</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nx">testutils</span><span class="p">.</span><span class="nf">ResetTestData</span><span class="p">(</span><span class="nx">db</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="c1">// This actually runs your unit tests</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nx">code</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">m</span><span class="p">.</span><span class="nf">Run</span><span class="p">()</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="c1">// Now we check to see if any connections were left open</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nx">c</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">db</span><span class="p">.</span><span class="nf">Stats</span><span class="p">().</span><span class="nx">OpenConnections</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="k">if</span><span class="w"> </span><span class="nx">c</span><span class="w"> </span><span class="o">!=</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nb">panic</span><span class="p">(</span><span class="s">&#34;connection left open&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nx">os</span><span class="p">.</span><span class="nf">Exit</span><span class="p">(</span><span class="nx">code</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span></code></pre></div><p>Of course once you have identified that DB connections are being left open, you need to identify which ones. In general, of course, it’ll be whichever one you wrote most recently. If you have a codebase which has never been tested like this before, though, you might have a lot of database leaks. In that case, the workaround is to check <code>OpenConnections</code> in each individual test.</p>
]]></content></entry><entry><title type="html">Java time conversion madness</title><link href="https://lpar.ATH0.com/posts/2018/04/java-time-conversion-madness/"/><id>https://lpar.ATH0.com/posts/2018/04/java-time-conversion-madness/</id><published>2018-04-06T19:36:41-05:00</published><updated>2018-04-06T19:36:41-05:00</updated><summary>Specifically, in Lotus Notes and XPages.</summary><content type="html"><![CDATA[<p>Lotus Notes is an old piece of software. It was inspired by PLATO Notes and DECNotes, and its development began in 1984. The first release was in 1989, though that’s not particularly old by IBM standards – IBM is <a href="https://www.ibm.com/us-en/marketplace/ims-15">still developing</a> IMS, the database <a href="https://www.ibm.com/support/knowledgecenter/en/SSEPH2_12.1.0/com.ibm.imsintro.doc.intro/intro_imsandapollo.html">designed in 1966</a> as ICS/DL/I to keep track of the approximately three million parts that made up an Apollo Saturn V.</p>
<p>Nevertheless, Notes predated Java, JavaScript, Unicode, TCP/IP support in Windows, and many other things we now take for granted. Sometimes the age of Notes shows through in how the product works internally.</p>
<p>An example of this is the date and time handling. Originally Notes used basically the same time zone lists as Windows 1.0, which in turn was based on how MS-DOS did things. Dates and times were “automatically” converted to your time zone, and that was it. Back in the late 1990s it became clear that this was insufficient, so Notes was given a new type of field which could be used for selecting and storing time zone information. Internally, the time zone was stored as a set of undocumented keys and values packed into a string, for example:</p>
<pre><code>Z=-1$DO=1$DL=3 -1 1 10 -1 1$ZX=130$ZN=W. Europe
</code></pre>
<p>Clearly Z is the Zulu offset, the number of hours from UTC. DO is Daylight Observed. DL is the rules for DST observance, ZX is likely the internal code number of the time zone in the old list, and ZN is the name of the time zone.</p>
<p>Unfortunately, time zones change quite regularly, because governments like to mess with them. It wasn’t long until changes were needed to the Notes and Domino time zone list. Unfortunately, the values in the string were stored in millions of user documents on customer servers around the world, so there was no way to easily rename (say) Tonga to Tongatapu. Nor was there any easy way to remove obsolete values. So instead, an extra layer of translation was added. The document might say <code>ZN=Tonga</code> in the time zone field, but that would be displayed as Nuku’alofa in the front end, that being the largest city on Tongatapu.</p>
<p>In the 1990s, Java was the new hotness. Early versions of Java had a terrible API for date and time handling; simple problems like producing a timestamp in Internet format could take ten lines of code. Nevertheless,
IBM decided to bet big on Java for enterprise software development. Notes and Domino were rebuilt, practically from the ground up, using Java EE and Eclipse technologies. Amazingly, full backward compatibility was kept with the old Windows version of Notes. This meant that when you started being able to develop Domino applications in Java, you found that as well as the Java <code>Calendar</code> and <code>Date</code> data types, there was also a <code>DateTime</code> class representing dates and times as handled by Notes since the 1980s.</p>
<p>Over the years, enough people complained about Java’s date and time APIs that it became clear that they needed replacing. Finally, Java 8 introduced a whole new date and time API.</p>
<p>If you haven’t learned Java 8 <code>java.time</code> APIs, well, they are <em>fantastic</em> compared to the old ones. Many problems which used to require error-prone hacks, such as how to represent a date with no time, now have straightforward and robust solutions.</p>
<p>Unfortunately, because it took until Java 8, there’s a huge amount of code out there which uses the old APIs. Oracle published <a href="https://docs.oracle.com/javase/tutorial/datetime/iso/legacy.html">some notes</a> on how to convert between the old and new classes, but basically left the problem as an exercise for the programmer.</p>
<p>So it was that I decided to sit down and work out a utility class with all the conversions, and a set of unit tests to verify them. I called the utility HodgePodge, partly after the state of most Java date/time code, and partly after the <a href="http://historiadiscordia.com/the-blivet-and-the-hodgepodge-transformer/">hodge/podge transformer</a> of Principia Discordia. I hoped that my HodgePodge class would help me reduce the general amount of chaos in my code.</p>
<p>Next, I turned my eye towards doing the same thing for IBM Notes and Domino DateTime values and time zone fields – that is, building utility functions to convert them to and from the new Java time API, since modern Domino development is done in Java and JavaScript.</p>
<p>This proved to be a tougher task. The first step was to build a list of Notes/Domino time zones, and work out how to convert them to Java 8 time zones, which are based on the Olson time zone database. To do this, I had to consult a number of sources.</p>
<p>First of all, I assembled a test database with every possible Notes/Domino time zone value represented, so I could examine both the front-end and back-end representations of them. I could then cross-reference that with <a href="https://support.microsoft.com/en-us/help/973627/microsoft-time-zone-index-values">Microsoft’s time zone list</a> for Windows, and a somewhat out-of-date IBM list of <a href="https://www-01.ibm.com/support/docview.wss?uid=swg27003019">Notes 4 time zones</a> that someone helpfully included in an article about decoding hexadecimal universally unique IDs.</p>
<p>With all that information, I could often find an obvious semantic match in the <a href="http://www.mkyong.com/java8/java-display-all-zoneid-and-its-utc-offset/">Java 8 timezone list</a>. If I couldn’t, my next step was to consult the site <a href="https://www.zeitverschiebung.net/">zeitverschiebung.net</a>, which seems to catalog every single time zone for every major city with typical German thoroughness, in each case providing the Olson time zone name – which is usually (but not always) found in the Java 8 list.</p>
<p>For an example of an easy one, consider <code>ZN=Eastern Standard Time (Mexico)</code>. There’s no Java/Olson entry under Mexico for any kind of Mexican Eastern Standard Time, but the Notes UI displays “Chetumal” in the time zone selector. Chetumal isn’t in Olson either, but if I look up Chetumal on the handy German web site, it tells me that the appropriate time zone is <code>Mexico/Cancun</code>. I know Cancun is a resort on the east coast of Mexico, which explains why it was called “Eastern Standard Time (Mexico)”, so that’s that one sorted.</p>
<p>It wasn’t long before I found some traps. How about <code>ZN=US Mountain</code>? That’ll be US Mountain Time, such as is observed in Colorado, so <code>America/Denver</code>, right? Wrong! The user interface control labels it Arizona. Arizona doesn’t observe DST, unlike Colorado, so the correct Java zone name is <code>America/Arizona</code>. There’s a separate <code>ZN=Mountain</code> for US Mountain Time.</p>
<p>Then there was <code>ZN=Central America</code>. That appears as Central America in the UI as well. It’s a Microsoft time zone, their page tells us that it represents “Central America Standard Time”, whatever that is, but no examples are given of anywhere which uses that time zone. However, looking at the underlying data structure it says <code>DO=0</code>, which means it doesn’t have DST. I went on vacation in Costa Rica and remembered that they don’t observe DST, because they’re a very sensible country. The offset matches, so <code>America/Costa_Rica</code> will do for that.</p>
<p>Then there’s <code>TZ=US Eastern</code>. You might think that that’s US Eastern Time (EST/EDT), but you’d be wrong because the value displayed to the end-user is Indiana (East). Indiana has been observing DST since 2006, so right now eastern Indiana is on EST/EDT – but there’s no guarantee that that will continue, so the best coding is probably <code>America/Indiana/Indianapolis</code>.</p>
<p>This sounds tedious, right? So you might be wondering if I could just use the Z
value (offset from UTC) and DO value (DST observed) to sort things out. The
answer, sadly, is no. It turns out that there’s both a Central Europe Daylight
Time and a Central Europe<em>an</em> Daylight Time, both abbreviated to CEDT, and
they’re semantically different, but they currently both have the same UTC
offsets and both observe DST. So if you want to convert times and dates with
best fidelity, you can’t just use the UTC offset (with or without DST), and you
can’t rely on the abbreviation for the time zone.</p>
<p>There’s a bigger problem, though – when the Domino <code>DateTime</code> object was created, Windows only supported integer time zone offsets – that is, whole numbers of hours. So the call to get the offset from UTC still only returns an integer. That’s a problem if you live in South Australia, where the time zone is +10:30. (And yes, quite a lot of people do live in Adelaide.)</p>
<p>So, what to do if the code needs a zoned time and date, but there’s no date/time field with a semantic value, just the offset found in the <code>DateTime</code> object? I could build an <code>OffsetDateTime</code> in Java, but there’s no way to get the necessary information. Or is there?</p>
<p>After thinking about the problem for a bit, I came up with a solution. The <code>DateTime</code> class has a method to return the date and time as a string, in its original internal time zone. It also has a method to return the date and time as a string in GMT. I could grab both, subtract one from the other, and that would tell me what the internal time zone offset was!</p>
<p>Unfortunately, the string format used by the <code>DateTime</code> object depends on the local i18n settings on the system where the code is running. So first, I had to write code which took the Notes/Domino i18n settings – provided as an <code>International</code> object – interrogated them, and built a format string to parse the appropriate date and time format using Java’s new <code>DateTimeFormatter</code>. I could then parse both my timestamps, calculate the time zone offset including the minutes, append that to the original timestamp, and parse that as an <code>OffsetDateTime</code>!</p>
<p>Oh, but it’s not <em>that</em> easy either. There’s a bug in Java 8 where it <a href="https://bugs.openjdk.java.net/browse/JDK-8066806">can’t parse timestamps with time zone offsets for which the number of hours is a single digit</a>. It’s fixed in Java 9, but there’s no Java 8 backport, and Java 9 isn’t LTS so I’d have to wait for Java 11. So instead, I had to assemble my own <code>ZoneOffset</code> object, and combine it with a <code>LocalDateTime</code> to produce an <code>OffsetDateTime</code>.</p>
<p>Anyway, back to time zones. Australia was easy compared to some of the other values. Consider the time zone abbreviated as <code>YW2</code>.</p>
<p>The YW2 time zone is stored in Notes as <code>ZN=Mid-Atlantic</code>. The front end display is “Mid-Atlantic - Old”, which gives a clue as to the problem: no country actually uses that time zone any more. It used to be the time zone of Fernando de Noronha, an archipelago of 21 islands off the coast of Brazil with a population of around 2,800 inhabitants. However, Brazil’s eastern islands no longer observe daylight saving time (or <em>horário de verão</em> as they call it); only the west side of Brazil bothers with that.</p>
<p>So the Olson and Java time zone databases have no entry for “GMT-2:00 with DST”, hence nothing which corresponds to YW2. Which is a shame, as someone has managed to enter data in YW2 into one of the databases I manage, as I discovered while testing my code.</p>
<p>For that case, I decided to code YW2 as <code>Etc/GMT+2</code> and accept that the data may be off by an hour for half the year, since I think the data is likely bogus to start with given the time zone attached. (Yes, GMT+2, because the Etc zones have + and - reversed to match POSIX and Microsoft conventions where positive time zones are west of Greenwich.)</p>
<p>Then there are a few values which are simply wrong in the current IBM Domino time zone list. The list has Samoa as UTC+13, but Samoa changed to UTC-11 (same as Niue) in 2011, so for a while it wasn’t in the Samoa Time Zone (defined by the US). Checking online suggests that Pago Pago (American Samoa) also moved time zone later on, so both Western Samoa and American Samoa are now UTC-11. Still, should I translate the time zone to American Samoa, Samoa (the nation), or even <code>Pacific/Pago_Pago</code>? I decided that since Samoa is an actual nation, references to Samoa without additional qualification should be taken to mean the nation, and I put <code>Pacific/Samoa</code> in the conversion function.</p>
<p>Finally, I went back and tested that all my test data produced valid semantic time zones when passed through the conversion functions, and results that were what I expected plus or minus an hour (because of DST being observed or not).</p>
<p>Overall, it was a gruelling and incredibly annoying experience, but I now have my web service providing events feeds in JSON with useful time zone information. To save any IBM customer from having to go through the same pain, I’m putting the code <a href="https://github.com/lpar/hodgepodge">up on Github</a>. Please let me know if you find any bugs!</p>
]]></content></entry><entry><title type="html">Go, PostgreSQL, time zones, UTC, and &amp;#43;0000 &amp;#43;0000</title><link href="https://lpar.ATH0.com/posts/2017/11/go-postgresql-time-zones-utc-and-0000-0000/"/><id>https://lpar.ATH0.com/posts/2017/11/go-postgresql-time-zones-utc-and-0000-0000/</id><published>2017-11-30T17:55:23-06:00</published><updated>2017-11-30T17:55:23-06:00</updated><summary>The PostgreSQL data type to use for storage, and why.</summary><content type="html"><![CDATA[<p>Imagine you’re writing a web application in Go, and storing your data in PostgreSQL. At some point, you find yourself wanting to store timestamps, and display them to the user in local time. Being a smart developer, you decide to store all your timestamps in UTC, and convert them for display.</p>
<p>Suppose you use a <code>TIMESTAMP WITHOUT TIME ZONE</code> data type, because you know all your values are going to be UTC. Unfortunately, when you read the values back via your Go code and convert them to strings, you get something like this:</p>
<pre><code>2012-11-01 22:08:41 +0000 +0000
</code></pre>
<p>Why is Go giving you “+0000” twice? The answer is explained in <a href="https://github.com/golang/go/issues/11712">Go issue #11712</a>. If the <code>time.Time</code> value only has a numeric time zone offset, and not a semantic timezone (such as ‘Central/CDT’ or ‘UTC’), the numeric offset is <em>also</em> used as the time zone’s name.</p>
<p>The value you wrote into the database was in UTC. However, PostgreSQL threw that away when the value was stored in a column of type <code>TIMESTAMP WITHOUT TIME ZONE</code>. When PostgreSQL fishes the value <em>out</em> of a column of that type, it returns a string with no timezone information to the SQL driver. The Go <code>pq</code> driver’s behavior is to assume that a timestamp with no time zone information has offset 0, rather than to assume that it’s UTC.</p>
<p>This is correct behavior on the driver’s part. There are multiple time zones with offset 0, and they aren’t identical to UTC. You <em>could</em> be in British Standard Time, or in Western European Time, in which case daylight saving time changes will need to be accounted for.</p>
<p>So, what if you really want your timestamps to be returned with a value in UTC? I did, so I started considering my options.</p>
<h2 id="option-1-do-it-in-go">Option 1: Do it in Go</h2>
<p>The first option I considered was to write code to mess with every timestamp I got back from my database, check if its zime zone offset was 0, and if so change its timezone to UTC.</p>
<p>The disadvantages of this approach are pretty obvious: I have to write the code, debug it, and remember to insert it everywhere I query a timestamp column.</p>
<p>In fact, the Go <code>pq</code> driver seems to do something a bit like this – looking at <a href="https://github.com/lib/pq/blob/master/encode.go#L353">the code for ParseTimestamp</a>, it adjusts the time zone to be the current location’s time zone if the offset matches what PostgreSQL returns.</p>
<p>I didn’t want to have to remember to call a function to correct all my timestamp values after every query; I wanted a solution that would give me the right value when I called <code>sql.Scan()</code>.</p>
<h2 id="option-2-what-if-we-store-the-time-zone-utc-every-time">Option 2: What if we store the time zone ‘UTC’ every time?</h2>
<p>The second option I considered was to change the timestamp column to be a <code>TIMESTAMP WITH TIME ZONE</code>, so that my <code>time.Time</code> value’s time zone would be recorded in the database and hopefully returned later on.</p>
<p>However, when I investigated further, it turned out that that’s not what actually happens. In spite of the name, <code>TIMESTAMP WITH TIME ZONE</code> columns <em>do not have a stored time zone</em>. If you read <a href="https://www.postgresql.org/docs/9.1/static/datatype-datetime.html">the documentation</a> carefully, you’ll find this note in section 8.4:</p>
<blockquote>
<p>For timestamp with time zone, the internally stored value is always in UTC (Universal Coordinated Time, traditionally known as Greenwich Mean Time, GMT). An input value that has an explicit time zone specified is converted to UTC using the appropriate offset for that time zone.</p>
</blockquote>
<p>The original time zone is thrown away; there are no functions to return what it was. So <code>TIMESTAMP WITH TIMEZONE</code> really means ’timestamp to which time zone calculations should be applied’, or ’timestamp which should have a time zone associated with it when read from the column’.</p>
<p>To test this, I wrote two timestamps into a <code>TIMESTAMP WITH TIME ZONE</code> column and then read the values back, and this happened:</p>
<pre tabindex="0"><code>Value written         Value read back by Go
2012-11-01T22:08:41Z  2012-11-01 17:08:41 -0500 CDT
2012-11-30T19:08:41Z  2012-11-30 13:08:41 -0600 CST
</code></pre><p>Both values were written while my current time zone was CST. So it seems PostgreSQL adjusted the values to be in <em>what it thinks the local time zone would have been at the UTC stored moment internal to the timestamp</em>. It certainly didn’t store the time zone of the value written into the column, or my local time zone when I wrote the values.</p>
<p>To make things worse, the adjustment was being made to the <em>server</em> time zone. That can be altered by the database server owner in <code>postgresql.conf</code>, and good luck getting it changed if you’re using someone else’s server, like a cloud service provider’s server.</p>
<p>For maximum code robustness, I clearly couldn’t insist that the server be configured to return UTC timestamps from <code>TIMESTAMP WITH TIME ZONE</code> columns.</p>
<p>What’s more, my entire goal was to avoid having PostgreSQL adjust with my timestamps. <code>TIMESTAMP WITH TIME ZONE</code> seemed fundamentally the wrong thing to do, as it has the opposite effect, telling PostgreSQL to go ahead and try to perform time zone adjustments.</p>
<h2 id="option-3-back-to-zoneless-timestamps">Option 3: Back to zoneless timestamps?</h2>
<p>This led me back to my original choice of <code>TIMESTAMP WITHOUT TIME ZONE</code> for all my timestamp columns. I wondered if I could get PostgreSQL to return a value which Go would convert to a <code>time.Time</code> in UTC.</p>
<p>Since my experiment had shown that Go would give me a named time zone if the value it retrieved was a <code>TIMESTAMP WITH TIME ZONE</code>, I decided to try using the PostgreSQL <code>AT TIME ZONE</code> construct, also available as the function <code>timezone(zone, timestamp)</code>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sql" data-lang="sql"><span class="line"><span class="cl"><span class="k">SELECT</span><span class="w"> </span><span class="n">ID</span><span class="p">,</span><span class="w"> </span><span class="k">Timestamp</span><span class="w"> </span><span class="k">AT</span><span class="w"> </span><span class="n">TIME</span><span class="w"> </span><span class="k">ZONE</span><span class="w"> </span><span class="s1">&#39;UTC&#39;</span><span class="w"> </span><span class="k">FROM</span><span class="w"> </span><span class="n">UpdateLog</span><span class="w">
</span></span></span></code></pre></div><p>Or equivalently:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sql" data-lang="sql"><span class="line"><span class="cl"><span class="k">SELECT</span><span class="w"> </span><span class="n">ID</span><span class="p">,</span><span class="w"> </span><span class="n">timezone</span><span class="p">(</span><span class="s1">&#39;UTC&#39;</span><span class="p">,</span><span class="w"> </span><span class="k">Timestamp</span><span class="p">)</span><span class="w"> </span><span class="k">FROM</span><span class="w"> </span><span class="n">UpdateLog</span><span class="w">
</span></span></span></code></pre></div><p>Sure enough, Go now gave me values with a semantic time zone. Unfortunately, it was still the server’s local time zone, which the UTC values were adjusted to.</p>
<p>I did some more digging, and discovered that there’s a <code>timezone</code> parameter you can set during a PostgreSQL session. If you do <code>SET TIMEZONE TO 'UTC'</code> before executing your queries, you’ll find that all your <code>timezone('UTC', value)</code>  are returned through as UTC. Hurrah!</p>
<p>There’s just one more problem: it’s a pain having to <code>SET TIMEZONE</code> for every database connection, not least because Go’s <code>sql.DB</code> is a connection <em>pool</em>. How to make sure every connection gets the appropriate value?</p>
<p>The answer to that conundrum is that you can add parameter values to the connection string. So after I have fetched the URL of the cloud PostgreSQL server from the environment, I add the parameter:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="nx">u</span><span class="p">,</span><span class="w"> </span><span class="nx">uerr</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">url</span><span class="p">.</span><span class="nf">Parse</span><span class="p">(</span><span class="nx">dburi</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="k">if</span><span class="w"> </span><span class="nx">uerr</span><span class="w"> </span><span class="o">!=</span><span class="w"> </span><span class="kc">nil</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="k">return</span><span class="w"> </span><span class="nx">dburi</span><span class="p">,</span><span class="w"> </span><span class="nx">uerr</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">v</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">u</span><span class="p">.</span><span class="nf">Query</span><span class="p">()</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">v</span><span class="p">.</span><span class="nf">Set</span><span class="p">(</span><span class="s">&#34;timezone&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;UTC&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">u</span><span class="p">.</span><span class="nx">RawQuery</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="nx">v</span><span class="p">.</span><span class="nf">Encode</span><span class="p">()</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">dburi</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="nx">u</span><span class="p">.</span><span class="nf">String</span><span class="p">()</span><span class="w">
</span></span></span></code></pre></div><p>This adds the parameter <code>timezone=UTC</code> to the URL if it isn’t there, and overrides any timezone parameter already in the URL.</p>
<h2 id="option-4-the-least-work-the-right-answer">Option 4: The least work, the right answer</h2>
<p>Having worked out that I could set the session time zone, wrap values in <code>timezone('UTC', value)</code>, and get the results I wanted, I suddenly realized I was being dumb: <code>timezone('UTC', value)</code> around a timestamp-without-timezone value, with the session timezone set to UTC, gives <em>exactly the same results</em> as reading a timestamp-with-timezone column with the session timezone set to UTC. No <code>timezone()</code> adjustment call required.</p>
<p>So while it might seem that making the columns <code>TIMESTAMP WITH TIME ZONE</code> is storing unnecessary information or causing unnecessary time zone adjustments, that’s not true – the stored information is just a UTC timestamp whether your timestamps are WITH TIME ZONE or not.</p>
<p>The difference between <code>TIMESTAMP WITH TIMEZONE</code> and <code>TIMESTAMP WITHOUT TIME ZONE</code> is whether your values get time zone adjusted  when you read or write them. And if you set <code>timezone=UTC</code> for the session, they don’t.</p>
<p>So in conclusion:</p>
<ol>
<li>Use <code>TIMESTAMP WITH TIME ZONE</code> so that you get a time zone in your retrieved values, and don’t worry because one isn’t being stored.</li>
<li>Use <code>timezone=UTC</code> in the connection URL so that the time zone you get in your retrieved values is the one you want, UTC.</li>
<li>Convert the <code>time.Time</code> values to whatever time zone you want for display purposes.</li>
</ol>
<p>When writing data, ideally convert to UTC first, though PostgreSQL will probably do the right thing as long as Go knows the right numeric offset for the time zone associated with the <code>time.Time</code> value.</p>
<p>And remember, elect me to be Supreme Galactic Ruler. I will decree that all times and dates are to be in UTC and formatted as per ISO 8601, and I will send any violators to the Imperial Martian Salt Mines.</p>
]]></content></entry><entry><title type="html">Go Fish</title><link href="https://lpar.ATH0.com/posts/2017/10/go-fish/"/><id>https://lpar.ATH0.com/posts/2017/10/go-fish/</id><published>2017-10-26T10:31:42-05:00</published><updated>2017-10-26T10:31:42-05:00</updated><summary>The Fish shell and why I switched to it from zsh.</summary><content type="html"><![CDATA[<p>I’ve been trying <a href="http://fishshell.com/">Fish</a>, the Friendly Interactive Shell. I was driven to do so by two <a href="http://www.zsh.org/">Zsh</a> bugs.</p>
<p>The first is that when I SSHed from a Linux machine to a Mac, something was getting messed up or not initiated correctly in my terminal session. There were control codes which messed up the display, and no matter what I set the prompt environment variables or TERM to, they remained. The problem didn’t occur in the opposite direction.</p>
<p>The more recent issue was that Zsh’s automatic “here’s what I think you might have meant” code broke, and commands which were unrecognized were completely ignored with no error message. This was enough of a potential issue to make me look again at other shells.</p>
<p>Over the years I’ve gone from <code>csh</code> to <code>tcsh</code> to <code>bash</code> to <code>zsh</code>, so the prospect of another change of shell wasn’t that daunting. (For the curious, I started with <code>csh</code> because it was the best shell available on Xenix in the mid 1980s.)</p>
<p>I don’t write code in shell script unless I absolutely have to, so scripting strength is relatively unimportant to me. All I really care about are ease of use and ease of configuration. Based on those criteria, my early impressions of <code>fish</code> are positive.</p>
<ol>
<li>
<p>It sets up my terminal correctly. SSH from Linux to Mac works fine now that it’s my login shell.</p>
</li>
<li>
<p>Terminal emulator tabs in Linux actually show what’s running in them without my having to do any special configuration.</p>
</li>
<li>
<p>The <code>vi</code> command line editing works well, again without any messing with configuration.</p>
</li>
<li>
<p>The prompt is sensible by default – it shows vi mode, user name, hostname, and abbreviated <code>pwd</code> by default. It’s the first shell where I haven’t felt the need to mess with the prompt.</p>
</li>
<li>
<p>Config is handled cleanly. Unlike the mess of startup scripts used by <code>bash</code>, which installers often try to patch for you, there’s a single <code>config.fish</code> for user preferences and a <code>conf.d</code> directory for package-provided scripts.</p>
</li>
<li>
<p>Autocomplete works all over the place, thanks to <code>fish</code> parsing man pages to work out the available options. It also autosuggests completions in gray without my having to hit tab, so I end up using the feature more.</p>
</li>
<li>
<p>Variables are all lists, making it easier to script operations on multiple files.</p>
</li>
<li>
<p>There’s a really handy ‘universal’ global variable type which applies to all <code>fish</code> sessions, <em>including ones already running</em>.</p>
</li>
</ol>
<p>Lacking a library of zsh or bash scripts, my first task was to convert my <code>.zshenv</code> file to <code>fish</code> syntax. The biggest part of that was rewriting the chunk of script which works out my <code>PATH</code>. For the sake of cross-platform compatibility and consistency of behavior, I make my shell run through a list of <em>possible</em> path directories found on all the Unix machines I use, in the order <em>I</em> would want them, and construct a path from the ones which exist. It didn’t take long to rewrite, though I admit I found myself wondering if the syntax changes between bash/zsh and fish were <em>really</em> worth the pain caused.</p>
<p>Then I tackled <code>.zshrc</code>, and the problem which inspired this article: <code>ssh-agent</code>. If SSH password prompting has always worked for you, well, consider yourself lucky, because I now know what a ghastly pile of hacks it is behind the scenes.</p>
<p>For starters, GNOME’s graphical SSH agent is about as <a href="https://ask.fedoraproject.org/en/question/92448/how-do-i-get-proper-ssh-agent-functionality-in-gnome/">defective and lacking in basic functionality</a> as I’ve come to expect from GNOME, in that it doesn’t understand elliptic curve keys or bcrypt-protected keys. For that reason I’d been using <code>ssh-agent</code>, but it had never really remembered that I’d unlocked my SSH keys already, and I’d never bothered to dig in and find out why. I’d just been typing my key passphrase every time, or accepting that <code>ssh-add</code> would only apply to the current shell.</p>
<p>Here’s the problem: When you run <code>ssh-agent</code> it sets up a daemon with a socket for communication. It then outputs the location of the socket and the pid of the daemon. The shell is supposed to pick up those values, and then when you spawn a new shell that new shell can continue to use the existing daemon.</p>
<p>The problem is <em>how</em> the new shell is supposed to do so. The agent spits out the information in the form of a piece of shell script which the shell is supposed to execute, which you can see by using the <code>-D</code> option to prevent the agent from daemonizing:</p>
<pre><code>% ssh-agent -D
SSH_AUTH_SOCK=/tmp/ssh-Xxp2vbEK9x4k/agent.16030; export SSH_AUTH_SOCK;
echo Agent pid 16030;
^C
</code></pre>
<p>There’s also an option to kill the current agent daemon and clean up the socket.</p>
<p>Clearly there’s an issue around the fact that <code>ssh-agent</code> outputs shell script. It knows how to output <code>sh</code> and <code>csh</code>, and that’s it – no <code>fish</code>, no <code>rc</code>, no <code>emacs</code>… But that’s the most superficial issue.</p>
<p>The deeper problem is that the operation each shell <em>actually</em> wants to perform is: “If the information in the environment points at a live daemon and a socket file, use them. Otherwise, kill any daemon with the pid that’s in the environment, start a new daemon with a new pid and socket, and use those.”</p>
<p>If I were writing <code>ssh-agent</code> I’d make that the default behavior, or at the very least <em>a behavior available using command line options</em>. No such luck with <code>ssh-agent</code> though. You can either kill an existing daemon, or you can start a new one. You can’t do both, presumably because they’re logically different operations. You also can’t ask the agent to check which is necessary.</p>
<p>No problem, you think, and you write a script which checks the socket and PID and calls <code>ssh-agent -k</code> to clean up if either of them are missing. And then you discover that if the environment points at a PID which <em>isn’t</em> a running daemon – say, if it crashed – the agent throws an error.</p>
<p>My summary would be that <code>ssh-agent</code> is pedantically correct rather than useful, with functionality implemented without regard to how anyone would want to use it in real life.</p>
<p>As evidence for this, my <code>.zshrc</code> (customized from a default provided by some Linux distro) simply called <code>ssh-agent</code> and hoped for the best, and I’m <a href="http://blog.joncairns.com/2013/12/understanding-ssh-agent-and-ssh-add/">not the only one</a> to have done so. There are long-winded <a href="https://github.com/wwalker/ssh-find-agent/blob/master/ssh-find-agent.sh">attempts to work around the SSH agent’s behavior</a>, but I’d never installed any of them. I’d just lived with typing my passphrase a lot. I imagine there are lots of Linux users who don’t even know that it can be any other way.</p>
<p>There are various solutions out there to make the SSH agent work with <code>fish</code>, of course. They mostly seem to be distributed as plugins and are fairly long and involve using <code>grep</code>, <code>sed</code>, and even <code>/bin/sh</code>. I felt like I could do better.</p>
<p>After quite a lot of experimentation, I came up with <a href="https://gist.github.com/lpar/44f45d78e7920f61bb235d192578defb">a short self-contained fish script for ssh-agent</a>. It uses <code>ps</code> to test for a running agent, and <code>kill</code> to kill one, but everything else is done inside fish. It will either display “Found ssh-agent” or “Started ssh-agent” depending on which operation it had to perform, so you can check its behavior when you open new tabs or start subshells. (Oh, and on macOS you don’t need it at all.)</p>
<p>Once I’d gotten <code>ssh-agent</code> working, it turned out that none of the rest of my <code>.zshrc</code> was necessary in <code>fish</code>. It was 200+ lines of setup to make things work which simply worked by default in the new shell. So, if you don’t use your interactive shell as your main scripting language, give <code>fish</code> a try.</p>
]]></content></entry><entry><title type="html">Curried JavaScript</title><link href="https://lpar.ATH0.com/posts/2017/09/curried-javascript/"/><id>https://lpar.ATH0.com/posts/2017/09/curried-javascript/</id><published>2017-09-23T09:58:17-05:00</published><updated>2017-09-23T09:58:17-05:00</updated><summary>Well, technically partial application.</summary><content type="html"><![CDATA[<p>I got contacted by someone who had been stumped by an interview question about JavaScript. The question involved <a href="https://en.wikipedia.org/wiki/Currying">currying functions</a>, and although I’ve mentioned curried functions and JavaScript before I haven’t really done more than assume people know what that is. This person had found my web site but remained confused.</p>
<p>Since I’m on vacation and I was drinking my morning coffee and feeling generally benevolent to the world, I wrote up a reply. This is that reply, recycled as a post and expanded.</p>
<hr>
<h3 id="problem">Problem:</h3>
<p>Given the following information:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="kd">var</span> <span class="nx">add</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">a</span><span class="p">,</span> <span class="nx">b</span><span class="p">)</span> <span class="p">{</span> <span class="k">return</span> <span class="nx">a</span><span class="o">+</span><span class="nx">b</span><span class="p">;</span> <span class="p">};</span>
</span></span><span class="line"><span class="cl"><span class="kd">var</span> <span class="nx">add2</span> <span class="o">=</span> <span class="nx">mybind</span><span class="p">(</span><span class="nx">add</span><span class="p">,</span> <span class="mi">2</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="nx">add2</span><span class="p">(</span><span class="mi">5</span><span class="p">);</span> <span class="c1">// outputs 7
</span></span></span></code></pre></div><p>Write the <code>mybind</code> function.</p>
<h3 id="discussion-and-solution">Discussion and Solution</h3>
<p>First of all, to keep things as clear as possible I’m going to follow Douglas Crockford’s suggestion in “<a href="http://amzn.to/2ykg1Xh">JavaScript: The Good Parts</a>” — a book which I strongly recommend — and put a space before the parentheses <code>( )</code> when they aren’t being used to invoke a function. So if you see <code>a(b)</code> in my code without a space it means <code>a</code> is a function and <code>b</code> is an argument.</p>
<p>So, let’s run through the code from the problem.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="kd">var</span> <span class="nx">add</span> <span class="o">=</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">a</span><span class="p">,</span> <span class="nx">b</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="k">return</span> <span class="nx">a</span><span class="o">+</span><span class="nx">b</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">};</span>
</span></span></code></pre></div><p>This one’s easy enough — we’re defining a function which adds two values together and returns the result.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="kd">var</span> <span class="nx">add2</span> <span class="o">=</span> <span class="nx">mybind</span><span class="p">(</span><span class="nx">add</span><span class="p">,</span> <span class="mi">2</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nx">add2</span><span class="p">(</span><span class="mi">5</span><span class="p">);</span> <span class="c1">// outputs 7
</span></span></span></code></pre></div><p>Now it gets tricky. Looking at the last line first, I’m going to assume that “outputs 7” means that we want it to <em>return</em> 7, so in my final code — which I’m testing with NodeJS — I’m going to do:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span> <span class="nx">add2</span><span class="p">(</span><span class="mi">5</span><span class="p">)</span> <span class="p">);</span>
</span></span></code></pre></div><p>I’ll consider the other possibility later.</p>
<p>Now <code>add2(5)</code> returns <code>7</code>, so <code>add2</code> must be a function which takes a single argument and returns a single argument.</p>
<p>But <code>add2</code> is created by the mysterious <code>mybind</code> function in the line before. So now we know that the <code>mybind</code> function itself must return a function. We also know what kind of function it returns — one which takes a single argument, and returns a single argument. Finally, we know that mybind takes two arguments.</p>
<p>So let’s write a skeleton version of “mybind” which does all that, but leave all the insides empty:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="kd">var</span> <span class="nx">mybind</span> <span class="o">=</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">a</span><span class="p">,</span> <span class="nx">b</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="k">return</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">x</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="c1">// ??? compute r for result
</span></span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="nx">r</span>
</span></span><span class="line"><span class="cl">  <span class="p">};</span>
</span></span><span class="line"><span class="cl"><span class="p">};</span>
</span></span></code></pre></div><p>Clear so far? That’s most of the battle, all we need to do now is work out what goes in the <code>// ???</code> line, given <code>a</code>, <code>b</code> and <code>x</code>.</p>
<p>At this point I was still having trouble seeing the right answer before finishing my morning coffee, so I decided to give myself some help: I renamed the function arguments to remind me of what the example values are in the problem! So instead of calling the first parameter to mybind <code>a</code>, I called it <code>add</code>; I called the variable which is going to hold the value 2 in the problem <code>two</code>, and so on. Once I did that, I had this:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="kd">var</span> <span class="nx">mybind</span> <span class="o">=</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">add</span><span class="p">,</span> <span class="nx">two</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="k">return</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">five</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="c1">// ??? compute seven for result
</span></span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="nx">seven</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="p">};</span>
</span></span><span class="line"><span class="cl"><span class="p">};</span>
</span></span></code></pre></div><p>At this point, the right answer will hopefully leap out at you the way it leapt out at me: remembering that <code>add</code> is a function which adds, <code>seven = add(five, two)</code>.</p>
<p>So, the final code is:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="kd">var</span> <span class="nx">mybind</span> <span class="o">=</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">add</span><span class="p">,</span> <span class="nx">two</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="k">return</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">five</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kd">var</span> <span class="nx">seven</span> <span class="o">=</span> <span class="nx">add</span><span class="p">(</span><span class="nx">five</span><span class="p">,</span> <span class="nx">two</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="nx">seven</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="p">};</span>
</span></span><span class="line"><span class="cl"><span class="p">};</span>
</span></span></code></pre></div><p>Of course, we can now rename the function arguments back to something general, and eliminate the unnecessary temporary variable. Here’s the final result, which I fed to NodeJS to check that it worked:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="kd">var</span> <span class="nx">add</span> <span class="o">=</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">a</span><span class="p">,</span> <span class="nx">b</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="k">return</span> <span class="nx">a</span> <span class="o">+</span> <span class="nx">b</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">};</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kd">var</span> <span class="nx">mybind</span> <span class="o">=</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">fn</span><span class="p">,</span> <span class="nx">a</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="k">return</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">b</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="nx">fn</span><span class="p">(</span><span class="nx">b</span><span class="p">,</span> <span class="nx">a</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">  <span class="p">};</span>
</span></span><span class="line"><span class="cl"><span class="p">};</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kd">var</span> <span class="nx">add2</span> <span class="o">=</span> <span class="nx">mybind</span><span class="p">(</span><span class="nx">add</span><span class="p">,</span> <span class="mi">2</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">add2</span><span class="p">(</span><span class="mi">5</span><span class="p">));</span>
</span></span></code></pre></div><p>The only remaining issue is whether <code>add2(5)</code> is really supposed to <em>return</em> 7 for the assumed <a href="https://en.wikipedia.org/wiki/Read%E2%80%93eval%E2%80%93print_loop">REPL loop</a> to display, or whether it was actually supposed to <em>output</em> 7 directly. That’s simple enough, though — it’s just a matter of changing mybind to (say) call <code>console.log</code> instead of returning the value.</p>
<h3 id="lets-make-it-more-confusing">Let’s Make It More Confusing</h3>
<p>The functional programmers of the JavaScript community will find the above solution rather unsatisfactory. It’s far too verbose! If functional programming is about anything, it’s about making your code look like scary opaque math in order to save a few keystrokes.</p>
<p>Fortunately, ECMAScript now has a wonderful tool for doing that: <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions">arrow functions</a>. Instead of the boring old:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="kd">function</span> <span class="p">(</span><span class="nx">a</span><span class="p">,</span> <span class="nx">b</span><span class="p">)</span> <span class="p">{</span> <span class="k">return</span> <span class="nx">a</span> <span class="o">+</span> <span class="nx">b</span><span class="p">;</span> <span class="p">};</span>
</span></span></code></pre></div><p>we can type:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="p">(</span><span class="nx">a</span><span class="p">,</span> <span class="nx">b</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="nx">a</span> <span class="o">+</span> <span class="nx">b</span><span class="p">;</span>
</span></span></code></pre></div><p>Half as much typing! So let’s use this new syntax to rewrite our <code>mybind</code> function:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="kd">let</span> <span class="nx">mybind</span> <span class="o">=</span> <span class="p">(</span><span class="nx">fn</span><span class="p">,</span> <span class="nx">a</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="p">(</span><span class="nx">b</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="nx">fn</span><span class="p">(</span><span class="nx">b</span><span class="p">,</span> <span class="nx">a</span><span class="p">);</span>
</span></span></code></pre></div><p>Isn’t that so much better for confusing inexperienced programmers?</p>
<p>As you can probably tell, I’m not a fan of this shorthand syntax. I feel that it obscures function bodies, making them implicit, and at a glance it looks too similar to a simple expression. I’m sure mathematicians love it, but I came to computer science via science and it makes my brain hurt.</p>
<h3 id="now-with-added-curry">Now With Added Curry</h3>
<p>Functional programmers are also likely unsatisfied with my mentioning currying at the start of the article, because <em>technically</em> the problem is about <a href="https://en.wikipedia.org/wiki/Partial_application">partial application</a> via function binding. So let me show why I thought “currying” when I saw the problem.</p>
<p>Here’s our problem and solution in shiny new ECMA syntax:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="kd">let</span> <span class="nx">add</span> <span class="o">=</span> <span class="p">(</span><span class="nx">a</span><span class="p">,</span> <span class="nx">b</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="nx">a</span> <span class="o">+</span> <span class="nx">b</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kd">let</span> <span class="nx">mybind</span> <span class="o">=</span> <span class="p">(</span><span class="nx">fn</span><span class="p">,</span> <span class="nx">a</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="p">(</span><span class="nx">b</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="nx">fn</span><span class="p">(</span><span class="nx">b</span><span class="p">,</span> <span class="nx">a</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kd">let</span> <span class="nx">add2</span> <span class="o">=</span> <span class="nx">mybind</span><span class="p">(</span><span class="nx">add</span><span class="p">,</span> <span class="mi">2</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">add2</span><span class="p">(</span><span class="mi">5</span><span class="p">));</span>
</span></span></code></pre></div><p>Currying is taking a function with multiple arguments, and reducing it to a sequence of applications of functions with a single argument. So <em>f(x,y,z)</em> becomes <em>f’(x)(y)(z)</em>, where <em>f’</em> is the curried version of <em>f</em>. <em>f’(x)</em> returns an unnamed function, and when that function is called with the value <code>y</code> <em>that</em> returns a function, and when <em>that</em> function is called with the value <code>z</code> it returns the answer.</p>
<p>We can then go further and say that <em>f(x,y,z)</em> is  <em>curry(f)(x)(y)(z)</em> where <em>curry</em> is the currying function which takes <em>f</em> and returns <em>f’</em>.</p>
<p>When I saw the problem, I imagined a curried add function:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="kd">let</span> <span class="nx">cadd</span> <span class="o">=</span> <span class="p">(</span><span class="nx">a</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="p">(</span><span class="nx">b</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="nx">add</span><span class="p">(</span><span class="nx">b</span><span class="p">,</span> <span class="nx">a</span><span class="p">);</span>
</span></span></code></pre></div><p>The imaginary curried add <code>cadd(a)</code> would return a function which, when applied to <code>b</code>, would call <code>add(a, b)</code> and return the result.</p>
<p>The <code>cadd</code> function is similar to mybind, except that <code>mybind</code> takes an additional argument for the function to apply instead of <code>add</code>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="kd">let</span> <span class="nx">mybind</span> <span class="o">=</span> <span class="p">(</span><span class="nx">fn</span><span class="p">,</span> <span class="nx">a</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="p">(</span><span class="nx">b</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="nx">fn</span><span class="p">(</span><span class="nx">b</span><span class="p">,</span> <span class="nx">a</span><span class="p">);</span>
</span></span></code></pre></div><p>So let’s finish the currying process. Given that we know what curried add would look like, we can write the currying function which, given <code>add</code>, returns <code>cadd</code>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="kd">let</span> <span class="nx">curry</span> <span class="o">=</span> <span class="p">(</span><span class="nx">f</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="p">(</span><span class="nx">a</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="p">(</span><span class="nx">b</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="nx">f</span><span class="p">(</span><span class="nx">b</span><span class="p">,</span> <span class="nx">a</span><span class="p">);</span>
</span></span></code></pre></div><p>And sure enough:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="kd">let</span> <span class="nx">add</span> <span class="o">=</span> <span class="p">(</span><span class="nx">a</span><span class="p">,</span> <span class="nx">b</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="nx">a</span> <span class="o">+</span> <span class="nx">b</span><span class="p">;</span>    
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kd">let</span> <span class="nx">curry</span> <span class="o">=</span> <span class="p">(</span><span class="nx">f</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="p">(</span><span class="nx">a</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="p">(</span><span class="nx">b</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="nx">f</span><span class="p">(</span><span class="nx">a</span><span class="p">,</span> <span class="nx">b</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span> <span class="nx">curry</span><span class="p">(</span><span class="nx">add</span><span class="p">)(</span><span class="mi">5</span><span class="p">)(</span><span class="mi">2</span><span class="p">)</span> <span class="p">);</span> <span class="c1">// outputs 7
</span></span></span></code></pre></div><p>If you’re totally lost, don’t worry too much — this is pretty much useless, except for getting a computer science degree or terrifying people in technical interviews.</p>
]]></content></entry><entry><title type="html">Go: Some lessons learned</title><link href="https://lpar.ATH0.com/posts/2017/08/go-some-lessons-learned/"/><id>https://lpar.ATH0.com/posts/2017/08/go-some-lessons-learned/</id><published>2017-08-11T14:23:14-05:00</published><updated>2017-08-11T14:23:14-05:00</updated><summary>The good, the bad, and the annoying.</summary><content type="html"><![CDATA[<p>Based on my experience building, deploying and maintaining a small web application for work purposes, I’ve assembled some thoughts on Go.</p>
<h3 id="design-patterns">Design patterns</h3>
<p>I started out with little code organization in terms of files and directories.
I eventually migrated to model, view and controller subdirectories, plus an
internal/test directory for test utilities.</p>
<p>I’m not a big believer in ORMs. I’ve tried them in the Java world, and found
that the benefits aren’t enough to make up for the downsides, at least not
given my reasonable SQL-query-writing abilities. I eventually settled on a
DAO model, with lightweight core object classes and FooMapper DAOs.</p>
<h3 id="verb-choice">Verb choice</h3>
<p>I think DAO verbs should match REST verbs. It’s tempting to implement UPSERT
and use it for both PUT and POST, but then your REST API ends up overly
forgiving.</p>
<p>The downside of using REST verbs is that it pushes some of the problem onto
your service consumers – they need to know whether they’re writing an object
which already exists, or a new one. On the plus side, it makes the DAO code
pretty trivial.</p>
<h3 id="method-naming">Method naming</h3>
<p>I’ve found that a good naming pattern is to include the class name in the DAO
method name if the method takes an ID as argument, but to exclude it as
redundant if the method takes an object argument. This also means you can have
both Delete(Foo) and DeleteFoo(id).</p>
<p>So I ended up with</p>
<ul>
<li>NewFoo (or just Foo{})</li>
<li>GetFoo</li>
<li>DeleteFoo</li>
<li>Put(Foo)</li>
<li>Post(Foo)</li>
</ul>
<h3 id="go-vs-java">Go vs Java</h3>
<p>Avoiding cyclomatic complexity seems to be much easier in Go than in Java. In
Java, I regularly get PMD complaining about method complexity &gt; 25; in Go, my
highest (excluding test code) was 9.</p>
<p>I spent more time worrying about how to structure my code, and less time
actually coding or working out how to do things. Eventually I’ll learn the Go
patterns, but for now it’s all different. So, don’t expect to use the same
patterns you would in Java or Ruby. For example, in Java it’s considered a
mortal sin to expose fields directly. In Go, it’s standard practice, if you
look at the standard library.</p>
<p>If something ends up being complicated, you’re probably doing it wrong. This is
a very generally applicable rule, but particularly relevant when moving between
programming languages with very different paradigms. For instance, I kept
forgetting that in Go, you don’t declare that you’re going to implement an
interface – you just do it.</p>
<p>Similarly, when I started writing my web service handlers, I found myself
frustrated by the lack of generics. I soon had a ton of code working around the
lack of generics using a shared interface, factories to instantiate objects,
and long switch statements. After that, I used currying to build a function
which would build a function to perform operations on an object of a given
type, using reflection where necessary. After <em>that</em>, I ripped out all the
clever code and just wrote plain old classes which implement the same
interface. It would be nice if Go had generics to <em>enforce</em> that the classes
have the same interface, but it’s not a huge deal.</p>
<h3 id="how-to-learn-go">How to learn Go</h3>
<p>Follow a learner’s path:</p>
<ol>
<li>Implement minimal functionality.</li>
<li>Implement unit tests for 1.</li>
<li>Lint 1 &amp; 2 until you’ve resolved all issues.</li>
<li>Iterate.</li>
</ol>
<p>Think interfaces first, and make your interfaces small.</p>
<p>And of course, every time you find a bug, try to add a unit test that would
have detected it.</p>
<h2 id="antipatterns">Antipatterns</h2>
<p>If you return <code>x, error</code>, error should always be non-nil if x is invalid.
Otherwise, you’re just asking for nil pointer runtime crashes.</p>
<p>For a field to be serialized as JSON or XML, it needs to be exported – but
that means it has to be visible to users. If you have a Java background it’s
tempting to have a hidden field and getter/setter pair, but then you need to
write your own custom serializer. The Go way is to simply make the field
visible and assume users will behave responsibly.</p>
<p>If you are building a web service, it might be tempting to try to mock the
database and mock up HTTP requests for your unit tests. Then you realize you
need to bypass the router, and pretty soon your test code is longer than the
handler method you’re actually testing. Better to do a full functional unit
test including router and database components. After all, a bad route change
can kill your application as dead as a handler error.</p>
<p>Don’t try to build class relationships using struct embedding. Trust me, that
way lies madness.</p>
<p>Don’t try to work around the lack of generics. If you can’t come up with a
single interface, just go ahead and build independent classes.</p>
<h2 id="annoyances">Annoyances</h2>
<p>There’s no Date type, so if you want one for your database records you’ll have
to build it yourself.</p>
<h2 id="end-thoughts">End thoughts</h2>
<p>After a long time in the Ruby/Rails and Java/JSF world, Go feels extremely
“bare metal”. No login system provided, no flash messages, no sessions even!
It can certainly trigger some impostor syndrome feelings.</p>
<p>In the end, though, there’s the benefit that there’s no “magic” being applied;
I’ve found that magic do-it-for-you code often misbehaves, and when it does you
can be powerless to fix it.</p>
<p>Ultimately, I still like Go, and want to carry on working with it. The radical
simplicity sometimes makes for some annoyances, but it has upsides.</p>
]]></content></entry><entry><title type="html">Perils of automatic invisible software updates</title><link href="https://lpar.ATH0.com/posts/2016/10/perils-of-automatic-invisible-software-updates/"/><id>https://lpar.ATH0.com/posts/2016/10/perils-of-automatic-invisible-software-updates/</id><published>2016-10-21T14:55:01+00:00</published><updated>2016-10-21T14:55:01+00:00</updated><summary>How my network speed looked degraded when it wasn’t.</summary><content type="html"><![CDATA[<p>A couple of days ago I noticed my Google Fiber uplink was only 100Mbps instead of 1Gbps. While debugging with the tech via phone, it seemed as though any time I had something connected to port 4 on the network box, the speed dropped. I moved cables around until the speed was back to normal, and they scheduled a tech to come swap out the box.</p>
<p>Today the tech arrived and was unable to reproduce the problem. Even with port 4 connected to the switch — the highest traffic network segment — everything was normal.</p>
<p>Finally, he checked the network maintenance logs. It turned out that I just happened to run a speed test during the exact time period when Google was pushing out a firmware update to my network box. It probably dropped the link to 100Mbps while it was flashing the firmware and rebooting. The fiber UI is very barebones and doesn’t show that information at all, so I had no way to know that.</p>
<p>Making details invisible to users is great, until the moment when things don’t work as expected.</p>
]]></content></entry><entry><title type="html">OpenID Connect introduction</title><link href="https://lpar.ATH0.com/posts/2016/05/openid-connect-introduction/"/><id>https://lpar.ATH0.com/posts/2016/05/openid-connect-introduction/</id><published>2016-05-27T23:18:15+00:00</published><updated>2016-05-27T23:18:15+00:00</updated><summary>A simplified OAuth2 authentication flow.</summary><content type="html"><![CDATA[<p>OpenID Connect is an authentication standard built on top of OAuth2. From my point of view it has the following key features:</p>
<ol>
<li>
<p>It’s a lot simpler than anything involving SAML. Validating SAML requires a full implementation of <a href="https://en.wikipedia.org/wiki/XML_Signature">XML Signature</a>, which requires an implementation of <a href="https://www.w3.org/TR/xml-exc-c14n/">XML Canonicalization</a>, which requires a full <a href="https://en.wikipedia.org/wiki/XPath">XPath</a> implementation. I’m not anti-XML in general, but I don’t think authenticating a user should require parsing, traversing and rearranging a DOM tree multiple times.</p>
</li>
<li>
<p>It’s more secure than OAuth2, as we’ll see below.</p>
</li>
<li>
<p>It can be implemented in situations where your web application can only reach the authentication provider via HTTPS — you don’t need to be able to make LDAP or Active Directory connections.</p>
</li>
<li>
<p>It’s an open standard.</p>
</li>
</ol>
<p>The downsides of OpenID Connect?</p>
<ol>
<li>
<p>It’s not very popular. Most Internet authentication providers seem to have rolled their own systems based on OAuth2.</p>
</li>
<li>
<p>It’s kind of a pain in the ass to implement.</p>
</li>
<li>
<p>The documentation is long and somewhat unapproachable.</p>
</li>
</ol>
<p>This is a summary of the key information I wish someone had given me before I tried to make sense of OpenID Connect.</p>
<h3 id="endpoints">Endpoints</h3>
<p>An OpenID Connect authentication provider has a set of four key endpoints:</p>
<ol>
<li>
<p>An <em>authentication endpoint</em>. You direct the user’s browser to this via an HTTP 301 redirect in order to start the authentication process. The user is bounced back to your web application after logging in, with parameters added to that HTTP request. The parameters may be a <em>code</em>, an <em>ID token</em>, an <em>access token</em>, or some combination of the three.</p>
</li>
<li>
<p>A <em>token endpoint</em>. This is a REST API your application can use to obtain an id token or access token, given a code.</p>
</li>
<li>
<p>A <em>user info endpoint</em>. This is a REST API your application can use to obtain information about a user, given an access token. Typically it’s used to get information that doesn’t fit inside the ID token, such as the user’s avatar image. It also may not be supported, as it’s totally optional.</p>
</li>
<li>
<p>An <em>introspection endpoint</em>. This is a REST API you can pass an access token to. It will return information about the token, such as whether it’s valid, when it will expire, and so on.</p>
</li>
</ol>
<p>There are other optional endpoints, but those are the most important.</p>
<h3 id="key-data">Key data</h3>
<p>As mentioned in the above descriptions, OpenID Connect involves passing around three key pieces of information:</p>
<ul>
<li>
<p>An <code>id_token</code> is what you typically want — key information about the logged-in user’s ID and their name.</p>
</li>
<li>
<p>The <code>access_token</code> (or just <code>token</code> in some places) is a token you can use to connect to the token endpoint, userinfo endpoint or introspection endpoint. It therefore allows you to obtain an ID token, get more detailed information about the user, or find out when the granted authentication will expire.</p>
</li>
<li>
<p>A <code>code</code> is a one-time code you can use, accompanied by a secret ID and password you’ve pre-arranged with the authentication provider, to connect to the token endpoint and get a token.</p>
</li>
</ul>
<p>Given the above, there are several ways to do OpenID Connect.</p>
<h3 id="implicit-flow">Implicit flow</h3>
<p>With <em>Implicit Flow</em> you bounce the user to the authentication endpoint, and when they return you’re passed an ID token (and optionally, an access token so you can look up information that doesn’t fit in the ID token).</p>
<p>The advantage of implicit flow is that it’s really easy to implement. The disadvantage is that it’s not very secure.</p>
<p>For example, browser malware such as a malicious extension can sniff the tokens from the response. Because the ID token is a standard format, it can collect the user’s account information. The stolen access token can be used with the authentication provider’s APIs as well.</p>
<p>There are some ways to mitigate the risk somewhat, but a much better option is…</p>
<h3 id="authorization-flow">Authorization flow</h3>
<p>With <em>Authorization Flow</em> you bounce the user to the authentication endpoint; but when they return, all your app gets is an opaque code. You then need to make an authenticated REST call to the token endpoint, using an ID and password (secret) you obtained by registering with the authentication provider.</p>
<p>Because the tokens are not obtained via the browser, you can avoid being open to token stealing via browser malware. In addition, the application’s ID and secret are never given to the browser, and without those the browser malware can’t obtain tokens from the token endpoint.</p>
<p>The obvious initial downside is that your web application has to make a connection via TLS to the authentication provider.</p>
<h3 id="hybrid-flow">Hybrid flow</h3>
<p>Hybrid flow is when you make a call which requests a code as well as tokens. It has all the security disadvantages of implicit flow, and I can’t see why you’d want a code if you’re going to be given tokens anyway.</p>
<h3 id="authorization-flow-in-detail">Authorization flow in detail</h3>
<p>It’s pretty clear that authentication flow is the one to choose for security reasons. That’s probably why the authentication providers I need to use at work don’t support implicit flow. So, let me go through the authentication flow in detail, from the point of view of a web application. The <a href="http://openid.net/specs/openid-connect-core-1_0.html#CodeFlowAuth">OpenID Core document</a> has examples of HTTP requests and responses, so I’ll skip those and just try to briefly and clearly summarize the process.</p>
<p>The first step is to bounce the user via HTTP 301 to the authentication endpoint with an OAuth2 request. The request has a scope of <code>openid</code> and a response type of <code>code</code>, and a redirection URI pointing back to your web application.</p>
<p>The ID provider then asks the user to log in. This may involve pretty much anything you can imagine. In my case, there’s a company login and password, and then I get asked for a TOTP one-time code from my phone.</p>
<p>Once the user has logged in, the authentication provider bounces them back to the URL that was specified in the request. The <code>code</code> value is added to the query part of the URL.</p>
<p>Next, your web application takes the code value and uses it to make a call to the token endpoint. The connection is made via HTTPS (TLS), and authenticated using an ID and secret (password) you were given when you registered your application with the authentication provider.</p>
<p>(The ID and secret may be passed as JSON values, or using regular HTTP Basic authentication. The latter is preferred, according to the standards.)</p>
<p>If all goes well and you weren’t given a fake code, you get back a hunk of JSON containing the tokens you requested. The one you’re probably most interested in is the <code>id_token</code>, and this is where things get a bit tricky.</p>
<p>The <code>id_token</code> is encoded and signed. You have to decode it, check the signature using the public key of the ID provider, check the token hasn’t expired, and only then can you rely on the information in it.</p>
<p>The standard to follow for the decoding and signing is <a href="https://jwt.io/">JSON Web Tokens</a> (JWT). If you get this far and paste the base64-encoded <code>id_token</code> string that you got from the token endpoint into the jwt.io web site, you should see the info you want appear as the payload.</p>
<p>So your code needs to load a PEM public key, decode the JSON Web Token, and check its contents using the public key. If the signature is invalid, someone’s trying to impersonate the authentication provider, and you don’t trust the info in the ID token.</p>
<p>If the ID token validation succeeded and you also requested an access token, you might then use the access token to make a call to the profile endpoint, to get additional user information. (Home address, photo, you name it — it’s extensible, like LDAP.)</p>
<h3 id="libraries-you-can-use">Libraries you can use</h3>
<p>I’d love to say “Go here and use this library”, but at least for Go I haven’t found anything that will do the whole job.</p>
<p>There are many OAuth2 libraries, but none of them seem to support RSA signed JWT tokens.</p>
<p>There’s an <a href="https://github.com/emanoelxavier/openid2go">openid2go</a> project which looks as if it might work, but it relies on <a href="https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderConfigurationRequest">OpenID Connect Discovery</a> being supported. Unfortunately, the authentication providers I need to use don’t have discovery enabled. Furthermore, it doesn’t look to me as if openid2go supports authentication flow.</p>
<p>What about at least handling the JWT part? Well, I took a look at the three Go packages linked from the JWT web site.</p>
<p>SermoDigital’s <code>jose</code> package describes itself as “A comprehensive set of JWT, JWS and JWE libraries”. Unfortunately the documentation is lacking, and I can’t work out how to perform signature validation against a public key, assuming that’s actually implemented.</p>
<p>Next, <a href="https://github.com/dvsekhvalnov/jose2go">jose2go</a>. That one’s nice and simple. Given the <code>id_token</code> text you got from the token endpoint as a string in the variable <code>idtoken</code>, the process looks like this:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="nx">pubkeydata</span><span class="p">,</span><span class="w"> </span><span class="nx">err</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">ioutil</span><span class="p">.</span><span class="nf">ReadFile</span><span class="p">(</span><span class="s">&#34;pubkey.crt&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Check error and deal with it here</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">pubkey</span><span class="p">,</span><span class="w"> </span><span class="nx">err</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">Rsa</span><span class="p">.</span><span class="nf">ReadPublic</span><span class="p">(</span><span class="nx">pubkeydata</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Check error and deal with it here</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">hdr</span><span class="p">,</span><span class="w"> </span><span class="nx">payload</span><span class="p">,</span><span class="w"> </span><span class="nx">err</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">jose</span><span class="p">.</span><span class="nf">Decode</span><span class="p">(</span><span class="nx">idtoken</span><span class="p">,</span><span class="w"> </span><span class="nx">pubkey</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Check error and deal with it here</span><span class="w">
</span></span></span></code></pre></div><p>The ID token info you want is then in the <code>hdr</code> variable, and <code>payload</code> can be examined to make sure the expected signature algorithm was used — because you don’t want to accept unsigned tokens. I checked that a tiny change to the payload correctly caused a signature error at the Decode stage.</p>
<p>Finally, there’s <a href="https://github.com/dgrijalva/jwt-go">jwt-go</a>. This one works too, but the decoding and verifying process is slightly more involved because you need to supply a callback function to look up the appropriate key given the signing method. You get a <code>Claims</code> map with the values you want, and a <code>Valid</code> field indicating whether the validation succeeded. Again, a tiny mutation to the data was successfully detected.</p>
]]></content></entry><entry><title type="html">Reflection in Go and modifying struct values</title><link href="https://lpar.ATH0.com/posts/2016/04/reflection-in-go-and-modifying-struct-values/"/><id>https://lpar.ATH0.com/posts/2016/04/reflection-in-go-and-modifying-struct-values/</id><published>2016-04-20T18:26:32+00:00</published><updated>2016-04-20T18:26:32+00:00</updated><summary>An example of using the reflect package.</summary><content type="html"><![CDATA[<p>Recently I found myself wanting to write some code to load values into a Go object. The obvious approach is reflection. However, the Go <a href="https://golang.org/pkg/reflect/">documentation on reflection</a> is somewhat impenetrable, and the accompanying article on <a href="https://blog.golang.org/laws-of-reflection">The Laws of Reflection</a> only has a single skimpy example involving structs right at the end.</p>
<p>After some trial and error I came up with some robust code to demonstrate examining a struct and altering its fields. I decided to write it up in detail here.</p>
<h3 id="a-simple-example">A simple example</h3>
<p>Let’s start with the struct:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="kd">type</span><span class="w"> </span><span class="nx">Name</span><span class="w"> </span><span class="kt">string</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">type</span><span class="w"> </span><span class="nx">Person</span><span class="w"> </span><span class="kd">struct</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nx">FirstName</span><span class="w"> </span><span class="nx">Name</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nx">LastName</span><span class="w">  </span><span class="nx">Name</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nx">Age</span><span class="w">       </span><span class="kt">int</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span></code></pre></div><p>First of all we define a custom type, so that our fields aren’t all primitive types and our example is a bit more general. Then we assemble a simple struct.</p>
<p>Next, we instantiate an example struct of that type, and pass it to a function.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="nx">t</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">Person</span><span class="p">{</span><span class="s">&#34;John&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;Smith&#34;</span><span class="p">,</span><span class="w"> </span><span class="mi">23</span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nf">reflectOn</span><span class="p">(</span><span class="nx">t</span><span class="p">)</span><span class="w">
</span></span></span></code></pre></div><p>The signature for the function will be as follows:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="kd">func</span><span class="w"> </span><span class="nf">reflectOn</span><span class="p">(</span><span class="nx">s</span><span class="w"> </span><span class="kd">interface</span><span class="p">{})</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="c1">// Code here</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span></code></pre></div><p>Why the function call for a simple example?</p>
<p>Well, in real code you aren’t going to be performing reflection in the same function where you create an object. By passing an <code>interface{}</code> argument, we manage to completely bypass all type safety, meaning our example will be forced to rely on reflection. In real code, of course, you’d ideally narrow the scope a bit with a more specific interface.</p>
<p>In addition, by putting the reflection code in a function we can call it twice:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="nf">reflectOn</span><span class="p">(</span><span class="nx">t</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nf">reflectOn</span><span class="p">(</span><span class="o">&amp;</span><span class="nx">t</span><span class="p">)</span><span class="w">
</span></span></span></code></pre></div><p>Now we can make sure our code deals with structs passed by reference as well as by value, and we can demonstrate the important difference that makes, concerning whether you can change the fields of the struct.</p>
<h3 id="so-what-is-a-function-argument-really">So, what is a function argument really?</h3>
<p>Recall that unlike (say) Java, Go is all about <em>interfaces</em>, not classes. A given object (struct) can implement any number of interfaces, just by providing the right methods. Object oriented programming is done via composition, rather than a class hierarchy.</p>
<p>So when you define a function in Go which operates on objects, you specify the interface which the objects must implement in order to be acceptable to the function. Our function takes an argument of type <code>interface{}</code>. That’s the empty interface, one with no methods specified, so <a href="https://golang.org/ref/spec#Interface_types">as per the spec</a> absolutely anything implements it — even a primitive type such as an <code>int</code>.</p>
<p>So our function accepts objects with any interface type. What it receives is an <em>interface value</em> in an <em>interface variable</em>.</p>
<p>If you’ve <a href="http://research.swtch.com/interfaces">read about the implementation of the Go type system</a> or at least tried to digest <a href="http://blog.golang.org/laws-of-reflection">The Laws of Reflection</a>, you’ll know that an interface value in Go is a tuple consisting of a type descriptor (“this is a string”) and the type-dependent data representing the value.</p>
<p>So, the first step for our reflection function is to extract those two things:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="nx">ptyp</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">reflect</span><span class="p">.</span><span class="nf">TypeOf</span><span class="p">(</span><span class="nx">s</span><span class="p">)</span><span class="w"> </span><span class="c1">// a reflect.Type</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">pval</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">reflect</span><span class="p">.</span><span class="nf">ValueOf</span><span class="p">(</span><span class="nx">s</span><span class="p">)</span><span class="w"> </span><span class="c1">// a reflect.Value</span><span class="w">
</span></span></span></code></pre></div><p>Next we want to look at the type of thing we were passed, to make sure it’s what we expect. However, the <code>Type</code> we just extracted is the <em>specific</em> type of the value — a <code>Person</code> in this case. What we really want to know is whether it’s a struct, before we try to go looking at its fields. So we look at the <code>Kind</code> of the type, which we obtain from the <code>Type</code> by calling <code>Kind()</code>.</p>
<p>You might want to try printing out the value of <code>ptyp.Kind()</code>. If you try it with the two function calls:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="nf">reflectOn</span><span class="p">(</span><span class="nx">t</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nf">reflectOn</span><span class="p">(</span><span class="o">&amp;</span><span class="nx">t</span><span class="p">)</span><span class="w">
</span></span></span></code></pre></div><p>…you will quickly discover that in the second case, the interface type’s Kind is <code>Ptr</code>. So although in Go you can often ignore the distinction between a struct and a pointer to a struct, when it comes to reflection the difference is exposed.</p>
<p>So our function needs to know how to deal with pointers and get at the thing pointed to. The reflect package <a href="https://golang.org/pkg/reflect/#Value.Elem">provides a method</a> <code>Elem()</code> which operates on a <code>Value</code> and dereferences to get the <code>Value</code> pointed at. A similar method does the same thing for the <code>Type</code>. So:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="kd">var</span><span class="w"> </span><span class="nx">typ</span><span class="w"> </span><span class="nx">reflect</span><span class="p">.</span><span class="nx">Type</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">var</span><span class="w"> </span><span class="nx">val</span><span class="w"> </span><span class="nx">reflect</span><span class="p">.</span><span class="nx">Value</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="k">if</span><span class="w"> </span><span class="nx">ptyp</span><span class="p">.</span><span class="nf">Kind</span><span class="p">()</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="nx">reflect</span><span class="p">.</span><span class="nx">Ptr</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nx">fmt</span><span class="p">.</span><span class="nf">Printf</span><span class="p">(</span><span class="s">&#34;Argument is a pointer, dereferencing.\n&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nx">typ</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="nx">ptyp</span><span class="p">.</span><span class="nf">Elem</span><span class="p">()</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nx">val</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="nx">pval</span><span class="p">.</span><span class="nf">Elem</span><span class="p">()</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nx">fmt</span><span class="p">.</span><span class="nf">Printf</span><span class="p">(</span><span class="s">&#34;Argument is %s.%s, a %s.\n&#34;</span><span class="p">,</span><span class="w"> </span><span class="nx">ptyp</span><span class="p">.</span><span class="nf">PkgPath</span><span class="p">(),</span><span class="w"> </span><span class="nx">ptyp</span><span class="p">.</span><span class="nf">Name</span><span class="p">(),</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nx">ptyp</span><span class="p">.</span><span class="nf">Kind</span><span class="p">())</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nx">typ</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="nx">ptyp</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nx">val</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="nx">pval</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span></code></pre></div><p>At this point, our two new variables <code>typ</code> and <code>val</code> contain the <code>Type</code> and <code>Value</code> of the actual struct, whether we were given it as an actual value or via a pointer. Now we can make sure that it really is a struct:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="k">if</span><span class="w"> </span><span class="nx">typ</span><span class="p">.</span><span class="nf">Kind</span><span class="p">()</span><span class="w"> </span><span class="o">!=</span><span class="w"> </span><span class="nx">reflect</span><span class="p">.</span><span class="nx">Struct</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nx">fmt</span><span class="p">.</span><span class="nf">Printf</span><span class="p">(</span><span class="s">&#34;Not a struct.\n&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="k">return</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span></code></pre></div><p>If this seems like a lot of work, remember that in real code you would know whether you were going to call your function with a struct or a pointer to a struct and would just call <code>Elem()</code> or not (as appropriate) in the first line or two of code.</p>
<p>Next, let’s examine the key difference between passing a struct by value and passing it by reference:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="k">if</span><span class="w"> </span><span class="nx">val</span><span class="p">.</span><span class="nf">CanSet</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nx">fmt</span><span class="p">.</span><span class="nf">Printf</span><span class="p">(</span><span class="s">&#34;We can set values.\n&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nx">fmt</span><span class="p">.</span><span class="nf">Printf</span><span class="p">(</span><span class="s">&#34;We cannot set values.\n&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span></code></pre></div><p>If you try the code so far, you’ll discover that if your function call is <code>reflectOn(t)</code> then <code>CanSet()</code> will report that you can’t set values. If it’s <code>reflectOn(&amp;t)</code>, you can set values. If you learned programming by learning Java, this probably makes no sense to you at all, but it goes back to the invention of function calls in programming languages. A brief digression is in order. If you’re a C or C++ programmer, you can skip to the next section.</p>
<h3 id="what-is-the-stack">What is the stack?</h3>
<p>Back in the 1950s, the programming language Algol 60 was being designed. One of its design goals was to support recursion. This meant allowing an unrestricted number of function calls — functions calling functions calling functions. To do this, Dijkstra invented the <em>stack</em>. (See: <a href="http://www.sigcis.org/files/A%20brief%20history.pdf">A Brief History Of The Stack</a>.)</p>
<p>Each time a function was called:</p>
<ol>
<li>The arguments would be pushed onto the stack, in specified order.</li>
<li>The code for the function would be called.</li>
<li>The function would pop the arguments off of the stack.</li>
<li>The function would perform its computations, and put its result on the stack.</li>
<li>The function would end, returning to the calling code, which would pop the result from the stack.</li>
</ol>
<p>In the 1960s, memory was scarce and computers were slow. A 1964 IBM 360 mainframe started out with 8KiB of memory and executed 34,500 instructions per second — so not even equivalent to a 1MHz clock. If you wanted to pass a string to a function, the idea of copying the entire string onto the stack and off again would have crippled performance. So instead, any argument whose data was larger than a few bytes would be replaced with a pointer to the argument.</p>
<p>The same methods were used for function calls in CPL, which was modeled on Algol. CPL gave way to the BCPL programming language, and its successor C.</p>
<p>Nowadays compilers use various tricks to speed up function calls. For example, if all the arguments will fit into processor registers, they get passed that way instead of via the stack. However, conceptually Go still uses the same stack-based argument passing as its programming language ancestors. One difference, however, is that Go will actually shove an entire string or other large data object onto the stack if you ask it to — conceptually, at least.</p>
<h3 id="by-value-or-by-reference">By value or by reference</h3>
<p>When we call our function via <code>reflectOn(t)</code>, Go pushes an entire copy of the struct <code>t</code> onto the stack. The function retrieves it as <code>s</code>. The function doesn’t have any way to know where the copy came from. Whatever it does with the copy, the original will remain unchanged.</p>
<p>When we call our function via <code>reflectOn(&amp;t)</code>, Go pushes a <em>pointer</em> to the struct onto the stack. The function retrieves the pointer. At that moment, it can access the original structure — so any changes it makes will be visible when the function returns and the original structure is examined.</p>
<p>So although our code makes sure that <code>typ</code> and <code>val</code> are the <code>Type</code> and <code>Value</code> of the struct, in one case they are the type and value of a <em>copy</em> of the struct, and any changes we try to make will be ignored — so Go warns us of this by returning <code>false</code> from <code>val.CanSet()</code>. Notice that whether the value is settable is a property of the value and how we obtained it, <em>not</em> a property of the type of the structure; the struct’s type is identical in both cases.</p>
<p>We’ll get back to this in a few more lines of code. First, let’s see how we look at the fields of the struct. Logically, the fields of the struct and their types are defined in the type definition of the struct, so we would expect to use the <code>typ</code> variable to access the individual fields. And so we do:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="k">for</span><span class="w"> </span><span class="nx">i</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="mi">0</span><span class="p">;</span><span class="w"> </span><span class="nx">i</span><span class="w"> </span><span class="p">&lt;</span><span class="w"> </span><span class="nx">typ</span><span class="p">.</span><span class="nf">NumField</span><span class="p">();</span><span class="w"> </span><span class="nx">i</span><span class="o">++</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nx">sfld</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">typ</span><span class="p">.</span><span class="nf">Field</span><span class="p">(</span><span class="nx">i</span><span class="p">)</span><span class="w">
</span></span></span></code></pre></div><p>At this point we have a value representing a field. If you’re used to how Java reflection works you might expect it to be some sort of field class of a particular type that you can use to access the data, but in Go there’s another step to go through.</p>
<p>In Go, the <code>.Field(int)</code> method, when called on a struct, always returns a special <code>StructField</code> object. To get the actual type of the field, we need to call <code>Type()</code> on the <code>StructField</code>. Just as we examined the underlying type or ‘kind’ of our function argument, so we can do the same for the field:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="nx">tfld</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">sfld</span><span class="p">.</span><span class="nx">Type</span><span class="w"> </span><span class="c1">// The Type of the StructField of the struct</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">kind</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">tfld</span><span class="p">.</span><span class="nf">Kind</span><span class="p">()</span><span class="w"> </span><span class="c1">// The Kind of the Type of the StructField</span><span class="w">
</span></span></span></code></pre></div><p>OK, now how about the value? Java gives you a single Field object which you can interrogate for both type and value information. Go has two separate sets of objects to handle that. So just as we called <code>.Field()</code> on the struct’s Type to get at the field’s type (via an intermediate <code>StructField</code>), so we need to call <code>.Field()</code> on the struct’s <code>Value</code> to get the field’s value. This time, however, there’s no intermediate <code>StructValue</code>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="nx">vfld</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">val</span><span class="p">.</span><span class="nf">Field</span><span class="p">(</span><span class="nx">i</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">fmt</span><span class="p">.</span><span class="nf">Printf</span><span class="p">(</span><span class="s">&#34;struct field %d: name %s type %s kind %s value %v\n&#34;</span><span class="p">,</span><span class="w"> 
</span></span></span><span class="line"><span class="cl"><span class="w">	   </span><span class="nx">i</span><span class="p">,</span><span class="w"> </span><span class="nx">sfld</span><span class="p">.</span><span class="nx">Name</span><span class="p">,</span><span class="w"> </span><span class="nx">tfld</span><span class="p">,</span><span class="w"> </span><span class="nx">kind</span><span class="p">,</span><span class="w"> </span><span class="nx">vfld</span><span class="p">)</span><span class="w">
</span></span></span></code></pre></div><p>Running the code at this stage will produce output like this:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-txt" data-lang="txt"><span class="line"><span class="cl">struct field 0: name FirstName type main.Name kind string value John
</span></span><span class="line"><span class="cl">struct field 1: name LastName type main.Name kind string value Smith
</span></span><span class="line"><span class="cl">struct field 2: name Age type int kind int value 23
</span></span></code></pre></div><p>So, we’ve decoded our struct completely, down to field level. We’ve extracted both the specific types (including custom types we defined), and the underlying primitive types. We’ve even read out the data.</p>
<h3 id="writing-fields">Writing fields</h3>
<p>Now that we can read from the struct, let’s work out how to change it.</p>
<p>You might wonder whether setting a value is an operation you perform on the type, or an operation you perform on the value. In a dynamic language like Ruby, you’d expect to call a type-dependent method to set the value. But Go is statically typed, so you can’t change the type of a field at runtime — only its value. So to change a value you use a <code>Set</code> method on the <em>value</em> of the individual field, as returned by the <code>Field()</code> method of the struct’s <code>Value</code>. And if you try to tell the <code>Value</code> to take on a value of a different incompatible type, Go will panic.</p>
<p>Also, you need to use the <code>Set</code> methods on the <code>Value</code> of the individual field you want to change — <em>not</em> the interim <code>StructField</code>. So let’s try it:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="k">if</span><span class="w"> </span><span class="nx">kind</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="nx">reflect</span><span class="p">.</span><span class="nx">String</span><span class="w"> </span><span class="o">&amp;&amp;</span><span class="w"> </span><span class="nx">vfld</span><span class="p">.</span><span class="nf">CanSet</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nx">fmt</span><span class="p">.</span><span class="nf">Printf</span><span class="p">(</span><span class="s">&#34;Overwriting field %s\n&#34;</span><span class="p">,</span><span class="w"> </span><span class="nx">sfld</span><span class="p">.</span><span class="nx">Name</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nx">vfld</span><span class="p">.</span><span class="nf">SetString</span><span class="p">(</span><span class="s">&#34;Anonymous&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span></code></pre></div><p>Notice that the field’s <code>Value</code> has its own <code>CanSet()</code> method, just like the overall struct’s <code>Value</code> does.</p>
<p>So now I can restate the part that confused the heck out of me: You can’t modify the value of a struct in Go using a <code>Type</code> or <code>StructField</code>. To perform a reflection operation in Go you need to go through two separate interrogation processes: first you start with the struct and retrieve all the type information you want and check it, then you start again at the struct and work down the value chain to the field value and change it.</p>
<p>You can interleave the operations, as I’ve done in this example code, but fundamentally you’re dealing with two different trees of information.</p>
<p>You can get <a href="https://gist.github.com/lpar/9e0431c1bc957a78cf3df90c8bf32617">the complete code on GitHub</a> with added comments. If you run it, you’ll see quite clearly the behavior difference between calling with a struct, versus calling with a pointer to a struct:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-txt" data-lang="txt"><span class="line"><span class="cl">First, passing the actual structure:
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">Argument is main.Person, a struct.
</span></span><span class="line"><span class="cl">We cannot set values.
</span></span><span class="line"><span class="cl">struct field 0: name FirstName type main.Name kind string value John
</span></span><span class="line"><span class="cl">struct field 1: name LastName type main.Name kind string value Smith
</span></span><span class="line"><span class="cl">struct field 2: name Age type int kind int value 23
</span></span><span class="line"><span class="cl">After reflection:
</span></span><span class="line"><span class="cl">John Smith, 23 years old
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">Now, passing a pointer to the structure:
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">Argument is a pointer, dereferencing.
</span></span><span class="line"><span class="cl">We can set values.
</span></span><span class="line"><span class="cl">struct field 0: name FirstName type main.Name kind string value John
</span></span><span class="line"><span class="cl">Overwriting field FirstName
</span></span><span class="line"><span class="cl">struct field 1: name LastName type main.Name kind string value Smith
</span></span><span class="line"><span class="cl">Overwriting field LastName
</span></span><span class="line"><span class="cl">struct field 2: name Age type int kind int value 23
</span></span><span class="line"><span class="cl">After reflection:
</span></span><span class="line"><span class="cl">Anonymous Anonymous, 23 years old
</span></span></code></pre></div><p>Hopefully that covers everything you need to know about reflecting on structs.</p>
]]></content></entry><entry><title type="html">Search is hard</title><link href="https://lpar.ATH0.com/posts/2016/01/search-is-hard/"/><id>https://lpar.ATH0.com/posts/2016/01/search-is-hard/</id><published>2016-01-28T19:55:37+00:00</published><updated>2016-01-28T19:55:37+00:00</updated><summary>It’s hard to make search behave the way people expect, and still be useful.</summary><content type="html"><![CDATA[<p>Getting search right in applications has many interesting subtleties.</p>
<p>One problem is that <a href="https://www.nngroup.com/articles/search-and-you-may-find/">most people don’t understand boolean algebra</a>, to the point that they don’t understand the difference between “and” and “or” in a set of search clauses. Unless your audience is highly technical, giving them a choice between “and” and “or” will only confuse them.</p>
<p>If you look at sites which successfully allow complex queries, they do it by using the type of UI component to express whether the choice is “and” or “or”. For example, NewEgg:</p>
<img src="/img/2016/newegg.png" alt="newegg" width="218" height="633" />
<p>Clauses are implicitly “and”, except for sets of checkboxes. So the final search here is “Newegg Premier” AND (price $200-300 OR price $300-400).</p>
<p>This “implicit boolean operators” search pattern has become almost ubiquitous, though you do find the occasional site running older search software that still has drop-downs to choose “and” or “or” for each clause.</p>
<p>Another subtlety of search is the underlying conceptual model of the operation. To a programmer, search is straightforward: you start with an empty result set, you assemble a list of criteria, you go to the database and pick out items that match the criteria, and you add them to the result set.</p>
<p>That’s not the user’s conceptual model, though. To the user, you start with the set of every possible item, and you then eliminate items which <em>don’t</em> match the criteria. The conceptual model mirrors how you’d perform a search manually.</p>
<p>This becomes relevant when the user is given an advanced search interface, selects no criteria at all, and asks the system to search. Programmatically, the set of items which don’t match any criteria is the empty set; but what the user actually expects based on their mental model is all items.</p>
<p>Google catch this scenario by disabling the search buttons on the front page until the user types some text. They also ignore empty search string submissions using the Enter key. Interestingly, they leave the Search button visibly enabled, even though it doesn’t work. It would certainly be possible to have the button visibly disabled until the search text field contained a non-empty string; presumably they’ve done A/B testing that demonstrated that buttons initially being disabled led to user confusion.</p>
<p>I initially considered catching the “no criteria” case and redirecting the user to the browse UI instead. On reflection, though, I realized that selecting no criteria and hitting “Search” was a legitimate thing to do. The use case is “find out what the search results page will look like, <em>then</em> decide how many criteria I need to specify”.</p>
<p>Not a hard problem from a technical point of view, but I thought it showed an interesting subtlety involved in getting search right.</p>
]]></content></entry><entry><title type="html">SSDs, or everything old is new again</title><link href="https://lpar.ATH0.com/posts/2015/12/ssds-or-everything-old-is-new-again/"/><id>https://lpar.ATH0.com/posts/2015/12/ssds-or-everything-old-is-new-again/</id><published>2015-12-21T16:57:45+00:00</published><updated>2015-12-21T16:57:45+00:00</updated><summary>They’re not necessarily a better choice than spinning rust.</summary><content type="html"><![CDATA[<p>Some <a href="http://www.zdnet.com/article/what-we-learned-about-ssds-in-2015/">information about SSDs</a> that a lot of people were apparently unaware of:</p>
<ol>
<li>High temperatures can make SSDs run slower.</li>
<li>The log-structured I/O SSDs use is really poor for databases, which add their own layer of log-structured I/O.</li>
<li>If you put multiple VMs on a single SSD, you can get unpredictable <em>read</em> latencies.</li>
<li>The more you write to an SSD, the quicker it will fail.</li>
</ol>
<p>Item 1 was actually news to me. Item 2 is something that ought to occur to you if you know how databases handle ACID updates and how SSDs handle writes, but obviously there are an awful lot of people who use both technologies with no idea of the underlying details.</p>
<p>Item 3 is an interesting one. The fundamental problem is related to item 2: the operating system basically has no way to know how the SSD is operating internally, and can’t make smart decisions to optimize performance to ensure low latency operations, even if they’re just reads.</p>
<p>Something similar happened with hard disks a few decades ago. In the 60s, 70s and 80s, the operating system generally handled the translation of a flat logical block address into individual values for <a href="https://en.wikipedia.org/wiki/Cylinder-head-sector">cylinder, head and sector</a> (CHS). In addition, the OS generally knew the cluster size of the underlying hardware — that is, the minimum number of sectors the hardware would read in a single operation.</p>
<p>So a request to read sector 48321 of the disk might translate into a request to read cylinder 3, head 2, sector 1 — and might actually result in sectors 0 thru 3 being read, and sector 1 passed back.</p>
<p>Because the OS knew about the disk geometry, it could arrange files and data structures in order to speed up access. Defragmenting, which most Windows users are somewhat familiar with, was only part of this.</p>
<p>Suppose you’re reading a large database file which is unfragmented. You can slurp up the first (say) 63 sectors by lowering the head to the disk and reading all the way around a single circular track. Now you need the next sector, so you instruct the head to move in to the next track. But while the head moves sideways, the disk is still spinning, so by the time the head is in place to read the next track it might be over (say) sector 11. So if you map sectors in the naïve way, you’ll have to wait for almost an entire revolution of the disk before sector 0 is under the head again. So ideally, you’ll skew adjacent tracks by enough sectors to give the head time to move to the next track.</p>
<p>Oh, but often hard disks would spin so fast that it wouldn’t be possible to shunt a sector of data across the bus to the memory quickly enough before the next sector on the track turned up under the head. So when I said you could slurp 63 sectors in a single operation — well, maybe you could, but not necessarily in that order. Often sectors would be interleaved on the track, 0 32 1 33 2 34 3 35 and so on. You’d read sector 0, wait for it to clear the bus, read sector 1, wait for it to clear the bus, and so on, reading the entire track in a single operation — but needing two disk revolutions.</p>
<p>There are other complexities. Maybe the drive has 4 heads. In that case, you might want to put the first track of data on head 0, the second on head 1, and so on, and then arrange it so that by the time you’ve read a track from head 3, head 0 will have moved across to the next track, and that track will be skewed enough that the next sector will be coming up. To do this, you need to know how long it takes to switch heads, because that takes time too.</p>
<p>Basically, every change of raw CHS address had a particular set of latency characteristics, whether you were switching head, switching sector, or switching cylinder. They weren’t simple fixed latencies, either. Cluster sizes could be different, and even sector sizes could be different. Optimizing it all was a dark art.</p>
<p>An aside: In the early days of MS-DOS hard disk support, there was a <a href="http://www.informit.com/articles/article.aspx?p=131238&amp;seqNum=13">fixed limit on the number of sectors DOS could handle</a>. But, people wanted bigger hard disks! Some manufacturers came up with a brilliant idea: They’d make their sectors twice as big, 1024 bytes rather than 512. They’d ship a special patched version of MS-DOS that knew about big sectors, and they’d be able to sell hard drives twice as big as their competitors could! Everyone would be happy, right up until Microsoft released a new version of MS-DOS, and the customer installed normal Microsoft MS-DOS on his computer, and MS-DOS treated every sector on his hard disk as half its actual size and scrambled all his files. That’s how I learned the intricacies of this stuff — working in data recovery…</p>
<p>Eventually people observed that tracks at the outside of a disk could easily squeeze in more sectors than the smaller tracks in the middle. Drives started to be built which had a variable number of sectors per track. This was a bit of a problem for CHS-based addressing, and often the drive would pretend to have a fixed number of sectors per track for simplicity.</p>
<p>Then in the mid 80s, <a href="https://en.wikipedia.org/wiki/SCSI">SCSI</a> started to become popular. With a SCSI hard disk, your computer simply asked for logical sector 48321, sending a request down the SCSI bus. The hard drive grabbed the data and sent it back. All of the messy details of cylinders, heads and sectors were hidden from the operating system. That meant the OS couldn’t use that information to optimize its requests. However, it also meant that you didn’t need to spend hours optimizing your hard disk’s addressing algorithm in order to get good performance. SCSI controllers started to include big chunks of RAM cache, and to do things like reading ahead a few sectors and caching the results on the off chance that you might ask for one of those sectors next. In addition, SCSI had a killer advantage: it didn’t require CPU time. But your disk performance was greatly dependent on the quality of the disk’s SCSI interface and its firmware. My first SCSI hard drive was generally great, but it was cheap (I was a student) and its latency was all over the place.</p>
<p>So that’s the point we’re at with SSDs. Some of them have a RAM cache, some don’t. Some have really good firmware, others <a href="https://techreport.com/news/28473/some-samsung-ssds-may-suffer-from-a-buggy-trim-implementation">not so much</a>. If you want predictable performance and reliability, you need to be very careful who you buy SSDs from, and bear their long term characteristics in mind. For example, don’t skimp on RAM for OS-level caches, don’t swap to SSD, and make sure the machine is properly cooled.</p>
]]></content></entry><entry><title type="html">&amp;#34;Stand back! I know regular expressions!&amp;#34;</title><link href="https://lpar.ATH0.com/posts/2015/12/stand-back-i-know-regular-expressions/"/><id>https://lpar.ATH0.com/posts/2015/12/stand-back-i-know-regular-expressions/</id><published>2015-12-06T20:36:17+00:00</published><updated>2015-12-06T20:36:17+00:00</updated><summary>Why you shouldn’t always grab a regexp library to solve a problem.</summary><content type="html"><![CDATA[<p>For the last few days I’ve been taking part in the <a href="http://adventofcode.com/">Advent of Code</a>. Each day there are a couple of small programming problems to solve in your choice of language. There’s a Reddit community where people discuss the problems and their solutions.</p>
<p>After solving the Day 5 problems pretty quickly, I went to the discussions and was a bit surprised to find that everyone was talking about regular expressions. I hadn’t used them. It had seemed pretty obvious to me that the state machines and string searches required could be handled explicitly, could do the job in linear time, and would likely be faster than a regexp engine.</p>
<p>But… what if I was wrong? What if I’d written the extra code for nothing?</p>
<p>I decided to implement a second pair of solutions using precompiled regexps and the PCRE library, make sure they passed the same tests, and benchmark all four. I had to install a PCRE library, because Go’s built-in regular expression library doesn’t support all the Perl-like features needed to solve the problem concisely.</p>
<p>Here’s what I got when I benchmarked:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-txt" data-lang="txt"><span class="line"><span class="cl">BenchmarkNice1-4            2000        738282 ns/op
</span></span><span class="line"><span class="cl">BenchmarkNice1RegExp-4      1000       2269376 ns/op
</span></span><span class="line"><span class="cl">BenchmarkNice2-4            2000        901082 ns/op
</span></span><span class="line"><span class="cl">BenchmarkNice2RegExp-4       300       4140755 ns/op
</span></span></code></pre></div><p>The second number in each row is the number of runs Go decided it needed to average to get a good measure of the speed.</p>
<p>My intuition was right, using a compiled language and a straightforward non-regexp state machine implementation beat a PCRE-based one, at least for this fairly simple problem.</p>
<h2 id="but-what-about-unicode">But what about Unicode?</h2>
<p>Pondering performance some more, I realized that Unicode processing was likely impacting the performance of my code, what with Go handling strings as UTF-8 by default.</p>
<p>I decided that for fairness, I should make sure both the regexp and non-regexp implementations dealt properly with Unicode.</p>
<p>The problem specifically says that the only characters deemed to be vowels are <code>aeiou</code>. However, part 2 talks about <em>letters</em>, which would logically include things like <code>é</code> and <code>ü</code>.</p>
<p>Also, nowhere does it state that the algorithm is allowed to assume that the input strings are only letters, so I decided to make sure my code could process things like <code>a☃️ee⛄️ioo🌨ee🎅u</code>. This is complicated in some programming languages, because <a href="http://www.fileformat.info/info/unicode/char/1f385/index.htm">Santa</a> does not reside in the the [Basic Multilingual Plane](<a href="https://en.wikipedia.org/wiki/Plane">https://en.wikipedia.org/wiki/Plane</a>_(Unicode)#Basic_Multilingual_Plane). Not a big deal in Go, though.</p>
<p>Once I’d done that and made sure all the tests still ran, I reran the benchmarks:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-txt" data-lang="txt"><span class="line"><span class="cl">BenchmarkNice1-4            2000        674877 ns/op
</span></span><span class="line"><span class="cl">BenchmarkNice1RegExp-4       500       2412329 ns/op
</span></span><span class="line"><span class="cl">BenchmarkNice2-4            1000       2160843 ns/op
</span></span><span class="line"><span class="cl">BenchmarkNice2RegExp-4       300       4806563 ns/op
</span></span></code></pre></div><p>I’d managed to speed up my part 1 code while reworking it, but part 2 was slower. Turning on UTF-8 processing for PCRE and fixing the regexps made all of them a bit slower too. Overall, the non-regexp solutions still win.</p>
<p>The moral of the story: Yes, regular expressions are really useful, but they’re not necessarily the first thing you should reach for.</p>
<p>Of course, the usual caveats about premature optimization and the benefits of writing as little code as possible still apply.</p>
]]></content></entry><entry><title type="html">Go: Preliminary verdict</title><link href="https://lpar.ATH0.com/posts/2015/12/go-preliminary-verdict/"/><id>https://lpar.ATH0.com/posts/2015/12/go-preliminary-verdict/</id><published>2015-12-05T00:02:47+00:00</published><updated>2015-12-05T00:02:47+00:00</updated><summary>Thoughts after writing real code.</summary><content type="html"><![CDATA[<p>So, how do I feel about Go, now that I know it better?</p>
<h3 id="the-good">The good</h3>
<p>On the whole, I like it. Some high points:</p>
<ul>
<li>
<p>It’s reasonably terse, and there’s not much syntax to remember. Like Ruby, you can do a lot in not much code, and unlike (say) Java there isn’t really a big need for an IDE.</p>
</li>
<li>
<p>It inherits from Modula-2 <a href="https://talks.golang.org/2012/splash.article">a focus on compile-time efficiency</a>. No header files, a compact grammar, and rigid dependency declaration make for rapid compilation times.</p>
</li>
<li>
<p>It’s <a href="https://talks.golang.org/2012/splash.article">memory-efficient</a>. <a href="https://benchmarksgame.alioth.debian.org/u64q/go.html">Far more so than Java</a>.</p>
</li>
<li>
<p>Performance is good, often <a href="https://benchmarksgame.alioth.debian.org/u64q/compare.php?lang=go&amp;lang2=gpp">comparable to C++</a>.</p>
</li>
<li>
<p>Cross-compilation is easy. On my Mac I can <code>GOOS=linux GOARCH=386 go build hello.go</code> and get a binary that I can just rsync to my Linux box and run there. And…</p>
</li>
<li>
<p>Deployment is easy: The compiler spits out a single binary, and that’s all you need. You don’t need any sort of Go runtime installed on the destination system.</p>
</li>
<li>
<p>Like Ruby, you don’t have to rigidly specify what interfaces your objects support; it’s all duck typed.</p>
</li>
</ul>
<p>The speed of the tools and ease of deployment make programming in Go a curiously retro experience. It feels a bit like I’m back sitting in front of a copy of Turbo Pascal.</p>
<h3 id="the-bad">The bad</h3>
<p>What don’t I like? Oh, a few things:</p>
<ul>
<li>
<p>There are two different syntaxes for variable declaration, and you have to know and use both of them. (Well, it might be possible to do without <code>:=</code>, but not without painful workarounds making the code ugly.)</p>
</li>
<li>
<p>No tail-call elimination (yet). Sometimes recursion is the best way to do something.</p>
</li>
<li>
<p>The standard logging library is poor. No levels, no level guards, and a gratuitously non-standard date/time format.</p>
</li>
<li>
<p>Variables aren’t immutable by default.</p>
</li>
<li>
<p>Pointers are visible.</p>
</li>
</ul>
<p>I don’t view any of these as deal-killers, though. In fact, I’d like to go through a few things other people often cite as criticisms of Go, which I think are features rather than bugs…</p>
<h3 id="no-exceptions">No exceptions</h3>
<p>Speaking as someone who writes Java for a living most weeks, I view Java’s approach to error-handling to be a well-intentioned experiment that has failed. Forcing bad programmers to pay attention to exceptions doesn’t work. In practice, they write code which catches and eats them, or fails to process them properly. (Try finding a single <em>correct</em> piece of example code to perform a JDBC query, dealing cleanly with all possible exceptions.)</p>
<h3 id="garbage-collection">Garbage collection</h3>
<p>Young programmers think they can handle memory manually, and do it right. About 40 years of industry security incidents suggests otherwise. A modern memory manager is <em>almost</em> as fast as well-written hand-optimized code. For almost all of the programmers almost all of the time, doing memory management manually makes as much sense as writing in assembler.</p>
<h3 id="no-generics-yet">No generics yet</h3>
<p>Sure, generics are useful in Java. They are also a major pain in Java. I’d rather wait and have them done properly in Go, than have a hurried ugly solution.</p>
<h3 id="in-conclusion">In conclusion</h3>
<p>As long as you’re not a language snob, I recommend taking a look at Go. It doesn’t do everything right, but it does a lot of things right.</p>
<p>There’s <a href="https://www.youtube.com/watch?v=rFejpH_tAHM">a video of a talk by Rob Pike</a> where he talks about Go’s focus on simplicity above almost everything else.</p>
<p>I like simple languages, and I think that’s why Go appeals to me. I like Scheme, and I like Ruby. (Ruby’s grammar is complicated, but <em>to the human</em> it’s very simple and consistent.) The simplicity is why I ditched Perl for Ruby. It’s why I prefer Objective-C to C++.</p>
<p>Java is also mostly pretty simple, it’s just annoyingly verbose — but once generics are involved, it can become really complicated; and now that it’s getting type inference, lambdas and type annotations it’s starting to look rather larger than I prefer. To see the direction it’s going, <a href="http://es6-features.org/">look at JavaScript</a>. Generator functions, for example, seem to me to be a wonderful example of adding complexity to the language without actually solving the concurrency problems they’re supposed to help with.</p>
<p>Overall, I think Go is one of the best new languages. The only other ones that interest me right now are Rust and Swift. As far as Rust goes, I’m not completely convinced that squeezing that last bit of performance out of the system is worth the hassle of manual memory management. With regard to Swift, it seems similar in many ways to Go, but with the benefit of excellent Mac OS X support.</p>
]]></content></entry><entry><title type="html">&amp;#34;The Go Programming Language&amp;#34;</title><link href="https://lpar.ATH0.com/posts/2015/12/the-go-programming-language/"/><id>https://lpar.ATH0.com/posts/2015/12/the-go-programming-language/</id><published>2015-12-04T01:34:17+00:00</published><updated>2015-12-04T01:34:17+00:00</updated><summary>A book review.</summary><content type="html"><![CDATA[<p><cite><a href="http://www.amazon.com/gp/product/0134190440/ref=as_li_tl?ie=UTF8&camp=1789&creative=390957&creativeASIN=0134190440&linkCode=as2&tag=a0ef8-20&linkId=5GGTFUBBKEFT5ROW">“The Go Programming Language” by Alan A.A. Donovan &amp; Brian W. Kernighan</a></cite></p>
<p><em>Addison-Wesley</em></p>
<p>Like many other programmers, I learned to write C by reading “The C Programming Language” by Kernighan and Ritchie, the book known to hackers everywhere as “K&amp;R”. I confess that I was initially drawn to “The Go Programming Language” out of sheer Kernighan brand awareness. Would it be the K&amp;R of the Go world? I certainly hoped so, as I have strong preferences when it comes to programming language textbooks.</p>
<p>First of all, I like my textbooks to be concise. “The Go Programming Language” is almost exactly the same width and height as K&amp;R, but about twice as thick. Some of that is down to paper thickness, though — it weighs in at 380 pages vs (my copy of) K&amp;R’s 272 pages. It’s no programming doorstopper.</p>
<p>
  <img src="/img/2015/IMG_20151203_185346_DxO.jpg" alt="Book comparison">

</p>
<p>“The Go Programming Language” is aimed at people who are already programmers, another thing I look for. I’ve written code in well over a dozen programming languages at this point, so the last thing I need is a chapter on what variables are or what a pointer is.</p>
<p>My third major preference is for examples over theory. Knuth’s “Art of Computer Programming” books, for example, are far too mathematical for my taste. I find math fascinating, but when it comes down to it I’d prove De Morgan’s laws by writing a program to dump out truth tables, not by doing the math. I also like the examples in a book to be things I might want (or at least need) to do, and this is an area where this particular book shines. Examples include building an Internet chat server, building a parallel download utility, calling a JSON API, converting dates and times, and so on. Chapter 9 even goes through the construction of a useful concurrent non-blocking cache implementation.</p>
<p>The overall structure of the book resembles K&amp;R, too. It opens by diving straight in to some examples, including a simple web server and code to draw some animated GIFs. By chapter 3 you’re drawing 3D surfaces and Mandelbrot sets. The general approach seems to be to take the reader on a whirlwind tour for a few chapters, convince them that it’s worth continuing to read the whole book, and then go back and cover topics in more detail. Sometimes a topic gets visited three or four times before the book gets to the bottom of it, so I recommend taking notes using an outliner or some other tool that lets you insert extra material later.</p>
<p>Mostly the book’s structure works, but occasionally details were omitted that I couldn’t help wondering about. For example, page 12 puts a <code>*</code> in front of the <code>os.File</code> type without any explanation of what it means. Even knowing that it indicates a pointer, I couldn’t work out why that type in particular needed to be a pointer in the example, when other structures didn’t. (That particular mystery wasn’t really resolved until chapter 6.) On several occasions I ended up searching the Internet for answers. I still don’t know what <code>//!+</code> and <code>//!-</code> comments mean in the example code, if anything.</p>
<p>Another thing that struck me as odd was that after covering structs, the book dived into JSON serialization and deserialization and templating, before it had even discussed how objects work. I’m being picky, though — the book did eventually cover the material, I just needed to relax and be patient and save my questions for the relevant chapter.</p>
<p>While the book is largely about the nuts and bolts of programming in Go, it does also cover some of what you might call the <em>philosophy</em> of the language — why it’s the way it is, and not like (say) C++, Rust or Scala. There’s also discussion of the benefits of encapsulation and its downsides, how to do unit testing, what recursion is, and so on.</p>
<p>There are two chapters on the problems of concurrency and shared data. This is necessary, given Go’s focus on concurrency — yet it’s also not enough. For example, the book talks quite extensively about race conditions and how to avoid them, but not so much about deadlocks (except as a side effect of bad mutex use). A separate book on concurrent programming would be advisable for those new to it; perhaps “Advanced Concurrent Programming With Go” is already in the works as the obvious sequel.</p>
<p>One thing K&amp;R had which is missing in “The Go Programming Language” is a reference section. This book has no list of the standard libraries or APIs in Go 1.x, so you’ll need to refer to the web site at <a href="https://golang.org/">golang.org</a> for that information. To give some specifics, the book doesn’t cover linked list data structures, logging, database access, or calling other processes. This is a bit of a shame, as at the time of writing the API documentation on the web is often minimal at best. On the other hand, I can understand that the APIs might still be too much of a moving target to be worth committing to paper, and including them <em>all</em> would have turned the book into a doorstop. I think the right decision was made, for now; just be aware that this is a book to teach you the core language, not a reference manual.</p>
<p>And with that said, my conclusion is that it’s an <em>excellent</em> book. By the time I was finishing reading it, things which had confused me during my early attempts at writing Go code were making perfect sense. If you’re a programmer and want to learn Go, this would be my recommendation for the first book to get.</p>
]]></content></entry><entry><title type="html">Go</title><link href="https://lpar.ATH0.com/posts/2015/12/go/"/><id>https://lpar.ATH0.com/posts/2015/12/go/</id><published>2015-12-02T23:23:16+00:00</published><updated>2015-12-02T23:23:16+00:00</updated><summary>It’s basically C, but a bit better.</summary><content type="html"><![CDATA[<p>Back when I was 17, I thought C was the greatest programming language in the world.</p>
<p>I had started programming in BASIC, messed with assembly language, then discovered Pascal. Both BASIC and Pascal were interpreted, at least in the implementations I had, so C was my first compiled language. Being able to produce machine code without writing assembler was a revelation. Sure, C had rough edges here and there — the type declarations often needed careful thought to decode — but it did the job like nothing else.</p>
<p>A year or so later I discovered Modula-2, again compiled. I wasn’t a big fan of the Pascal-style BEGIN…END blocks, having become used to the brevity of C’s curly brackets, but Modula-2’s import mechanism and limited multithreading made development less painful.</p>
<p>Still, I couldn’t help think that C and Modula-2 had some obvious things missing. The one that I found strangest was the inability to return multiple values from a function. If the compiler could push multiple arguments on the stack before calling the function code, why couldn’t it pop multiple results off the stack afterwards? Another thing I found annoying was manual memory management, particularly manually sizing and resizing arrays.</p>
<p>Later at university, I became interested in dataflow programming languages, experimental graphical programming environments where you wired together data channels between blocks representing computation units. The idea seemed sound, particularly with talk of massively parallel computers on the horizon, but I couldn’t help thinking that textual code was still the way to go.</p>
<p>I found myself imagining my ideal programming language. It would be superficially like C, but with the ability to return multiple values from functions. It would handle imports and libraries like Modula-2. It would allow parallelism, with communication by message passing, defining channels in and out of functions and wiring them together. And of course, it would support arbitrary size arrays.</p>
<p>Then I fell in love with Lisp, learned object oriented programming, graduated, got a job, and forgot the whole thing.</p>
<p>Fast forward to 2012. Google launched version 1.0 of a new programming language called Go. I ignored it for a while — you can’t pay attention to <em>every</em> new programming language — but after it failed to go away for a couple of years I decided to take a look at it. I soon noticed how much it seemed to resemble the imagined ideal programming language of my teenage years.</p>
<p>Programming language snobs have been scathing about Go, calling it a joke of a language. The funny thing about jokes, though, is that they often seem to win. Unix started out as a joke, and <a href="https://en.wikipedia.org/wiki/The_Unix-Haters_Handbook">was mocked well into the 1990s</a> — and now everyone carries a Unix computer in their pockets everywhere. Linux was a joke too, a crudely hacked-together clone of Unix with fundamentally the wrong architecture. The web was a joke — links that broke all the time, incompatibilities everywhere, and don’t even mention JavaScript. Plenty of people tried to build a non-Unix OS in C++, Ada or some other “real” programming language, and they all failed, often before getting to market.</p>
<p>I messed with Go, hacked together some simple programs, and decided it was something worth investigating further. The documentation on the web was definitely lacking, though — it was time to work my way through a good book.</p>
<p>Next: The book.</p>
]]></content></entry><entry><title type="html">The worst mergers and acquisitions</title><link href="https://lpar.ATH0.com/posts/2015/11/the-worst-mergers-and-acquisitions/"/><id>https://lpar.ATH0.com/posts/2015/11/the-worst-mergers-and-acquisitions/</id><published>2015-11-01T20:16:24+00:00</published><updated>2015-11-01T20:16:24+00:00</updated><summary>Often technologies die for reasons that have nothing to do with technology.</summary><content type="html"><![CDATA[<p>ZDNet ran a story in the week before Halloween about <a href="http://www.zdnet.com/article/horror-show-worst-mergers-and-acquisitions-in-tech-history/">the worst tech mergers and acquisitions</a>. Here are my thoughts on some of them.</p>
<h3 id="caldera-and-sco">Caldera and SCO</h3>
<p>Xenix was the first Unix I ever used. It’s how I ended up using the C Shell — I remember the Xenix box as only having csh, though it’s possible that it also had a really feature-poor version of sh. Either way, csh was the only reasonable option for interactive use.</p>
<p>When I got MINIX running at home, I stuck with csh. On real Unix, I switched to tcsh. Eventually Bash got support for Unicode, which was a compelling enough reason to switch to the Bourne family of shells. Then once Zsh got Unicode, I finally completed my destined path.</p>
<p>The less said about SCO’s business ventures after the Caldera acquisition, the better.</p>
<h3 id="palm">Palm</h3>
<p>Not mentioned in the article is that Palm OS was modeled on classic Mac OS, and the hardware used low power variants of the same 680×0 series processors that 1980s Macs were built on. PalmOS had <a href="https://en.wikipedia.org/wiki/Resource_fork">resource forks</a>, four character file type and <a href="https://en.wikipedia.org/wiki/Creator_code">creator IDs</a> — and no memory protection or virtual memory. This meant that Palm OS started to hit a technological wall a few years after the first PalmPilot; a single bad application could crash the entire device. As with classic Mac OS, there was no plausible technical way forward without basically starting from scratch, and by the end of the 90s it was clear to me that PalmOS was a dead end.</p>
<p>I think WebOS could have succeeded, if HP had stuck with it. The problem was, like the Apple Newton MessagePad, the software wasn’t <em>quite</em> ready by the time the hardware launched, and the hardware wasn’t quite the form factor people wanted. Better market research and a couple more iterations and I think they could have made it a going concern. I went with a BlackBerry instead, and watched the train wreck from a safe distance. (And then watched BlackBerry fail to deal with their own technological wall, and jumped again to Android.)</p>
<p>As an aside, I always expected Apple to sue Palm for patent or copyright violation.</p>
<h3 id="oracle-and-sun">Oracle and Sun</h3>
<p>I remember when Sun was looking for suitors, seeing employees saying “Anyone but IBM”. I suspect that hindsight may have caused them to re-evaluate that sentiment. Obviously I’m biased, but I think that IBM buying Sun would have been much better for almost all of Sun’s products.</p>
<p>Clearly OpenOffice would have lived for longer. In fact, IBM did its best to keep OpenOffice a going concern even while Oracle was busy killing its community. MySQL, too, would have been OK — IBM has long experience at maintaining multiple competing databases and supporting them all, and I think MySQL would have just been slotted into the portfolio alongside Informix, DB2, DB2 on i, Derby and IMS. Netbeans and Eclipse probably would have had a cage match, and Eclipse probably would have won out of inertia, but Netbeans features would have been rolled into Eclipse — and Java would have stayed an open technology.</p>
<p>The one Sun product I think would have had trouble at IBM is Solaris. AIX vs Solaris was still serious warfare at that point. Now, Linux is where it’s all happening (at least from my viewpoint), and I think Solaris would have ended up sidelined even if it had beaten out AIX for its new master’s affections. Still, Linux would have gotten ZFS and dtrace and the other things from Solaris that people actually like, and maybe SMF instead of systemd.</p>
<h3 id="hp-and-compaq">HP and Compaq</h3>
<p>HP’s real problem was partnering with Intel to produce its new RISC-replacement. Given <a href="http://lpar.ath0.com/2013/04/03/510/">Intel’s history</a>, they really should have known better. They then dumped the working Alpha CPU they had acquired by buying DEC, deciding to wait for Intel’s promised Itanic — and decided to let Intel handle all the design itself.</p>
<p>I guess that’s pretty much standard Carly Fiorina era HP, though — treat engineering as an expense you should avoid as much as possible, and make business decisions without their input.</p>
<h3 id="microsoft-and-danger">Microsoft and Danger</h3>
<p>The Danger Hiptop was a great product from a hardware and user experience standpoint, but when I discovered that it was entirely dependent on back-end cloud servers I steered clear and went with a BlackBerry instead. I don’t mind cloud services, but the product has to be able to work standalone. When Microsoft bought Danger I knew they were doomed. You could put together an entire article of disasters just by cataloging companies that have developed an intimate relationship with Microsoft: Microsoft and <a href="https://en.wikipedia.org/wiki/Vivo_Software">Vivo Software</a>, Microsoft and <a href="http://www.pcworld.com/article/122978/article.html">RealNetworks</a>, Microsoft and Kodak, Microsoft and <a href="http://www.theguardian.com/technology/2014/apr/29/stephen-elop-microsoft-nokia">Nokia</a>, Microsoft and <a href="https://en.wikipedia.org/wiki/Groove_Networks">Groove Networks</a>, Microsoft and <a href="http://venturebeat.com/2013/07/26/why-lorne-lanning-went-from-aaa-games-to-indie-and-loudly-loves-it-interview/">Oddworld Inhabitants</a>, Microsoft and Bungie, Microsoft and <a href="https://en.wikipedia.org/wiki/FASA_Studio">FASA Interactive</a>, Microsoft and <a href="https://en.wikipedia.org/wiki/Connectix">Connectix</a>, Microsoft and <a href="https://en.wikipedia.org/wiki/Rare">Rare</a>, Microsoft and WebTV…</p>
<h3 id="borland-and-ashton-tate">Borland and Ashton-Tate</h3>
<p>Borland had two big problems which hurt sales of their compiler products: their languages were non-standard, and they were single platform.</p>
<p>Turbo Pascal was great, but it wasn’t <a href="https://en.wikipedia.org/wiki/Pascal_%28programming_language%29#ISO.2FIEC_7185:1990_Pascal">standard ISO Pascal</a>. Instead of migrating to (say) <a href="https://en.wikipedia.org/wiki/Modula-3">Modula-3</a>, they added proprietary extensions to Pascal for OOP. They had C++, but they used their own layer of windowing APIs on top of Microsoft’s, which led to the horror of <a href="http://c2.com/cgi/wiki?BorlandButtons">Borland Buttons</a>.</p>
<p>
  <img src="/img/2015/download.jpeg" alt="">

</p>
<p>So if you wrote your code for Borland C++ or Pascal, you were forever tied to Windows. That meant that once Microsoft had a workable set of development tools, Borland’s target market was people who loved Microsoft enough to want to use only Microsoft Windows as their OS, but didn’t like Microsoft enough to use their development tools. That market was approximately 0 people.</p>
<h3 id="novell-and-unix">Novell and Unix</h3>
<p>Novell’s problem was wasting its time trying to keep IPX alive and trying to be a Unix vendor. Once dial-up Internet was a thing and TCP/IP was usable even in small offices of Windows machines, IPX was dead. Windows for Workgroups in 1993 showed the future. If Novell had made a user-friendly fileserver OS by adding full TCP/IP services to NetWare, they could have had a sellable product; but practically nobody who used NetWare wanted to switch to Unix, and nobody who wanted to use Unix had any compelling reason to get it from Novell.</p>
<h3 id="google-and-motorola">Google and Motorola</h3>
<p>It was patently apparent, if you’ll pardon the pun, that Google was only interested in Motorola in order to use its ‘intellectual property’ as a defensive resource in the litigation wars started by Apple. I don’t call this one a failure. Motorola even produced some great handsets during the Google period — look at the Moto X and Moto G.</p>
<p>What <em>has</em> been a disaster, is <a href="http://www.androidpolice.com/2015/10/08/an-open-letter-to-motorola-start-promising-a-concrete-period-of-update-support-to-your-customers-or-start-losing-them/">Motorola since Lenovo took over</a>.</p>
<h3 id="hp-and-autonomy">HP and Autonomy</h3>
<p>Autonomy had some really neat software when I saw demos around 2000. Sure, it was all based on Bayesian inference, but it was useful stuff. Other than HP paying too much, the real problem with this merger is that HP has never been any good at selling software.</p>
<h3 id="nokia-and-microsoft">Nokia and Microsoft</h3>
<p>Nokia made a lot of mistakes in the 1990s. Like Palm and BlackBerry, they ignored their OS platform’s technical shortcomings. Like HP with WebOS, they made poor hardware design decisions.</p>
<p>However, by the early 2000s Nokia was <a href="https://en.wikipedia.org/wiki/Maemo">heading in the direction of a Linux-based handset OS</a> developed in an open source fashion, and they were about to start <a href="https://en.wikipedia.org/wiki/Maemo#Qt">moving to Qt for their UI</a> to make development and porting from other platforms easier. Maemo was almost at the point where it would have been workable for phones, it just needed a better touch UI, which Qt would likely have given it one.</p>
<p>It’s pretty clear to me that Microsoft wanted to kill Maemo before it was too late, and obtain Nokia’s patents so they could use them against Android. Elop may deny it, but I think this is another outwardly disastrous merger that went exactly the way it was intended to.</p>
<p>I mean, Microsoft had been trying to sell Windows-based mobile phones <a href="http://mashable.com/2012/10/29/microsoft-mobile-history/">since 2000</a> without major success (vertical markets excepted). It makes no sense that Elop would kill Maemo <em>and</em> Symbian and bet the company on Windows Phone — until you realize that he joined Nokia from Microsoft.</p>
<p>Not convinced it went according to plan? Consider that it was Elop who made the decision to sell Nokia to Microsoft once its value had dropped by 85%, and that he <a href="http://www.telegraph.co.uk/finance/newsbysector/mediatechnologyandtelecoms/telecoms/10321231/Nokia-chief-Stephen-Elop-to-get-25m-after-Microsoft-deal.html">got a $25m reward when that transaction was completed</a> — with <a href="http://www.slashgear.com/nokia-to-pay-stephen-elop-millions-to-move-to-microsoft-19298520/">most of the cash coming from Microsoft</a>.</p>
<p>Microsoft <a href="https://www.polygon.com/2014/2/24/5444290/stephen-elop-taking-over-xbox-division-microsoft">gave Elop the Xbox division</a> to play with for a year, but he was <a href="http://www.theverge.com/2015/6/17/8796055/stephen-elop-mark-penn-leave-microsoft">invited to accept a horizontal promotion</a> as soon the media had forgotten about him. They <a href="http://uk.businessinsider.com/even-microsoft-is-giving-up-on-windows-phones-2015-7?r=US&amp;IR=T">quietly killed Windows Phone</a>, and have settled into their primary mobile strategy of <a href="http://arstechnica.com/information-technology/2011/10/microsoft-collects-license-fees-on-50-of-android-devices-tells-google-to-wake-up/">collecting patent licensing fees on Android devices</a> and <a href="http://www.cnet.com/news/microsoft-asus-sign-combined-android-patent-office-bundling-deal/">forcing Android device manufacturers to bundle Office</a>.</p>
]]></content></entry><entry><title type="html">Engage!</title><link href="https://lpar.ATH0.com/posts/2015/10/engage/"/><id>https://lpar.ATH0.com/posts/2015/10/engage/</id><published>2015-10-20T18:52:10+00:00</published><updated>2015-10-20T18:52:10+00:00</updated><summary>A CPU instruction even better than EIEIO.</summary><content type="html"><![CDATA[<p><code>makeitso</code></p>
<p>New in the POWER8 processor, this instruction allows data to push out to the coherence point as quickly as possible. An attempt to run the <code>makeitso</code> instruction provides a hint that preceding stores are made visible with higher priority.</p>
<p>— <a href="http://www.redbooks.ibm.com/abstracts/sg248171.html?Open">Performance Optimization and Tuning Techniques for IBM Power Systems Processors Including IBM POWER8</a></p>
]]></content></entry><entry><title type="html">On ad blocking and ethics</title><link href="https://lpar.ATH0.com/posts/2015/09/on-ad-blocking-and-ethics/"/><id>https://lpar.ATH0.com/posts/2015/09/on-ad-blocking-and-ethics/</id><published>2015-09-20T15:58:08+00:00</published><updated>2015-09-20T15:58:08+00:00</updated><summary>Please feel free to block all the ads on my web site.</summary><content type="html"><![CDATA[<p>Apple’s introduction of an API for browser content blockers on iOS has reignited the debate over ad blocking on the web.</p>
<p>While Apple have promoted the feature as something aimed at improving the mobile user experience, others have pointed out that it’s transparently an attempt to harm Google. In truth, it’s both of those things.</p>
<p>The mobile web experience without a content blocker is wretched. Just yesterday I attempted to read an article on the New York Times, only to have it forcibly scroll my tablet to the top of the page in an endless loop to try to force me to read the ads. This new practice is probably a result of user studies I saw recently (no handy link, sorry) revealing that half of users now start scrolling down to avoid the ads before the page has even finished rendering.</p>
<p>Another good example of just how bad things can be is The Verge, who bloat every few kilobytes of page content with <a href="/2015/07/20/why-the-mobile-web-sucks/">2.6MB or more of ads and scripts</a>. Then there are the sites still using Flash, who pop up large gray rectangles over their content.</p>
<p>On desktop, I don’t block ads. Instead, I block third party scripts, cookies and plugins. Given that major ad networks’ scripts <a href="http://www.cyphort.com/huffingtonpost-serving-malware/">have been</a> used to <a href="https://blog.malwarebytes.org/malvertising-2/2015/08/large-malvertising-campaign-takes-on-yahoo/">spread malware</a>, I view the script blocking as an essential security practice. The cookie blocking is simply to reduce the amount I’m tracked across the web. Flash is a security and privacy disaster that should have died ages ago, so I don’t have it installed.</p>
<p>But here’s the thing: blocking invasive and dangerous ads is, in practice, much like blocking all ads. Major sites like CNN and the New York Times show up ad-free, because all their ads attempt to track you and hijack control of your browser. This shows that there’s a big problem with the online advertising industry.</p>
<p>Newspaper ads and billboards don’t interrupt people’s navigating the city or track them as they travel, yet they’re still effective. But somehow because it was <em>possible</em> to do those things on the web, advertisers managed to persuade site owners that it was <em>necessary</em>. Well, it isn’t, and now we’re seeing the backlash.</p>
<p>The sites now screaming about the evils of ad blockers need to adjust their approach. If you give people a choice of invasive ads or no ads, they’ll take no ads every time. So instead, you need to rein in your demands and ask people to limit their blocking.</p>
<p>So, encourage users to install <a href="https://www.eff.org/privacybadger">Privacy Badger</a> in place of a full-on ad blocker, or to turn on the option to <a href="https://adblockplus.org/acceptable-ads">allow non-invasive ads in AdBlock Plus</a>. Go back to safe scriptless ads that don’t try to install cross-site tracking cookies. People will see your ads and still keep their privacy and security, and everyone will be happy.</p>
]]></content></entry><entry><title type="html">Hypertext and software patents</title><link href="https://lpar.ATH0.com/posts/2015/09/hypertext-and-software-patents/"/><id>https://lpar.ATH0.com/posts/2015/09/hypertext-and-software-patents/</id><published>2015-09-01T14:04:59+00:00</published><updated>2015-09-01T14:04:59+00:00</updated><summary>Prior art from a long time ago.</summary><content type="html"><![CDATA[<p>While I was visiting my family in the UK recently, I went through some old paperwork. One of the documents was my undergraduate dissertation from 1989/1990. My project was to build a graphical hypertext browser and editor which could link existing text files. I’d been experimenting with hypertext on and off since the mid 80s, when I had learned about it from Ted Nelson’s book “Dream Machines”.</p>
<p>My browser used a two-pane interface resembling a frameset, with links in a list on the right of the document being viewed. It wasn’t terribly elaborate — after all, it was only an undergraduate project — but it’s worth remembering that this was before Tim Berners-Lee developed his first web browser, and several years before Netscape introduced framesets.</p>
<p>I’ve scanned the document to PDF and filed it away, mostly because there’s a chance it might one day be useful as a demonstration of prior art to invalidate a software patent. I don’t plan on publishing it here, because it really isn’t anything special; I’m just writing this note for the benefit of anyone who suddenly needs prior art around framesets, hyperlinks and extrinsic links, who might want to contact me.</p>
]]></content></entry><entry><title type="html">Security practices: experts vs non-experts</title><link href="https://lpar.ATH0.com/posts/2015/08/security-practices-experts-vs-non-experts/"/><id>https://lpar.ATH0.com/posts/2015/08/security-practices-experts-vs-non-experts/</id><published>2015-08-29T17:57:42+00:00</published><updated>2015-08-29T17:57:42+00:00</updated><summary>What people believe vs what’s effective.</summary><content type="html"><![CDATA[<p>Google recently published the results of a survey of computer users to see what security practices they follow. The paper splits the users into two groups — security experts (people who deal with computer security for a living as part of their job, like me), and non-expert users.</p>
<p>For each of the two groups, Google <a href="http://googleonlinesecurity.blogspot.com/2015/07/new-research-comparing-how-security.html?m=1">assembled a list of the top five security practices followed</a>. You probably won’t be surprised to learn that the two groups had almost completely different lists.</p>
<p>I thought I’d write and explain <em>why</em> the experts make the choices they do, and what it is about the non-experts’ choices that make them relatively poor ones.</p>
<hr>
<p>First on the experts’ list is <em>install software updates</em>.</p>
<p>I do this. It’s part of my job, as a server sysadmin, but I do it at home as well. As soon as a software update is available which includes any bug fixes, I install it. This morning I upgraded WordPress, for example. In fact, I don’t just wait to be told about bug fixes — I look out for announcements of security issues on prominent tech news sites, and go find the fixes.</p>
<p>Most other people aren’t as diligent. My spouse has a bad habit of leaving software updates for weeks. Yes, it often requires rebooting, but really, it’s important! 99% of attacks <a href="http://www.insidecounsel.com/2015/04/14/999-percent-of-hackers-exploiting-publicly-known-s">happen as a result of known security flaws</a> that people have been too lazy to install the fix for. That’s why Microsoft is going to be <a href="http://www.slashgear.com/windows-10-auto-updates-are-a-necessary-evil-20393580/">requiring that users accept automatic updates for Windows 10</a>.</p>
<p>Second on the experts’ security practices list is <em>use unique passwords</em>. This is absolutely crucial. Every few months a web site gets hacked and the passwords are stolen and leaked. If it happens to you and you’ve used the same password everywhere, you have to hurry and change your password before some bad guy cross-references your accounts. Worst case for me, they get the password to the one site that was hacked.</p>
<p>I go a step further. For accounts where security is particularly important — like bank accounts — I use a unique user ID different from the one I use anywhere else. A criminal won’t be able to find out my bank login just because some forum got hacked.</p>
<p>Of course, using unique passwords means having too many passwords to memorize. That’s why an important step towards better online security is <a href="https://www.schneier.com/blog/archives/2014/09/security_of_pas.html">using some sort of password manager</a> — whether it’s a paper notebook you keep in your office, an application, or a fancy online service like LastPass. That’s item 5 on the experts’ list.</p>
<p>Item 3 on the experts’ list is <em>use two-factor authentication</em>. I do this too, using the free open source <a href="https://play.google.com/store/apps/details?id=org.fedorahosted.freeotp&amp;hl=en">FreeOTP</a>. It implements TOTP, which is the Internet standard for time-dependent two-factor authentication. TOTP is the basis of Google Authenticator, so anywhere Google Authenticator works, FreeOTP works.</p>
<p>Two-factor authentication is pretty simple once you set it up. When you log in, you’re asked for the secret code. You run the app on your phone, and it shows you a 6-digit number, which you enter into the login form. That’s it, you’re done. The clever parts that make this good for security are:</p>
<ol>
<li>The 6-digit code changes every 60 seconds, and</li>
<li>Each code only works once.</li>
</ol>
<p>This immediately helps with all kinds of security problems:</p>
<ul>
<li>A web site hack exposes my password? Not a big deal, without the code generator it’s useless, so there’s no hurry to change it.</li>
<li>I log in using someone else’s computer, and they have keylogger malware on it? Not a major problem — the code only works once, so the logged password and code can’t be used again.</li>
<li>Someone shoulder-surfs me and watches me type my password <em>and</em> sees the code number on my phone screen? Not a problem, the code number only works once, and when I’m done logging in I lock the phone so they can’t get a fresh number, even assuming they could hurry to use the information within a minute.</li>
</ul>
<p>Two-factor authentication doesn’t prevent <em>all</em> attacks, of course, but it’s a massive improvement over just a login and password.</p>
<p>Unfortunately, there are a few sites that still don’t support TOTP — including Apple, Twitter, eBay and PayPal. I don’t use SMS-based two factor authentication because SMS isn’t reliable and doesn’t necessarily work if you’re overseas, meaning it’s all too easy to get locked out or have to wait half an hour to log in.</p>
<p>Item four on the experts’ list is <em>use strong passwords</em>. You might wonder why it’s so far down the list. Well, using a strong password is less important than using a unique one. If you use unique weak passwords, well, it probably won’t be that big of a deal — most web sites limit the number of attempts to log in remotely or how quickly you can try again if you get the password wrong. The real danger of a weak password is that any hacker getting the encrypted password file will be able to crack the password immediately. As long as I use unique passwords, that only lets them get into my account on the site that was hacked.</p>
<p>Contrast that with the situation if you use the same strong password everywhere. Eventually a web site will be hacked that doesn’t properly encrypt its passwords, and the hackers will now have your password to every site you use. Much, much worse. So unique passwords are much more important than strong ones — not that I’m encouraging you to use weak passwords, by any means.</p>
<p>As an aside, you might surprised by just how long and complicated a password has to be in order to be a strong password. The bare minimum password length you should be using <a href="http://blog.codinghorror.com/your-password-is-too-damn-short/">is 12 characters</a>, and that’s assuming you use random combinations of upper- and lower-case letters, numbers and symbols.</p>
<hr>
<p>Now let’s go through the <em>non-experts’</em> list of security practices, and consider why they aren’t very useful.</p>
<p>First on the non-expert list is to use antivirus software. I’m honestly not sure how important that is on Windows these days, but I’ll confess that I haven’t used Mac or Linux antivirus software in years. I haven’t heard of anyone I know getting a Mac or Linux virus in years either. Trojans, yes, but not viruses.</p>
<p>Second on the non-experts’ list is strong passwords, and I’ve already discussed why that’s less important than you think — but I’ll point out that it’s also trivial to use strong passwords anyway if you do what the experts do, and use a password manager.</p>
<p>Third on the non-experts’ list is to change passwords frequently. A few web sites seem to think this is good practice, but it usually isn’t.</p>
<p>First of all, if you have a strong password, there is nothing to be gained by changing it. If it’ll take a hundred years to crack it, changing it to another strong password gains you nothing.</p>
<p>Even if you don’t have a strong password, there’s the downside that changing passwords are harder to remember. That means people are more likely to write them down or leave them on a Post-It note on the monitor.</p>
<p>But the big reason why I don’t change passwords often is that the real reason for changing them isn’t to make them harder to guess. Rather, it’s to limit the amount of time for which a stolen password can be used. If someone steals my password and I don’t change it for a year, they can use that password for a year to snoop on my account.</p>
<p>Except… I use two factor authentication. But even ignoring that, most hackers today aren’t going to quietly snoop. If you read stories about victims of hacks, you’ll learn that <a href="https://www.schneier.com/blog/archives/2010/11/changing_passwo.html">today’s crooks generally steal a password and then immediately change it</a>, to lock the rightful owner out of the account while they steal whatever they’re after.</p>
<p>So password changing is really only protecting you against a particular class of attacker — say, the jealous ex-boyfriend who wants to read your e-mail, or the corporate competitor who wants to spy on your sales prospects. For things like your Amazon account or your bank account, that’s not the kind of attack you need to worry about.</p>
<p>Number 4 on the non-experts’ lists is to only visit web sites you know.</p>
<p>Well, that’s an easy guideline to evaluate — it’s completely useless. Consider all the well-known companies whose systems have been hacked: Home Depot, Target, Sony, AT&amp;T, Nieman Marcus, Michaels, Yahoo!, eBay, Evernote, Apple, JPMorganChase, Snapsave… and that’s just a <em>partial</em> list of the hacks in 2014 alone!</p>
<p>Now consider how many of the rest of the sites you know and visit run ad banners, and ponder the fact that in the same year, Google’s Doubleclick ad network <a href="http://www.theverge.com/2014/9/19/6537511/google-ad-network-exposed-millions-of-computers-to-malware">exposed millions of computers to malware</a>.</p>
<p>No, restricting yourself only to familiar big name web sites isn’t going to do anything for your security. In fact, since the big names are big targets and seem to be doing a terrible job of protecting you, you’re probably <em>safer</em> visiting some obscure web forum nobody has heard of. In a 2012 study by Symantec, the most dangerous sites to visit were <a href="http://www.huffingtonpost.com/2012/05/02/port-religious-sites-riskier_n_1471175.html">religious sites</a> — you were safer visiting sleazy porn sites than the site of your well-known local church.</p>
<p>The final non-expert security practice is <em>don’t share personal information</em>. That’s not a terrible principle to follow, but it’s way down the list of effective security measures. The problem is that you <em>need</em> to share personal information with many companies in order to do business with them, and criminals don’t get your personal information by asking you to share it — they get it by hacking the database where it has been collected.</p>
<p>The most recent example is the <a href="https://en.wikipedia.org/wiki/Office_of_Personnel_Management_data_breach">data breach at the Office of Personnel Management</a>. That’s the agency that performs <a href="https://www.opm.gov/investigations/background-investigations/">90% of US government background checks</a>. So sorry, but you don’t get to decide whether to share your personal information with the OPM — at least, not if you want a government job. And that database got stolen because as a cost-saving measure, the OPM had decided to use offshore contractors to manage their systems — so as part of that deal, <a href="http://arstechnica.com/security/2015/06/encryption-would-not-have-helped-at-opm-says-dhs-official/">they handed root access to their systems to a Chinese national living in China</a> and another person living in Argentina. Remember, this is the database that contains all the background check information for US spies.</p>
<p>Similarly, the Hollywood stars who had their personal lives exposed by the Sony hack didn’t really have any choice about whether to share information with Sony, if they wanted a career in Hollywood. And while you might have read that the “hack” was the work of North Korea, the evidence suggests that it was the work of <a href="http://time.com/3649394/sony-hack-inside-job-north-korea/">Russian hackers tipped off by a disgruntled insider</a>.</p>
<p>Finally, let me throw in a vital security practice which was missing from the experts’ list: <em>backing up</em>.</p>
<p>As more and more of our data gets stored in the cloud, or on Internet-connected systems, it becomes more and more likely that a security incident will result in data being wiped. Last year, a source code hosting system called Code Spaces was hacked, and the hackers <a href="http://searchaws.techtarget.com/news/2240223024/Code-Spaces-goes-dark-after-AWS-cloud-security-hack">wiped all their data</a>. Plenty of small web sites get hacked too, and <a href="https://www.phpbb.com/community/viewtopic.php?f=46&amp;t=2266291">forums get wiped</a>.</p>
<p>WordPress is a notorious target; you don’t have to go far to find stories of <a href="https://wordpress.org/support/topic/alright-my-wordpress-got-hacked-and-deleted-help-me?replies=10">sites being wiped by hackers</a>. That’s why I keep backups of everything I post. Not just copies, either — rolling incremental backups which will let me roll back some number of days, in case it takes a while for me to notice that something is wrong. The backups are stored on a machine in my office, which you can’t get to from the web server.</p>
<p>So, back up your data. Use Apple Time Machine or something like it. Keep backups of everything you store in the cloud.</p>
]]></content></entry><entry><title type="html">Why the mobile web sucks</title><link href="https://lpar.ATH0.com/posts/2015/07/why-the-mobile-web-sucks/"/><id>https://lpar.ATH0.com/posts/2015/07/why-the-mobile-web-sucks/</id><published>2015-07-20T17:47:49+00:00</published><updated>2015-07-20T17:47:49+00:00</updated><summary>Except this site, of course.</summary><content type="html"><![CDATA[<p>Over at The Verge, <a href="http://www.theverge.com/2015/7/20/9002721/the-mobile-web-sucks">Nilay Patel writes</a>:</p>
<blockquote>
<p>I hate browsing the web on my phone.</p>
<p>I do it all the time, of course — we all do. Just looking at the stats for The Verge, our mobile traffic is up 70 percent from last year, while desktop traffic is up only 11 percent. That trend isn’t going back; phones are just too convenient, beckoning us to waste more and more of our time gazing at their ever-larger screens.</p>
<p>But man, the web browsers on phones are terrible. They are an abomination of bad user experience, poor performance, and overall disdain for the open web that kicked off the modern tech revolution. […]</p>
<p>Now, I happen to work a media company, and I happen to run a website that can be bloated and slow. Some of this is our fault: The Verge is ultra-complicated, we have huge images, and we serve ads from our own direct sales and a variety of programmatic networks. Our video player is annoying. (I swear a better one is coming, for real this time.) We could do a lot of things to make our site load faster, and we’re doing them.</p>
</blockquote>
<p>I couldn’t resist doing a quick analysis of page speed for that very article:</p>
<ul>
<li>22 seconds to fully load on desktop</li>
<li>2.6MB of data</li>
<li>81 separate JavaScripts</li>
<li>…plus 12 more JavaScripts blocked for XHR violations</li>
<li>…plus chartbeat.net trackers giving 503 errors (site over capacity)</li>
<li>…plus 3 Flash movies which would have bloated things up much further if I didn’t have Flash disabled</li>
</ul>
<p>And yes, if I emulate a mobile device, it’s the same 2.6MB of data and 81 JavaScripts.</p>
<p>Gosh, I wonder why The Verge is miserable to read on mobile, eh?</p>
<p>Expecting mobile browser makers to magically solve your site’s performance problems is unrealistic. Mobile network data has high latency and (comparatively) low speed, and that’s inherent to the technology. You simply <em>must</em> engineer your web site with mobile browsers in mind.</p>
<p>For those who have ignored web performance, the current trend of more and more traffic coming from mobile browsers is going to lead to a painful reckoning.</p>
]]></content></entry><entry><title type="html">Two OpenLDAP TLS gotchas</title><link href="https://lpar.ATH0.com/posts/2015/06/two-openldap-tls-gotchas/"/><id>https://lpar.ATH0.com/posts/2015/06/two-openldap-tls-gotchas/</id><published>2015-06-11T22:03:39+00:00</published><updated>2015-06-11T22:03:39+00:00</updated><summary>CentOS 7 / RHEL 7 can’t contact TLS server.</summary><content type="html"><![CDATA[<p>The scenario:</p>
<ul>
<li>You’re using CentOS 7 or RHEL 7.</li>
<li>You’re using OpenLDAP.</li>
<li>You have TLS set up on OpenLDAP.</li>
<li>You are trying to perform a query against the server using <code>ldapsearch</code>.</li>
</ul>
<h3 id="problem-1">Problem #1:</h3>
<p>You get:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-txt" data-lang="txt"><span class="line"><span class="cl">ldap_start_tls: Can&#39;t contact LDAP server (-1)
</span></span><span class="line"><span class="cl">ldap_sasl_bind(SIMPLE): Can&#39;t contact LDAP server (-1)
</span></span></code></pre></div><p>Possible solution:</p>
<p>You’re using the <code>-Z</code> option (along with <code>-h</code> and <code>-p</code>) to specify the host and port and request TLS. That option doesn’t work.</p>
<p>Instead, just use the <code>-H</code> option and specify the parameters as an LDAPS URL.</p>
<p>For example:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sh" data-lang="sh"><span class="line"><span class="cl">ldapsearch -x -Z -h localhost -p <span class="m">636</span> -b <span class="s1">&#39;dc=example&#39;</span> <span class="s1">&#39;(objectClass=*)&#39;</span>
</span></span></code></pre></div><p>becomes:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sh" data-lang="sh"><span class="line"><span class="cl">ldapsearch -x -H ldaps://localhost:636/ -b <span class="s1">&#39;dc=example&#39;</span> <span class="s1">&#39;(objectClass=*)&#39;</span>
</span></span></code></pre></div><p>This is actually mentioned on the <a href="http://www.openldap.org/faq/data/cache/185.html">OpenLDAP FAQ</a> if you look hard enough:</p>
<blockquote>
<p>Most clients now have a -Z flag which enables sending the StartTLS extended operation to the server. This extended operation initiates TLS negotiation. <strong>To use ldaps://, one must use -H ldaps://.</strong></p>
</blockquote>
<p>(Emphasis mine.) I’ve no idea what <code>-Z</code> is for, given that it isn’t needed if you use -H with an LDAPS URL, and doesn’t work if you don’t.</p>
<h3 id="problem-2">Problem 2:</h3>
<p>Having worked out how to request a TLS connection, it still doesn’t work, so you try adding the <code>-d 1</code> argument to turn on some debugging. In the client’s debug logs you see either:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-txt" data-lang="txt"><span class="line"><span class="cl">TLS: error: tlsm_PR_Recv returned 0 - error 21:Is a directory
</span></span></code></pre></div><p>or</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-txt" data-lang="txt"><span class="line"><span class="cl">TLS: error: tlsm_PR_Recv returned 0 - error 13:Permission denied
</span></span></code></pre></div><p>Solution:</p>
<p>You probably have SELinux enabled. OpenLDAP doesn’t work with SELinux. Disable it and reboot the server, or work out how to persuade SELinux to let openldap open its own config files.</p>
]]></content></entry><entry><title type="html">Systemd</title><link href="https://lpar.ATH0.com/posts/2015/02/systemd/"/><id>https://lpar.ATH0.com/posts/2015/02/systemd/</id><published>2015-02-04T18:39:36+00:00</published><updated>2015-02-04T18:39:36+00:00</updated><summary>We will add your technological distinctiveness to our own. Your distribution will adapt to service us. Resistance is futile.</summary><content type="html"><![CDATA[<p>[Now <a href="https://ma.ttias.be/whats-new-systemd-2015-edition/">updated for 2015</a>!]</p>
<table>
	<thead>
			<tr>
					<th>Component</th>
					<th>Status</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td>systemd</td>
					<td>Replaces init, cron, inetd, udev, locale, acpid, atd, <a href="https://tlhp.cf/lennart-poettering-su/">su</a>.</td>
			</tr>
			<tr>
					<td>systemd-journald</td>
					<td>Replaces syslog, klog.</td>
			</tr>
			<tr>
					<td>systemd-logind</td>
					<td>Replaces getty, login, xdm. (*)</td>
			</tr>
			<tr>
					<td>systemd-networkd</td>
					<td>Replaces ifup, ifdown, tcpwrapper, hostname, dhcpd.</td>
			</tr>
			<tr>
					<td>systemd-journal-gatewayd</td>
					<td>Provides HTTP server for systemd-journal.</td>
			</tr>
			<tr>
					<td>systemd-timesync</td>
					<td>Replaces NTP.</td>
			</tr>
			<tr>
					<td>systemd-resolved</td>
					<td>Replaces resolvconf, bind, powerdns-recursor, dnsmasq.</td>
			</tr>
			<tr>
					<td>systemd-automount</td>
					<td>Replaces autofs.</td>
			</tr>
			<tr>
					<td>systemd-readahead</td>
					<td>No longer supported because <a href="https://www.mail-archive.com/systemd-devel@lists.freedesktop.org/msg21693.html">everyone who matters has SSDs</a>.</td>
			</tr>
			<tr>
					<td>systemd-machined</td>
					<td>Replaces VirtualBox, VMware. (<a href="http://ma.ttias.be/whats-new-systemd-2015-edition/">Coming soon</a>.)</td>
			</tr>
			<tr>
					<td>systemctl-cat</td>
					<td>Replaces cat. Really.</td>
			</tr>
			<tr>
					<td>systemd-udevd</td>
					<td>Replaces udev.</td>
			</tr>
			<tr>
					<td>systemd-firewall</td>
					<td>Replaces iptables.</td>
			</tr>
			<tr>
					<td>systemd-journal-remote</td>
					<td>Replaces logstash/elasticsearch with a new logging protocol over HTTP.</td>
			</tr>
			<tr>
					<td>gummiboot</td>
					<td>To be incorporated, replacing grub.</td>
			</tr>
	</tbody>
</table>
<p>Also, <a href="http://seclists.org/oss-sec/2014/q4/592">here come the security vulnerabilities</a>:</p>
<blockquote>
<p>…systemd-resolved does not implement any of the hardening recommendations of rfc5452</p>
</blockquote>
<p>(*) OK, so it’s a bit more complicated than that. Eventually the plan is to get rid of X11 for Wayland, but currently X11 is still allowed. However, systemd is part of the PAM configuration now, and <a href="https://wiki.archlinux.org/index.php/Systemd/User#Xorg_as_a_systemd_user_service">systemd starts your X session with display manager and window manager</a>. So far login and getty still service legacy non-console ttys.</p>
]]></content></entry><entry><title type="html">In the wake of shellshock</title><link href="https://lpar.ATH0.com/posts/2014/09/in-the-wake-of-shellshock/"/><id>https://lpar.ATH0.com/posts/2014/09/in-the-wake-of-shellshock/</id><published>2014-09-26T16:06:39+00:00</published><updated>2014-09-26T16:06:39+00:00</updated><summary>Bash bashing.</summary><content type="html"><![CDATA[<p>So, <a href="http://seclists.org/oss-sec/2014/q3/650">shellshock</a>. It’s big. I think it’s bigger than heartbleed, because the bug has been in the code for 22 years, so there are an awful lot of systems out there with a vulnerable shell installed and nobody maintaining them properly.</p>
<p>One misconception I’ve seen posted across the web is that you’re not in trouble if you don’t use bash as your shell, or that you’re safe if you have dash as <code>/bin/sh</code>. Sadly, that’s not true. GNU tools like <code>env</code> will use bash to execute other programs no matter what your personal shell is. Other programs you use may invoke bash too — for example, on Ubuntu the <code>zcat</code> utility is a bash script. So are Firefox and Chrome.</p>
<p>As for exploits, basically any program which sets environment variables based on user input and uses the shell to execute something can become a vector. There’s a working exploit for Linux DHCP, so you can get pwned simply by connecting to a WiFi network. There are at least two worms spreading via the web, where you can pwn servers just by setting your web browser’s user agent to something cunning. There’s an IRC worm active, and an exploit via email has been demonstrated for some server-side software. SSH restricted mode is affected, becoming SSH totally unrestricted mode. And that’s just the stuff I know about.</p>
<p>At work, a colleague just asked what needs to be upgraded. My answer: <em>Every Linux system on the planet.</em> Prioritize ones which accept data from outside your organization (no matter how they do it). You’ll eventually want to patch everything running a Linux distibution, because the bug is also perfect for use crafting local root exploits.</p>
<p>Yes, it really is that bad. Even Windows systems with Cygwin are affected. Many embedded systems use busybox rather than a full shell, so (for example) your router might be safe, but I advise that you check: See if <code>/bin/bash</code> exists and whether <code>/bin/bash --version</code> reports that it really is bash. One small silver lining is that Android phones aren’t affected unless the user has chosen to install a bash shell, so we aren’t looking at a mobile phone worm apocalypse yet.</p>
<p>Oh, and if you patched your Linux system yesterday, patch again, because <a href="https://access.redhat.com/articles/1200223">the first patch didn’t completely solve the problem</a>, and there was a second patch released this morning.</p>
<p>Apple, meanwhile, still doesn’t have a patch for their old forked version of bash. Instead, they have a statement that the issue <a href="http://www.theverge.com/2014/9/26/6848661/apple-promises-bash-bug-shellshock-fix">is not a problem for Mac users</a>, so I’m sure hackers are developing OS X exploits right now.</p>
<p>Some people have been warning about the dangers of bash scripting for years. I’ve been bash-averse for decades; in fact, I never write shell scripts unless I absolutely have to because shell in general has so many pitfalls compared to (say) Ruby.</p>
<p>Of course, I’ve still had to deal with the fallout from shellshock, but I must admit I’m chuckling about the fact that purely by chance, I decided last week was the week I would finally get to grips with using <a href="http://www.ansible.com/">Ansible</a> to push software updates to all the servers I look after.</p>
<p>Another bash basher is David Jones, who has now written about <a href="http://drj11.wordpress.com/2014/09/26/why-big-is-bad/">why bash is bad</a>, and provides some <a href="http://drj11.wordpress.com/2014/09/26/10-tips-for-turning-bash-scripts-into-portable-posix-scripts/">tips on turning your bash scripts into standard shell scripts</a>.</p>
<p>If you really must continue to use bash, use <a href="http://redsymbol.net/articles/unofficial-bash-strict-mode/">unofficial bash strict mode</a>.</p>
]]></content></entry><entry><title type="html">Why I don&amp;#39;t like systemd</title><link href="https://lpar.ATH0.com/posts/2014/05/why-i-dont-like-systemd/"/><id>https://lpar.ATH0.com/posts/2014/05/why-i-dont-like-systemd/</id><published>2014-05-18T19:35:09+00:00</published><updated>2014-05-18T19:35:09+00:00</updated><summary>I quite like journalctl and not using shell scripts, it’s the rest of it that bothers me.</summary><content type="html"><![CDATA[<p>Since a lot of <a href="http://adrian.holfter.de/blog/en/2013/05/systemd-sucks/">other</a> <a href="http://ewontfix.com/14/">people</a> <a href="http://boycottsystemd.org/">have</a> <a href="http://www.landley.net/notes.html#23-04-2014">been</a> <a href="http://wizardofbits.tumblr.com/post/45232318557/systemd-more-like-shit-stemd">writing</a> about systemd recently, I decided I’d post my own thoughts about it. Note that I jotted these notes down in late 2012, before systemd got forcibly rammed into the plans for pretty much every Linux distribution, and based on reading all Lennart’s postings about it. It’s possible that some of these issues have been addressed.</p>
<ol>
<li>
<p>With systemd, every daemon has to hand over socket handling to systemd. That means portable daemons will have two different code paths, depending on whether they’re running on Linux or not. That’s a testing and reliability headache for developers.</p>
</li>
<li>
<p>Because systemd controls the sockets, it will end up being a dependency of every daemon, unless distributions ship both systemd and non-systemd packages for all their daemons. No doubt that’s good for forcing systemd adoption, but it’s going to be a pain for everyone else.</p>
</li>
<li>
<p>Got a daemon you want to run that hasn’t been systemd-ized? Good luck with that.</p>
</li>
<li>
<p>Seriously, it’s 2012 and you’re trying to introduce a new configuration file syntax <em>modeled on Windows .INI files</em>?</p>
</li>
<li>
<p>Systemd has a deliberately undocumented binary log file format, in an attempt to replace syslog. And no, you can’t turn off systemd’s syslog replacement and use a standard syslog.</p>
</li>
<li>
<p>With systemd written in C and controlling all the TCP/IP ports, it will become a primary attack vector for crackers and malware. Because it’s the init daemon, every time a systemd security update is pushed, you’ll need to reboot. But don’t worry, I’m sure the author of PulseAudio can write the kind of bug-free code necessary for good security, right?</p>
</li>
</ol>
<hr>
<p>Regarding item 5, the document <a href="https://docs.google.com/document/pub?id=1IC9yOXj7j6cdLLxWEBAGRL6wl97tFxgjLUEHIX3MSTs&amp;pli=1">arguing in favor of systemd having its own logging system</a> gives a number of bogus reasons, so let’s go through them:</p>
<blockquote>
<p>The message data is generally not authenticated</p>
</blockquote>
<p><a href="http://www.rsyslog.com/doc/rsyslog_secure_tls.html">It can be</a> if you configure syslog that way.</p>
<blockquote>
<p>The data logged is very free-form. Automated log-analyzers need to parse human language strings to a) identify message types, and b) parse parameters from them.</p>
</blockquote>
<p><a href="http://www.rsyslog.com/tag/structured-data/">Doesn’t have to be that way</a>.</p>
<blockquote>
<p>The timestamps generally do not carry timezone information, even though some newer specifications define support for it.</p>
</blockquote>
<p>I wrote about that <a href="http://meta.ath0.com/2005/05/25/syslog-is-broken-will-someone-please-fix-it/">in 2005</a> and a fix has been available since 2010. Here’s a log line from my server:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-txt" data-lang="txt"><span class="line"><span class="cl">&lt;22&gt;1 2014-05-18T14:22:56.950703-05:00 castor postfix 3139 - -  D4F38C1317: removed
</span></span></code></pre></div><blockquote>
<p>Syslog is only one of many log systems on local machines. Separate logs are kept for utmp/wtmp, lastlog, audit, kernel logs, firmware logs, and a multitude of application-specific log formats.</p>
</blockquote>
<p>Adding systemd is not going to magically stop bad software from writing its own logs in its own format, any more than the existence of syslog did. And the fact that syslog writes to multiple separate log files rather than one huge database is a feature, not a bug.</p>
<blockquote>
<p>Reading log files is simple but very inefficient. Many key log operations have a complexity of O(n). Indexing is generally not available.</p>
</blockquote>
<p>If only you could syslog to a database… Oh, wait, <a href="http://www.rsyslog.com/doc/rsyslog_mysql.html">you can</a>.</p>
<blockquote>
<p>The syslog network protocol is very simple, but also very limited. Since it generally supports only a push transfer model, and does not employ store-and-forward, problems such as Thundering Herd or packet loss severely hamper its use.</p>
</blockquote>
<p>Whereas systemd <a href="http://www.freedesktop.org/software/systemd/man/systemd-journal-gatewayd.service.html">sends network log events over HTTP</a>, a protocol known for its reliability, efficiency and store-and-forward support?</p>
<blockquote>
<p>Log files are easily manipulable by attackers, providing easy ways to hide attack information from the administrator.</p>
</blockquote>
<p><a href="http://www.rsyslog.com/logtools-0-1-0-released/">Also fixable</a> with properly configured <a href="http://tools.ietf.org/html/rfc5848">standard syslog</a>.</p>
<blockquote>
<p>Unless manually scripted by the administrator a user either gets full access to the log files, or no access at all.</p>
</blockquote>
<p>…which is why syslog writes to multiple log files, so that access can be handled on a granular basis.</p>
<blockquote>
<p>The meta data stored for log entries is limited, and lacking key bits of information, such as service name, audit session or monotonic timestamps.</p>
</blockquote>
<p>Repetition, see above.</p>
<blockquote>
<p>Automatic rotation of log files is available, but less than ideal in most implementations: instead of watching disk usage continuously to enforce disk usage limits rotation is only attempted in fixed time intervals, thus leaving the door open to many DoS attacks.</p>
</blockquote>
<p>It’s not hard to imagine how this could be fixed by integrating rotation into syslog. In fact, there are already implementations via logging to channels.</p>
<blockquote>
<p>Compression in the log structure on disk is generally available but usually only as effect of rotation and has a negative effect on the already bad complexity behaviour of many key log operations.</p>
</blockquote>
<p>You can <a href="http://www.rsyslog.com/doc/omfile.html">log to zip files</a> if you care mostly about disk space, or log to a database if you care mostly about speed.</p>
<blockquote>
<p>Classic Syslog traditionally is not useful to handle early boot or late shutdown logging, even though recent improvements (for example in systemd) made this work.</p>
</blockquote>
<p>That’s why we have the kernel ring buffer and klogd, and then transfer those initial log records to syslog later on.</p>
<blockquote>
<p>Binary data cannot be logged, which in some cases is essential (Examples: ATA SMART blobs or SCSI sense data, firmware dumps)</p>
</blockquote>
<p>I see that as a feature. You log the binary blob as-is in a directory, then log its name and the other metadata in the syslog.</p>
<p>Basically, I don’t see any functionality in systemd’s journal that necessitates replacing syslog.</p>
]]></content></entry><entry><title type="html">Teletext and hypertext</title><link href="https://lpar.ATH0.com/posts/2014/05/teletext-and-hypertext/"/><id>https://lpar.ATH0.com/posts/2014/05/teletext-and-hypertext/</id><published>2014-05-06T20:16:32+00:00</published><updated>2014-05-06T20:16:32+00:00</updated><summary>The web before the web.</summary><content type="html"><![CDATA[<p>Before the web, we had <a href="http://www.markcarver.plus.com/Teletext/Photographs.html">Teletext</a>.</p>
<p>
  <img src="/img/2014/teletext.jpg" alt="Teletext">

</p>
<p>As a child growing up with a home computer, I was fascinated by Teletext. Unfortunately, we didn’t have a TV with a Teletext decoder, as those were pretty pricey. My only chance to enjoy real Teletext was when visiting relatives. However, I had a BBC Computer, which had a Teletext mode known as <a href="http://www.bbcbasic.co.uk/bbcwin/manual/bbcwinh.html">Mode 7</a>.</p>
<p>
  <img src="/img/2014/300px-BBC_Micro_Front_Restored.jpg" alt="BBC Micro">

</p>
<p>In Mode 7, you could put a control character at a particular point on the screen, and all character cells to the right of that cell would display block graphics in a particular color when filled with a character code 160 or higher. Each character cell was split into 6 pixels, for 64 possible combinations represented by characters 160 to 255. Something similar exists today in the form of the <a href="http://www.bbcbasic.co.uk/bbcwin/manual/bbcwinh.html">Unicode block-drawing characters</a>.</p>
<p>The Mode 7 screen was 40×25, so your maximum graphical resolution was 78×75, with the left column of cells being used up switching on graphics mode. Even for the 1980s that was pretty awful, but it had the benefit that an entire screen of text was only 1000 bytes. On a system with just 32K of memory in total, where video RAM was taken out of total system RAM, that was a major benefit. Plus, it meant you could fit 100 pages on a floppy disk!</p>
<p>As well as the poor resolution, there were obviously limits on which colors could be next to other colors, and how complicated your shapes could be. But the biggest problem was that working out which character codes you needed to (say) draw a box on the screen was a major pain. So in 1984 I wrote a teletext graphics editor which would allow me to create my own Teletext pages, with an easier way to draw lines and shapes and select colors. It also eventually supported automatic generation of banner text, text written in pixels. (Which, because the pixels were so big, was huge.)</p>
<p>I shared the program with friends at school, where we had a lab of BBC Micros. I also sent a copy to Personal Computer World magazine (PCW), who (to my surprise) published it. (This was back in the days when computer magazines printed listings in BASIC which readers would type in for themselves, and also back in the days when PCW wasn’t all IBM PCs all the time.)</p>
<p>Encouraged by my unexpected success, I went on to develop my own network-aware Teletext information system for the school. Users could create as many pages as they wanted, stored in their network filespace. (An Amcom E-net system with a hard disk.) Each page could link to other pages by username and page number. You could select page links using cursor keys then hit a key to go to that page. It was basically a primitive multi-user hypertext system, like the web — but in 1985, 5 years before the first web browser. I had been inspired by reading about Ted Nelson’s <a href="http://en.wikipedia.org/wiki/Hypertext_Editing_System">IBM and Brown University hypertext project of the 1960s</a>, so I don’t claim any genius level originality; hypertext was something that was going to happen, we were just waiting for networks to get good enough.</p>
<p>I didn’t stop with text and graphics, though. I extended the system to allow downloadable executable code, so you could use it to build a hypertextual menu of educational software which you could launch right from the menu screens.</p>
<p>For some reason, nobody else at school was as excited by the possibilities as I was. Eventually I got an Atari ST, went to university, and started building hypertext systems on Unix. The code for my network teletext system is long lost at this point. I don’t even have the floppy disks. I wish I had kept them, if for no other reason than to provide examples of prior art to fight patent trolls.</p>
<p>I finally got my own Teletext TV in 1990, and enjoyed it for a few years before emigrating to a country that had apparently never heard of anything that advanced.</p>
<p>For more examples of Teletext pages, see <a href="http://teletext.mb21.co.uk/gallery/ceefax/main1.shtml">the Teletext museum</a>. It’s now being rediscovered <a href="http://www.fixc.fi/itaf/">as an artistic medium</a>.</p>
]]></content></entry><entry><title type="html">The myth of the totem pole</title><link href="https://lpar.ATH0.com/posts/2014/04/the-myth-of-the-totem-pole/"/><id>https://lpar.ATH0.com/posts/2014/04/the-myth-of-the-totem-pole/</id><published>2014-04-16T15:45:08+00:00</published><updated>2014-04-16T15:45:08+00:00</updated><summary>Developers are not at the top of a usefulness hierachy.</summary><content type="html"><![CDATA[<p>In <a href="http://jeffknupp.com/blog/2014/04/15/how-devops-is-killing-the-developer/">a widely-linked blog post ranting about devops</a>, Jeff Knupp writes:</p>
<blockquote>
<p>I know I’m going to get a ton of hate mail, but there <em>is</em> a hierarchy of usefulness of technology roles in an organization. Developer is at the top, followed by sysadmin and DBA. QA teams, “operations” people, release coordinators and the like are at the bottom of the totem pole. Why is it arranged like this?</p>
<p><strong>Because each role can do the job of all roles below it if necessary.</strong></p>
</blockquote>
<p>This is, sadly, not the case.</p>
<p>I’ve known plenty of people who could crank out code, but who couldn’t maintain a stable and secure production environment to save their lives. In fact, earlier this year I got pulled in to fix up the security issues on a production system that had been installed and maintained by developers until flags were raised about its dozens of gaping security holes. Anyone who can write Java code in Eclipse on Windows can obviously set up a secure production Linux server with a J2EE stack, right? Wrong.</p>
<p>Similarly, managing a release requires project management skills which many developers simply do not have, not to mention some everyday human interaction skills which many of them have somehow managed not to develop. Even making sure the technical issues get dealt with can be a problem for developers. At one company I worked for, one of the development teams had been doing their own release management. It was eventually discovered that there was only one desktop PC that could actually assemble a release build of the company’s main product. Perhaps the developers theoretically <em>could</em> have implemented a system that allowed repeatable builds to be triggered on any machine, or at least documented the required build environment, but it didn’t look that way. Whether they lacked the skills or simply didn’t value the task — or quite possibly both — the outcome was the same, a disaster waiting to happen.</p>
<p>Then there’s QA. Developers love to view them as basically trained apes banging randomly on keyboards until something breaks, but testing software <em>well</em> requires a kind of malicious naïvety and inventiveness. You have to learn to think like an end user who knows nothing about the internals of the system. That’s a hard trick to pull off if you wrote it, which is why no matter how much you test your code yourself, someone will always find an ‘obvious’ and embarrassing bug.</p>
<p>More generally, the ’totem pole’ idea reflects a common geek mindset: “Anything I haven’t studied and don’t want to do, must obviously be trivial.” Ask mathematicians what they think of physicists, ask physicists what they think of chemists, and then ask chemists what they think of mathematicians.</p>
<p>I’ve found that most things get more and more complicated and interesting the more you examine them. I know next to nothing about sports, for example, but I know that there are people who spend hours on statistical analyses, tactical studies, research into biochemistry and sports medicine, the engineering of sporting equipment, and so on.</p>
<p>So if you’re inclined to think of documentation as pointless time-wasting anyone could do, or you think that product management is trivial, try studying them a bit. You might be surprised.</p>
<p>Yes, even marketing.</p>
]]></content></entry><entry><title type="html">Java file I/O in 2014</title><link href="https://lpar.ATH0.com/posts/2014/03/java-file-io-in-2014/"/><id>https://lpar.ATH0.com/posts/2014/03/java-file-io-in-2014/</id><published>2014-03-11T14:08:02+00:00</published><updated>2014-03-11T14:08:02+00:00</updated><summary>NIO vs legacy I/O.</summary><content type="html"><![CDATA[<p>There are lots of articles about file handling in Java. However, a lot of them seem to be out-of-date, given the advent of New IO (NIO) and the enhancements in Java 1.7. So, I sat down with the J2SE 7 JavaDoc, and put together this guide to how to do modern Java file I/O.</p>
<h2 id="step-0">Step 0</h2>
<p>Before you start dealing with file streams, see if Java NIO will do all the work for you. If you just need to read the lines of text from the file into memory, the <code>Files</code> class has a convenience method <code>readAllLines()</code> that will do the job as a one-liner.</p>
<p>If you need to do something more complicated, like obtain a file data stream you can parse to a parser, or parse files that might be bigger than available memory, then continue on…</p>
<h2 id="step-1">Step 1</h2>
<p>Decide whether you want file input, file output, or files you can both read and write.</p>
<p>If you want input or output, you also have to decide whether you want the files to be binary data or text.</p>
<table>
	<thead>
			<tr>
					<th>Direction</th>
					<th>Type</th>
					<th>What to obtain</th>
					<th>How to obtain it</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td>Input</td>
					<td>Binary</td>
					<td><code>InputStream</code></td>
					<td><code>Files.newInputStream(Path)</code></td>
			</tr>
			<tr>
					<td>Input</td>
					<td>Text</td>
					<td><code>Reader</code></td>
					<td><code>Files.newBufferedReader(Path)</code></td>
			</tr>
			<tr>
					<td>Output</td>
					<td>Binary</td>
					<td><code>OutputStream</code></td>
					<td><code>Files.newOutputStream(Path)</code></td>
			</tr>
			<tr>
					<td>Output</td>
					<td>Text</td>
					<td><code>Writer</code></td>
					<td><code>Files.newBufferedWriter(Path)</code></td>
			</tr>
			<tr>
					<td>Both</td>
					<td>Binary</td>
					<td><code>SeekableByteChannel</code></td>
					<td><code>Files.newByteChannel(Path, ...)</code></td>
			</tr>
	</tbody>
</table>
<p>These are the NIO (new IO) methods for Java 1.7, and they all take Path objects as arguments. To get a Path object for a file:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="line"><span class="cl"><span class="n">Path</span><span class="w"> </span><span class="n">path</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">FileSystems</span><span class="p">.</span><span class="na">getDefault</span><span class="p">().</span><span class="na">getPath</span><span class="p">(</span><span class="s">&#34;file.txt&#34;</span><span class="p">);</span><span class="w">
</span></span></span></code></pre></div><p>So your code would look like:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="line"><span class="cl"><span class="n">Path</span><span class="w"> </span><span class="n">path</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">FileSystems</span><span class="p">.</span><span class="na">getDefault</span><span class="p">().</span><span class="na">getPath</span><span class="p">(</span><span class="s">&#34;file.txt&#34;</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="n">Reader</span><span class="w"> </span><span class="n">rdr</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Files</span><span class="p">.</span><span class="na">newBufferedReader</span><span class="p">(</span><span class="n">path</span><span class="p">);</span><span class="w">
</span></span></span></code></pre></div><p>Note use of the abstract <code>Reader</code> class. The object will actually be a <code>BufferedReader</code> wrapping a <code>FileReader</code> wrapping an <code>InputStream</code>, but by using just the abstract type the code can be reused with any kind of reader.</p>
<p>You can also use the older Java I/O classes, which are your only choice for Java older than 1.7:</p>
<table>
	<thead>
			<tr>
					<th>Direction</th>
					<th>Type</th>
					<th>What to obtain</th>
					<th>How to obtain it</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td>Input</td>
					<td>Binary</td>
					<td><code>InputStream</code></td>
					<td><code>new InputStream(File)</code></td>
			</tr>
			<tr>
					<td>Input</td>
					<td>Text</td>
					<td><code>Reader</code></td>
					<td><code>new BufferedReader(new InputStreamReader(new InputStream(File)))</code></td>
			</tr>
			<tr>
					<td>Output</td>
					<td>Binary</td>
					<td><code>OutputStream</code></td>
					<td><code>new OutputStream(File)</code></td>
			</tr>
			<tr>
					<td>Output</td>
					<td>Text</td>
					<td><code>Writer</code></td>
					<td><code>new BufferedWriter(new OutputStreamWriter(new OutputStream(File)))</code></td>
			</tr>
			<tr>
					<td>Both</td>
					<td>Binary</td>
					<td><code>RandomAccessFile</code></td>
					<td><code>new RandomAccessFile(File)</code></td>
			</tr>
	</tbody>
</table>
<p>For the older I/O classes, you need a <code>File</code> object. If you’re using a current version of Java, you can turn a <code>Path</code> object into a file object by calling its <code>getFile()</code> method. Or for any version of Java, you can construct a <code>File</code> object from a path string via its normal constructor.</p>
<p>As you might have noticed, getting <code>Reader</code> and <code>Writer</code> objects in old I/O is a pain. You might be tempted to use the <code>FileReader</code> and <code>FileWriter</code> classes, which make it convenient to go straight from a <code>File</code> to a <code>Reader</code> or <code>Writer</code>. Unfortunately, <code>FileReader</code> and <code>FileWriter</code> use the default character encoding for the Java platform; and sadly, that’s the legacy UTF-16 encoding, which is almost certainly <em>not</em> what you want unless you’re running Windows, and <a href="http://www.utf8everywhere.org/">possibly not even then</a>. Yes, you can change the encoding, but that requires a command-line argument to the Java VM at run time, which is ugly.</p>
<h2 id="step-2-buffering">Step 2: Buffering</h2>
<p>If you have a SeekableByteChannel or RandomAccessFile, it’s going to be binary and unbuffered and rather inconvenient, so you can stop reading at this point.</p>
<p>If you have a binary <code>InputStream</code> or <code>OutputStream</code> at this point, decide if you want buffering for your binary data.</p>
<p>If you do, wrap your Stream in a <code>BufferedOutputStream</code> or <code>BufferedInputStream</code> as appropriate.</p>
<p>If you have a text <code>Reader</code> or <code>Writer</code>, Java NIO will have automatically given you a buffered one. That’s the right decision, so I included the buffering in the old I/O table for step 1. You really <em>don’t</em> want to do unbuffered text I/O, particularly not with UTF-8 text.</p>
<h2 id="step-3-convenience">Step 3: Convenience</h2>
<p>If you have a <code>Writer</code>, you’ll probably want to wrap it in a <code>PrintWriter</code> to make life easier.</p>
<p>If you have a <code>Reader</code>, you’ll probably want to parse the input in some way. I recommend investigating the <code>Scanner</code> class.</p>
<h2 id="things-to-avoid">Things to avoid</h2>
<p>Here’s a list of some I/O classes to avoid using, why you should avoid them, and what to use instead:</p>
<table>
	<thead>
			<tr>
					<th>Class</th>
					<th>Why you shouldn’t use it</th>
					<th>What to use instead</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td>StringBufferInputStream</td>
					<td>It doesn’t convert characters properly.</td>
					<td>StringReader</td>
			</tr>
			<tr>
					<td>LineNumberInputStream</td>
					<td>It doesn’t convert characters properly.</td>
					<td>LineNumberReader</td>
			</tr>
			<tr>
					<td>FileReader</td>
					<td>It reads UTF-16.</td>
					<td>InputStreamReader</td>
			</tr>
			<tr>
					<td>FileWriter</td>
					<td>It writes UTF-16.</td>
					<td>OutputStreamWriter</td>
			</tr>
	</tbody>
</table>
]]></content></entry><entry><title type="html">Thoughts on unit testing</title><link href="https://lpar.ATH0.com/posts/2014/03/thoughts-on-unit-testing/"/><id>https://lpar.ATH0.com/posts/2014/03/thoughts-on-unit-testing/</id><published>2014-03-07T19:46:02+00:00</published><updated>2014-03-07T19:46:02+00:00</updated><summary>Sometimes it’s great, but it’s not a panacea.</summary><content type="html"><![CDATA[<p>Controversial paper: <a href="http://www.rbcs-us.com/documents/Why-Most-Unit-Testing-is-Waste.pdf">Why Most Unit Testing Is Waste</a>.</p>
<p>I’m not sure I’d go that far, but I will confess that I don’t write unit tests for all, or even <em>most</em> of my code. My view is that there are certain problem domains that are complicated, or where programmers are highly prone to error. Off the top of my head, some examples:</p>
<ul>
<li>Anything involving date and time arithmetic.</li>
<li>Anything involving cryptography.</li>
<li>Anything involving manual memory allocation.</li>
<li>Anything involving threads.</li>
<li>Code to validate human data input.</li>
<li>APIs someone else is going to use.</li>
<li>Code which it will be expensive to change.</li>
<li>Anything involving real money transactions.</li>
</ul>
<p>That’s definitely not an exhaustive list. But if you’re writing code that does something on that list, then I think you absolutely should have bunch of unit tests. In fact, just this week I wrote a couple of methods for performing some date calculations in Java, and thoroughly unit-tested them with as many pathological examples as I could find on the calendar.</p>
<p>But in big companies, a lot of code is fairly mundane manipulation of data, and much of it is written to tight commercial constraints—meaning the company needs it done quickly, ideally yesterday. I tend to find that in those circumstances, the extra time spent to write code cleanly is a clear win — especially once the throwaway code becomes a permanent mission-critical system. The extra time to unit test everything, on the other hand, doesn’t really stand up to cost/benefit analysis.</p>
]]></content></entry><entry><title type="html">Sometimes old technology is the best option</title><link href="https://lpar.ATH0.com/posts/2013/09/sometimes-old-technology-is-the-best-option/"/><id>https://lpar.ATH0.com/posts/2013/09/sometimes-old-technology-is-the-best-option/</id><published>2013-09-23T20:05:27+00:00</published><updated>2013-09-23T20:05:27+00:00</updated><summary>UUCP!</summary><content type="html"><![CDATA[<p>A while back, I had an interesting problem to solve. We have a set of servers on their own TCP/IP network, with addresses in the 10.0.0.0/8 private IPv4 space; it’s colloquially referred to as “the 10 network”. It’s cut off from the main corporate network; you generally need to use a VPN client to access it. It’s possible to get SSH connections enabled by special request, but only from the corporate network to the private network, only to unprivileged IDs, only between static IP addresses, and definitely not for any non-SSH protocol.</p>
<p>We needed to be able to send e-mail from the private network, via the corporate e-mail servers. I could set up an SMTP server on the 10 network easily enough, but there was no way it could initiate a connection to any other SMTP server. We couldn’t even initiate an SMTP connection <em>inbound</em> to it.</p>
<p>Colleagues suggested schemes involving POP3 or IMAP to pull down mail and re-send it. There was discussion whether we would be allowed to use a scripted SSH connection from a system running the VPN software, to trigger a temporary port tunnel and then prod the MTA to attempt delivery. However, I had a better idea, because I remembered how e-mail had been delivered in the 1970s through to the early 1990s, when all we had was dial-up connections.</p>
<p>The software in question is called <a href="http://en.wikipedia.org/wiki/UUCP">UUCP</a>, the Unix to Unix Copy Protocol. The great thing about UUCP is that all it needs is a way to send and receive bytes via a terminal-type connection. In fact, it doesn’t even need that; back when UUCP was in common use, there were quite a few networks or modems that only supported 7-bit data, so UUCP can escape data to make it work over 7-bit links too. UUCP also doesn’t need the connection to be reliable, or even there all the time—it can be triggered to perform data transfers in batch mode, then shut down.</p>
<p>I vaguely remembered that the free software <a href="http://www.airs.com/ian/uucp.html">Taylor UUCP</a> had been given some sort of SSH support. Investigation revealed that <a href="http://airs.com/ian/uucp-doc/uucp_7.html#SEC99">protocol t</a> was aimed at TCP/IP connections, where you can assume that the bytes you send will be received accurately at the other end. (Unless, of course, the entire connection fails for some reason, in which case UUCP will detect the problem and retry later.)</p>
<p>Taylor UUCP was still available prepackaged for RHEL, and Postfix still had all the hooks for UUCP support available. I set up the two servers, one on the corporate network and one on the 10 network. The corporate machine had been set up to allow SSH (and only SSH) connections to the 10 network. I set things up so that UUCP ran chrooted under a restricted ID, and I was also able to set the 10 network server’s UUCP user to have <code>uucico</code> as login shell—so even if the ID is compromised, it can’t be used to attack either server.</p>
<p>So now Postfix accepts mail from machines on the isolated network, and passes it to UUCP. UUCP turns the mail into UUCP jobs, and queues them. A few times an hour, a cron job on the the internal network machine starts up <code>uucico</code>, which calls SSH to open a connection to the <code>uucico</code> on the isolated server. They then exchange all the pending UUCP jobs—bidirectionally—and disconnect. Finally, UUCP on both servers processes the batches it just received, and passes the e-mail on to Postfix. And all without even any port forwarding.</p>
<p>It’s worth mentioning that you could go a step further, and not even allow the SSH connection, if you ran a serial cable between the two servers. IBM Notes still supports serial connections too, allowing secure e-mail between machines that can’t route TCP/IP packets.</p>
<p>So if you ever find yourself in a similar bind because of firewall issues or corporate security policies, remember that we used to transfer files and send e-mail before there were even TCP/IP networks to firewall. There are tutorials for <a href="http://www.onlamp.com/pub/a/bsd/2005/03/10/uucpmail.html">how to set up UUCP over SSH</a>, and unlike any port forwarding kludge you’re likely to come up with, UUCP is time-tested software. It may be a little arcane, but it works.</p>
]]></content></entry><entry><title type="html">The x86</title><link href="https://lpar.ATH0.com/posts/2013/04/the-x86/"/><id>https://lpar.ATH0.com/posts/2013/04/the-x86/</id><published>2013-04-03T19:07:52+00:00</published><updated>2013-04-03T19:07:52+00:00</updated><summary>The design Intel keeps trying to get rid of.</summary><content type="html"><![CDATA[<p>Did you know that the desktop or laptop computer you use is almost certainly based on the design of a dumb terminal? Let me tell you the story…</p>
<p>But first, a disclaimer: As with everything else on my web site, this represents my opinion, not IBM’s. I’ve done my best to be accurate, but inevitably I’ve had to skate over details here and there. You’re encouraged to follow the links and read more!</p>
<p>So, once upon a time, over 40 years ago, computers filled rooms, and everyone used <a href="http://en.wikipedia.org/wiki/Computer_terminal">dumb terminals</a> for their computer access. These terminals were expensive to manufacture, being built from discrete components. They had complicated decoding logic which had gradually grown over the years, as the computers they were connected to had gained more features.</p>
<p>In those days, the basic unit of computation wasn’t necessarily an 8 bit byte. The popular <a href="http://en.wikipedia.org/wiki/PDP-8">PDP-8</a> used 12-bit words, with 7-bit ASCII characters that always had the 8th bit set to 1. The <a href="http://en.wikipedia.org/wiki/IBM_System/360">IBM System/360</a> used 8 bit bytes, but in the <a href="http://en.wikipedia.org/wiki/EBCDIC">EBCDIC</a> character set. Older IBM systems used 6-bit <a href="http://en.wikipedia.org/wiki/Binary-coded_decimal">BCD coding</a>, based on punched cards. The <a href="http://en.wikipedia.org/wiki/CDC_Cyber">CDC Cyber</a> range of mainframes used 12-bit bytes and 60-bit words, but 6-bit characters in CDC’s own <a href="http://en.wikipedia.org/wiki/Display_code">display code</a>. And each manufacturer had its own set of control codes for moving the cursor around the screen.</p>
<p>Because of all this variation, the Computer Terminal Corporation (CTC) decided to build a universal terminal which would have its own internal instruction set. You would then be able to load in a tape which would map from your choice of proprietary terminal control codes to the terminal’s internal set. In other words, it was going to be a hardware computer designed for running terminal emulators. It was to be called the <a href="http://en.wikipedia.org/wiki/Datapoint_2200">Datapoint 2200</a>.</p>
<p>This programmable terminal was designed to have a processor built from individual <a href="http://en.wikipedia.org/wiki/Transistor-transistor_logic">TTL components</a> — small ICs with typically a dozen or so transistors on them, at most a few hundred. The most popular TTL chips were (and still are) the Texas Instruments (TI) <a href="http://en.wikipedia.org/wiki/7400_series">7400 series</a>. But because of the number of components needed, the Datapoint 2200 was going to be expensive to build, heavy, and would need fans to keep all the circuit boards cool. Previous CTC terminals had suffered from major overheating problems.</p>
<p>In the early 1970s <a href="http://en.wikipedia.org/wiki/Integrated_circuit">integrated circuits</a> based on Large Scale Integration (LSI) were becoming commercially available. These new chips had thousands of transistors on them, allowing an entire circuit board of components to be condensed into a single chip. So CTC approached a startup company that was designing LSI microchips, and asked them if they could replace the two circuit boards of the Datapoint 2200’s processor design with a single chip.</p>
<p>That startup company was called Intel. They initially mostly made memory chips, but in 1971 they launched the first CPU on a chip, the 4-bit <a href="http://en.wikipedia.org/wiki/Intel_4004">Intel 4004</a>, which they had built for a Japanese company that used it to build desktop calculators.</p>
<p>A year later, Intel finished taking the 100 or so chips for the 2200 terminal emulator’s processor and condensing them down to a single IC design known as the 1201. TI manufactured some samples. The new chip wasn’t any good; the instruction set was buggy. Intel were convinced they could fix the bugs, but CTC weren’t prepared to wait, and launched the 2200 using the full-size CPU circuit boards instead.</p>
<p>Nevertheless, Intel had the 4004’s designer work on the 1201. The bugs were fixed, and the result was delivered to CTC in 1972. But by that time, CTC had upgraded their terminal design to a new model with a built-in hard disk drive, and the Intel chip wasn’t powerful enough to handle that. CTC decided to cancel the contract with Intel and walk away from the deal.</p>
<p>Intel decided to take the fixed 1201, rename it the 8008, and see if they could get anyone to buy it. A team at California State University Sacramento did, and built a small microcomputer around it, complete with BASIC language interpreter. Before long, a couple of commercial 8-bit personal computers were on sale with the Intel 8008 inside.</p>
<p>Based on the feedback from 8008 users, Intel added some new instructions which provided a way to use two 8-bit registers together as if they were a 16-bit register. They also expanded the stack pointer and program counter to 16-bit, allowing up to a 64K of RAM. Though it seems comical now, it was a huge amount at the time; in those days, an IBM mainframe only had 8K or 16K of high-speed storage, and the PDP-11 that UNIX was developed on only had 24K of RAM.</p>
<p>The new expanded 8008 was launched as the <a href="http://en.wikipedia.org/wiki/Intel_8080">Intel 8080</a>. It was used for a number of early personal computers, particularly the <a href="http://en.wikipedia.org/wiki/Altair_8800">Altair 8800</a> which was sold as a kit through ads in electronics hobbyist magazines.</p>
<p>However, by 1976, Intel had competition. Federico Faggin, the technical genius who had led the project to fix the Intel 1201, had left Intel to form his own company, Zilog. They launched a CPU called the <a href="http://en.wikipedia.org/wiki/Zilog_Z80">Z-80</a>, cunningly designed to be backward compatible with Intel 8080 code. It had more instructions and registers than the 8080, to make programming easier; it even had two separate sets of registers you could swap between. It required fewer support components than Intel’s chip, and became wildly popular. The Z-80 was used in the Tandy <a href="http://en.wikipedia.org/wiki/TRS-80">TRS-80</a>, launched in 1977, the first popular pre-built personal computer to be available in malls across America. (The Z-80 also later became part of the Sinclair ZX80, ZX81 and Spectrum computers.)</p>
<p>Meanwhile, Motorola had designed a minimalist 8-bit processor called the 6800, targeted at computer peripherals, test equipment, and terminals. A Motorola engineer named Chuck Peddle left the company and helped found MOS Technology; there, he designed an enhanced chip compatible with the 6800 instruction set. It was a radical, minimalist design for a general purpose computer, having a tiny instruction set and a mere 3 registers (compared to the 7 available on the 8080 and the two sets of 8 general purpose registers found in the Z-80). The new MOS CPU was known as the 6502. Its lean design meant that it could be manufactured and sold for a fraction of the price of any Intel processor; it launched for just $25, while the 8080 had launched at $360. The 6502 became the basis of the Apple II, BBC Micro, Atari 2600, Nintendo NES, Commodore VIC-20, Commodore 64, and many other home computers of the late 70s and early 80s. It has since come to be viewed as perhaps the first <a href="http://en.wikipedia.org/wiki/Reduced_instruction_set_computing">RISC</a> design.</p>
<p>Intel were forced to fight back. They started designing the <a href="http://en.wikipedia.org/wiki/IAPX_432">Intel iAPX 432</a>, which would be their first 32 bit computer, and would ensure their technological dominance during the 1980s. It would be programmed in the US DoD-approved language of the future — <a href="http://en.wikipedia.org/wiki/Ada_%28programming_language%29">Ada</a>. It would even have built-in support for object-oriented programming.</p>
<p>In the mean time, Intel needed a stopgap solution to claw back some market share. They launched the 8085, which was an 8080 that needed fewer support components — it could talk directly to RAM chips and only needed a single voltage power supply. It wasn’t a big hit, though; it was pricey, and was only ever used in a few models of computer. However, one of those computers was the <a href="http://www-03.ibm.com/ibm/history/exhibits/pc/pc_9.html">IBM System/23 Datamaster</a>.</p>
<p>IBM had noticed businesses starting to use Apple II and TRS-80 computers for word processing, spreadsheets, and other business tasks. The microcomputers were starting to make it harder to sell IBM mainframes. In response, the company developed a series of standalone desktop business computers. The <a href="http://www-03.ibm.com/ibm/history/exhibits/pc/pc_3.html">IBM 5100</a> for scientists, the <a href="http://www-03.ibm.com/ibm/history/exhibits/pc/pc_4.html">IBM 5110</a> for handling accounting and ledgers, and the <a href="http://www-03.ibm.com/ibm/history/exhibits/pc/pc_8.html">IBM Displaywriter</a> for word processing.</p>
<p>This strategy of single-purpose computers was of limited success. Small businesses would have a hard time justifying purchase of a $10,000 IBM 5110 and a $7,800 Displaywriter when they could buy a TRS-80 for $2,500 and use it for both word processing <em>and</em> accounting. IBM realized it needed something a little more general purpose, but at the same time it didn’t want to launch anything that might destroy sales of high-end workstations or mainframes. The Intel 8085 seemed like a good choice of CPU; it was basically the guts of a souped-up dumb terminal, and was already inferior to the Z-80. It became the guts of the <a href="http://www-03.ibm.com/ibm/history/exhibits/pc/pc_9.html">System/23 Datamaster</a>, which offered both word processing and accounting at a new low price of $9,830 (including printer).</p>
<p>The Datamaster was IBM’s cheapest business computer ever, but it still failed to compete with the early 1980s home computers which were being repurposed as business machines. IBM decided it needed to compete directly with the likes of the TRS-80 Model III and Apple II Plus. A team was assembled to design and build an IBM PC.</p>
<p>Meanwhile, Intel had been having trouble with the iAPX 432. As a temporary stopgap measure, they put together another 8000 series CPU aimed at stealing back business from Zilog. While it was a ground-up redesign, Intel made it back-compatible with source code for the 8008, 8080 or 8085, so if you needed to you could reassemble your assembly language source code for your 8008 and run it on the new chip, called the <a href="http://en.wikipedia.org/wiki/Intel_8086">8086</a>. Unlike the 8085, though, it had a proper 16 bit mode, and new instructions designed to help with implementation of modern (for the time) programming languages like Pascal. The basic design of the 8086 was thrown together in about 3 months, and in production just over 2 years later.</p>
<p>By this time, Z-80 based <a href="http://en.wikipedia.org/wiki/CP/M">CP/M</a> had become the OS of choice for serious business computing. It was the first OS to provide a certain amount of cross-platform compatibility; you could run CP/M applications like Wordstar or dBase on a TRS-80, a MITS Altair, a DEC, an Apple II with a <a href="http://en.wikipedia.org/wiki/Z-80_SoftCard">Z-80 card</a> added to it, or even the revolutionary <a href="http://en.wikipedia.org/wiki/Osborne_1">Osbourne 1</a> portable computer.</p>
<p>At IBM, the PC team considered using IBM’s new RISC CPU, the 801. However, it was considered a mainframe-class processor, and using it what was intended to be a cheap personal computer would have raised political and technical hurdles. Some of the team had worked on the Datamaster, so the Intel 8000-series CPUs were familiar to them. The 8086 was squarely aimed at the Z-80, which meant it ought to be easy to get CP/M ported to it. It was so slow that it couldn’t possibly compete with IBM’s more expensive business systems. Best of all, IBM had already licensed the option of making 8086 chips itself.</p>
<p>The 8086-based IBM PC was to launch in 1981. Negotiations to have CP/M ready at launch hadn’t gone well. IBM’s CEO at the time was John Opel, who was on the board of United Way of America with <a href="http://en.wikipedia.org/wiki/Mary_Maxwell_Gates">Mary Gates</a>. Mary apparently mentioned that her son Bill wrote microcomputer software; at the time, he was selling Microsoft BASIC to hobbyists. IBM asked Microsoft if they could supply an operating system similar to CP/M but for an 8086-based computer.</p>
<p>Microsoft didn’t have anything like that. So Bill Gates said yes, and then he and Paul Allen shopped around and eventually bought all rights to an unauthorized CP/M clone called <a href="http://en.wikipedia.org/wiki/86-DOS">86-DOS</a> from Seattle Computer Products, for $50,000. 86-DOS was quickly renamed MS-DOS. It was sold on a per-copy basis to IBM and shipped with the IBM PC as PC-DOS, but Microsoft made sure the contract was non-exclusive so they could sell it to other companies as well, at $50 per copy.</p>
<p>In the meantime, Intel had continued with its stopgap attempts to compete with the Z-80, and had produced a cut-down version of the 8086, called the 8088. It had the same registers and address space, but moved all the data across an 8-bit bus like the Z-80, instead of a 16-bit bus. This meant performance was worse, but you needed even less in the way of support circuits. The IBM PC eventually shipped with the 8088 inside.</p>
<p>A couple of years later, Intel’s iAPX was finally ready. It was so complicated that it wouldn’t fit on a single chip using the technology available at the time, so it was shipped on two separate chips — one to fetch and decode the instructions, and a second one to execute them. It was substantially slower than the Motorola 68000, launched four years earlier, and PCs started to appear based on the 68000.</p>
<p>Intel threw out the iAPX design, and went back to the 8086. They added a new way of handling memory addresses, so that it could deal with up to 16MB of RAM; however, it also had an 8086-compatible mode so you could keep running your DOS programs. The new 80286 also had memory protection options, and doubled the number of instructions executed per clock cycle. It used twice as many transistors as the 8086, and could barely be squeezed on a single IC, but it was faster than the iAPX, and was used in the <a href="http://en.wikipedia.org/wiki/IBM_Personal_Computer/AT">IBM Personal Computer/AT</a> — the AT standing for Advanced Technology.</p>
<p>It was only advanced for a few months, though. Later in 1984 the Macintosh launched, closely followed in 1985 by the Amiga and Atari ST. All three used the Motorola 68000, and all three made the text-based IBM PC look like a dumb terminal. Throwing high resolution graphics around would require a lot more RAM, so Intel expanded the 8086 design again, to a full 32 bit design that could compete with the 68000 series. This was called the 80386.</p>
<p>Of course, Intel knew it couldn’t keep bolting more features on the 8086 forever, so in 1984 it started designing <em>two</em> new RISC CPUs, called the i860 and i960. This time, the i960 would be the do-everything high end design aimed at government and military applications — and still to be programmed in the language of the future, Ada — and the i860, which would be a more manageable general purpose RISC CPU for desktop computers.</p>
<p>In the mean time, Motorola had launched the 68030, a full 32 bit CPU with all the memory protection and other features of the 80386. It started to appear in UNIX workstations like the NeXT cube, as well as the Macintosh and Amiga. Intel needed to compete, so in 1989 they launched both the new i860, and the 80486.</p>
<p>The 80486 added high speed on-chip cache like the 68030. Also like the 68030, it had a dedicated on-chip floating point processor. It was quickly incorporated into PC designs, while the i860 was quietly ignored.</p>
<p>At this point, Intel realized that the DOS and Windows based PC industry wasn’t going to be willing to migrate to a whole new architecture. So they set out to build a completely new CPU from the ground up — but one that would still be able to run legacy 8086 software.</p>
<p>Meanwhile, AMD had produced a chip that was code-compatible with the 80386. Unfortunately for Intel, the AMD <a href="http://en.wikipedia.org/wiki/Am386">Am386</a> was also faster than the 80386, and almost as fast as the 80486 because of its use of instruction pipelining and internal cache. It ran hot compared to Intel’s processor, but customers just put more fans in their computers.</p>
<p>For the next decade or so, Intel and AMD engaged in a technological battle. The Pentium, Pentium Pro, Pentium II and Pentium III were released, all based on <a href="http://en.wikipedia.org/wiki/P5_%28microarchitecture%29">adding incremental improvements to the old 80486 design</a> and <a href="http://en.wikipedia.org/wiki/P6_%28microarchitecture%29">building from there</a>. So the 80486 became the P5 microarchitecture, which became the P6 microarchitecture of the Pentium Pro.</p>
<p>But Intel still wanted a new, clean chip design. So in the late 90s, they started working on a new ground-up chip design called <a href="http://en.wikipedia.org/wiki/NetBurst_%28microarchitecture%29">NetBurst</a>. They went crazy with the pipelining and cache. Also, because people tended to evaluate competing PCs based on their CPU speed in MHz or GHz, Intel designed the new Pentium 4 so that they would eventually be able to up the clock speed to 10GHz.</p>
<p>At the same time, IBM’s POWER architecture and Sun’s SPARC were carving up the high-end server and workstation market. Intel again felt it needed something to compete. i860 had failed, so another new RISC project was started. The result was called Itanium, a true 64-bit CPU. It would even <a href="http://www.adacore.com/2002/04/30/adacore-awarded-hp-contract-for-porting-ada-toolset-to-hp-openvms-for-itanium-2/">support the language of the future</a> — Ada. This time, Microsoft was on board, and would port Windows to run on Itanium. Everyone was agreed that it would utterly destroy POWER and SPARC.</p>
<p>Pentium 4 launched in 2000 with saturation advertising. It soon seemed as though the “bing bong” Pentium jingle was a mandatory part of every TV ad break. Of course, the chips were much more expensive than AMD’s offerings — after all, someone has to pay for all that advertising — but the strategy seemed to work. People didn’t even notice that the Pentium 4 needed to run at a 15% higher clock speed just to match the performance of the old P6 Pentium chips.</p>
<p>The Pentium 4 wasn’t really suitable for laptops, though, because of its high power requirements. So as a stopgap, Intel went back to the old P6 Pentium Pro era design, made a few improvements, and started selling it as the Pentium M.</p>
<p>Itanium launched in 2001. Hardly anyone noticed, and it quickly got dubbed ‘Itanic’. Over the next four years it <a href="http://www.theregister.co.uk/2004/02/17/who_sank_itanic/">quietly sank</a>.</p>
<p>By 2003, AMD was making significant gains in the high performance x86 server market. Intel tried launching a Pentium 4 Extreme Edition at $999 per chip, but the next week AMD launched Athlon 64. It was a true 64 bit x86, but it could still run 32 bit x86 code. So it was more compatible than Itanium, and faster and more expandable than Pentium 4.</p>
<p>In 2004, Intel released a Pentium 4 with an implementation of AMD’s 64 bit x86 instructions. It was another humiliating stopgap measure, but worse was to come. The chip’s architecture wasn’t working out the way it had been planned — instead of the planned 10GHz, the fastest it was ever pushed was 3.8GHz. Beyond that, it had major thermal problems, chewing and dissipating so much power that it was tough to keep the chip from melting.</p>
<p>The Pentium 4 wasn’t going to cut it against the competition. So Intel threw away both their new architectures, Pentium 4/NetBurst and Itanium, and went back to the old P6 Pentium Pro design <em>yet again</em>. This time they took the old Pentium M core, stuck two of them on a single chip, added more cache, and called the result Core Duo. The ’new’ architecture was called <a href="http://en.wikipedia.org/wiki/Core_%28microarchitecture%29">Core</a>, and it was a success — the personal computer industry was moving towards laptops, and at the same time people were starting to demand smooth multitasking and multimedia, listening to MP3s or watching videos while editing documents. Core Duo’s comparatively low power requirements and dual cores made for a great laptop experience. By 2006 they had extended the Core architecture to add AMD’s 64 bit instructions, and Core 2 was born. Core i5 and Core i7 followed, and here we are.</p>
<p>So in summary: The Intel 1201 was designed to operate a dumb terminal, but didn’t work. It fixed up and condensed onto a single chip as the 8008. The 8008 was hacked to support 16 bit, and became the 8080. The 8080 was condensed onto fewer chips as the 8085. The 8086 was a quick hack designed to be a new 16 bit chip, but compatible with the 8085. The 8086 was temporarily hacked to support more memory as the 80286, given bolted-on 32 bit support as the 80386, then upgraded to become the 80486 and Pentium series. The 80486 became a stopgap CPU for laptops, the Pentium M. That then became the CPU core at the center of the Core series, which had a clone of AMD’s 64 bit support bolted on as the Core 2.</p>
<p>So to summarize the summary, we’re still running CPUs based on the design of a 1971 dumb terminal, with more and more hacks bolted on. Intel have desperately tried to replace the mess multiple times, but every fundamentally new CPU architecture they’ve come up with has been sub-par in some major respect, and failed.</p>
<p>How long can this last? Well, there are signs that the era of the x86 might finally be ending, as the personal computer era ends. More and more people use mobile phones and tablets as their primary computing devices, and Intel has failed to get any traction in that market space. Instead, all the popular devices are based on <a href="https://en.wikipedia.org/wiki/ARM_architecture">ARM</a>, a pure and clean RISC design by Acorn, inspired by the classic 6502. Recently, the most popular laptop on Amazon has been the ChromeBook — running on ARM. Devices are starting to appear powered by the 64 bit ARM design released in late 2011. At the high end, IBM’s POWER architecture has reached clock speeds of up to 5GHz, and massive supercomputing projects like <a href="http://www-03.ibm.com/systems/power/advantages/watson/index.html">Watson</a> are built on it. Intel is in the middle, and being squeezed from both sides. RISC may yet have the last laugh.</p>
]]></content></entry><entry><title type="html">Sinatra, web apps, and a Ruby flock</title><link href="https://lpar.ATH0.com/posts/2013/01/sinatra-web-apps-and-a-ruby-flock/"/><id>https://lpar.ATH0.com/posts/2013/01/sinatra-web-apps-and-a-ruby-flock/</id><published>2013-01-29T16:30:19+00:00</published><updated>2013-01-29T16:30:19+00:00</updated><summary>Building web applications without Rails.</summary><content type="html"><![CDATA[<p>I’ve been writing a web application in Ruby recently, in order to glue together a couple of fairly complicated systems into something approaching a sane workflow.</p>
<p>You might think I’d use Rails. Once upon a time I thought I’d write applications in Rails too. I bought the book, wrote some toy apps, and set it aside until I next needed it.</p>
<p>In the meantime, Rails got bigger and bigger. It adopted <a href="http://www.rubyinside.com/rails-3-1-adopts-coffeescript-jquery-sass-and-controversy-4669.html">controversial trendy libraries</a>. Its <a href="http://blog.steveklabnik.com/posts/2011-12-30-active-record-considered-harmful">limitations started to become apparent</a>, and even the hipsters started <a href="http://gilesbowkett.blogspot.co.uk/2012/02/rails-went-off-rails-why-im-rebuilding.html">abandoning it</a>. When I looked at Rails 3, I decided it was no longer heading in a direction I wanted to go.</p>
<p>I’m not a big fan of frameworks anyway. “<a href="http://discuss.joelonsoftware.com/default.asp?joel.3.219431.12">Why I Hate Frameworks</a>” discusses part of the reason—they tend to result in too much abstraction. They also tend to result in lots of indirect external dependencies; your platform choices, for example, can end up being made for you. And then there’s the opinionated way they tend to dictate your other choices. To me, a framework is a library with delusions of grandeur; it’s like hiring a plumber because you need the sink fixed, and having him lecture you about how you should landscape your front yard.</p>
<p>That’s not to say that there isn’t a place for frameworks. Sometimes you are doing something that’s very complicated but standardized, like building a GUI application. Sometimes you’re a beginner, and you want someone to tell you what to do and how to do it. But mostly, frameworks annoy me.</p>
<p>There are a few exceptions, though. One is the framework I’ve been using for my trivial web application. It’s called <a href="http://www.sinatrarb.com/">Sinatra</a>, and is not much more than <a href="https://github.com/sinatra/sinatra/">a thin layer of syntactic sugar</a> sprinkled on top of HTTP.</p>
<p>I don’t need widgets or a sophisticated templating system, as the look and feel has been supplied to me by the corporate web design team. I don’t even need a database, because my application just needs to pull data from one system and push/pull it with another, via REST APIs. The Ruby <a href="https://github.com/archiloque/rest-client">rest-client</a> Gem makes that easy; it basically does for REST calls what Sinatra does for HTTP servers. So Sinatra gets the job done. Rails is a faster way to get <a href="http://en.wikipedia.org/wiki/Create,_read,_update_and_delete">CRUD</a> apps started, but if you have a problem that isn’t CRUD, I’d suggest checking out Sinatra.</p>
<p>Ruby tends to lend itself to these kinds of domain-specific languages. For instance, here’s a function which implements locking using a temporary lock file and the POSIX flock call, to ensure exclusive access between multiple processes:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ruby" data-lang="ruby"><span class="line"><span class="cl"><span class="no">LOCK_FILE</span><span class="o">=</span><span class="s1">&#39;/tmp/lockfile.tmp&#39;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">exclusively</span>
</span></span><span class="line"><span class="cl">  <span class="no">File</span><span class="o">.</span><span class="n">open</span><span class="p">(</span><span class="no">LOCK_FILE</span><span class="p">,</span> <span class="no">File</span><span class="o">::</span><span class="no">CREAT</span><span class="o">|</span><span class="no">File</span><span class="o">::</span><span class="no">RDWR</span><span class="p">,</span> <span class="mo">0644</span><span class="p">)</span> <span class="k">do</span> <span class="o">|</span><span class="n">file</span><span class="o">|</span>
</span></span><span class="line"><span class="cl">    <span class="n">file</span><span class="o">.</span><span class="n">flock</span><span class="p">(</span><span class="no">File</span><span class="o">::</span><span class="no">LOCK_EX</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="k">yield</span>
</span></span><span class="line"><span class="cl">    <span class="n">file</span><span class="o">.</span><span class="n">flock</span><span class="p">(</span><span class="no">File</span><span class="o">::</span><span class="no">LOCK_UN</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">  <span class="k">end</span>
</span></span><span class="line"><span class="cl"><span class="k">end</span>
</span></span></code></pre></div><p>You can then put a lock around some access to a resource like this:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ruby" data-lang="ruby"><span class="line"><span class="cl"><span class="nb">puts</span> <span class="s2">&#34;Entering exclusivity zone...&#34;</span>
</span></span><span class="line"><span class="cl"><span class="n">exclusively</span> <span class="k">do</span>
</span></span><span class="line"><span class="cl">  <span class="nb">puts</span> <span class="s2">&#34;I&#39;m in!&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="nb">sleep</span> <span class="mi">20</span> <span class="c1"># simulate access to slow resource</span>
</span></span><span class="line"><span class="cl">  <span class="nb">puts</span> <span class="s2">&#34;Exiting exclusivity zone...&#34;</span>
</span></span><span class="line"><span class="cl"><span class="k">end</span>
</span></span></code></pre></div><p>For more elaborate lock file requirements, there’s the <a href="https://github.com/ahoward/lockfile">lockfile gem</a>.</p>
]]></content></entry><entry><title type="html">Sometimes ORM is not the answer</title><link href="https://lpar.ATH0.com/posts/2012/05/sometimes-orm-is-not-the-answer/"/><id>https://lpar.ATH0.com/posts/2012/05/sometimes-orm-is-not-the-answer/</id><published>2012-05-18T23:41:09+00:00</published><updated>2012-05-18T23:41:09+00:00</updated><summary>Maybe it’s better to write SQL.</summary><content type="html"><![CDATA[<p>Earlier this week, I wrote some data pump code to move information between DB2 and Domino, filtering and cleaning it on the way. I wrote the code using JPA 2 so that I’d have less code to write, and so that I could more easily turn it over to someone else some day and not have a lot of questions to answer.</p>
<p>Performance seemed really slow, so I decided to measure just how slow. I grabbed my <a href="https://gist.github.com/1107823">stopwatch class</a>, hacked it in, replaced the output database with a file, and looked at the results in seconds taken per thousand records read:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-txt" data-lang="txt"><span class="line"><span class="cl">JPA 2:
</span></span><span class="line"><span class="cl">81.54 s/krec
</span></span><span class="line"><span class="cl">77.82 s/krec
</span></span><span class="line"><span class="cl">81.89 s/krec
</span></span><span class="line"><span class="cl">89.60 s/krec
</span></span></code></pre></div><p>Taking 81 seconds per thousand records might seem pretty good, but it meant my data pump was going to take over 5 hours each night. And that assumed multiple threads so that the writing part of the problem didn’t slow it down any further.</p>
<p>At this point, I could have done the Rails hipster thing, and said “Oh dear, relational databases are slow and useless, let’s use NoSQL”, but instead I decided to investigate further. To find out how much of the overhead was down to JPA 2, I hacked together some raw JDBC code to compare:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-txt" data-lang="txt"><span class="line"><span class="cl">JDBC:
</span></span><span class="line"><span class="cl">0.42 s/krec
</span></span><span class="line"><span class="cl">0.42 s/krec
</span></span><span class="line"><span class="cl">0.42 s/krec
</span></span><span class="line"><span class="cl">0.42 s/krec
</span></span></code></pre></div><p>So, about 200x faster. Not looking good for JPA 2 and EclipseLink. I turned up the logging level, and took a look at the actual SQL being executed.</p>
<p>The actual column retrieval part of the query looked fine; exactly how I’d written it in the JDBC code, in fact. The problem is that it was wrapped in this:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sql" data-lang="sql"><span class="line"><span class="cl"><span class="k">SELECT</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="k">FROM</span><span class="w"> </span><span class="p">(</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="k">SELECT</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="k">FROM</span><span class="w"> </span><span class="p">(</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="k">SELECT</span><span class="w"> </span><span class="n">EL_TEMP</span><span class="p">.</span><span class="o">*</span><span class="p">,</span><span class="w"> </span><span class="n">ROWNUMBER</span><span class="p">()</span><span class="w"> </span><span class="n">OVER</span><span class="p">()</span><span class="w"> </span><span class="k">AS</span><span class="w"> </span><span class="n">EL_ROWNM</span><span class="w"> 
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="k">FROM</span><span class="w"> </span><span class="p">(</span><span class="w"> </span><span class="n">sensible</span><span class="w"> </span><span class="n">query</span><span class="w"> </span><span class="n">goes</span><span class="w"> </span><span class="n">here</span><span class="w"> </span><span class="p">)</span><span class="w"> </span><span class="k">AS</span><span class="w"> </span><span class="n">EL_TEMP</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="k">AS</span><span class="w"> </span><span class="n">EL_TEMP2</span><span class="w"> </span><span class="k">WHERE</span><span class="w"> </span><span class="n">EL_ROWNM</span><span class="w"> </span><span class="o">&lt;=</span><span class="w"> </span><span class="o">?</span><span class="p">)</span><span class="w"> 
</span></span></span><span class="line"><span class="cl"><span class="k">AS</span><span class="w"> </span><span class="n">EL_TEMP3</span><span class="w"> </span><span class="k">WHERE</span><span class="w"> </span><span class="n">EL_ROWNM</span><span class="w"> </span><span class="o">&gt;</span><span class="w"> </span><span class="o">?</span><span class="w">
</span></span></span></code></pre></div><p>This was being done to chop the result table into reasonable slices. I was using a wrapper class which called JPA’s <code>setFirstResult()</code>/<code>setMaxResult()</code> to page through the results, cache them, and hand the objects back to my code. JPA was then generating the nested queries to implement this pagination. Timing the paginated query revealed that it was responsible for the slowdown.</p>
<p>I couldn’t eliminate paging; the dataset was just too big. So I tried altering the code to make the cache and page size much larger. That helped a bit, and allowed me to get the delay down to 4.21s/krec. Still 10x slower than raw JDBC, but 20x faster than it had been.</p>
<p>I looked around for some information about how to best do result pagination with DB2, and found <a href="http://www.ibm.com/developerworks/data/library/techarticle/0307balani/0307balani.html">a developerWorks article</a>. I used the techniques from that article to put together a paged query equivalent to the one EclipseLink was generating, ran them both through DB2’s command-line performance measurement tool, and verified that both gave the same output.</p>
<p>The EclipseLink query was 3x faster than the new one.</p>
<p>Next, I decided to see how fast the DB2 command line client could dump the data. It was only slightly faster than the raw JDBC; 0.399 s/krec rather than 0.42.</p>
<p>I reached several conclusions.</p>
<p>Firstly, EclipseLink is pretty good from a performance point of view. Given the problem of issuing paginated queries against a database, chances are EclipseLink will do better than a random non-expert programmer writing raw SQL.</p>
<p>However, that might not be good enough. Pagination can be expensive, so if you’re batch-processing data you might be much better off avoiding ORM entirely. So like most things in software development, ORM is not always the right answer.</p>
<p>I’m also disappointed that there’s still no good way to use JPA to get your query results in Iterator form, so that pagination becomes unnecessary.</p>
]]></content></entry><entry><title type="html">Random cool hack: Make your Ruby scripts work as man pages</title><link href="https://lpar.ATH0.com/posts/2011/10/random-cool-hack-make-your-ruby-scripts-work-as-man-pages/"/><id>https://lpar.ATH0.com/posts/2011/10/random-cool-hack-make-your-ruby-scripts-work-as-man-pages/</id><published>2011-10-27T20:49:02+00:00</published><updated>2011-10-27T20:49:02+00:00</updated><summary>It’s a script and a man page and a floor wax and a dessert topping.</summary><content type="html"><![CDATA[<p>Via careful use of nroff directives and comments, it’s possible to make <a href="https://gist.github.com/1320801">a Ruby script that works both as a command line utility you can run, and as a man page</a>. It’s a floor wax <em>and</em> a dessert topping.</p>
<p>This is handy, as it means you can distribute both the utility and the documentation in a single file, and symlink the script into the appropriate man page.</p>
<p>You can also, of course, look for the standard <code>--help</code> command line option, and make your utility call man with its own source file as argument to provide the help.</p>
<p>Note that if your utility makes extensive use of command line options, you’ll probably want to use <a href="http://rdoc.info/stdlib/getoptlong/1.9.2/frames">GetoptLong</a>.</p>
]]></content></entry><entry><title type="html">It&amp;#39;s possible to be too helpful</title><link href="https://lpar.ATH0.com/posts/2011/07/its-possible-to-be-too-helpful/"/><id>https://lpar.ATH0.com/posts/2011/07/its-possible-to-be-too-helpful/</id><published>2011-07-01T21:53:46+00:00</published><updated>2011-07-01T21:53:46+00:00</updated><summary>object Object.</summary><content type="html"><![CDATA[<p>I think this may be the best JavaScript error I’ve ever been given:</p>
<blockquote>
<p>Uncaught TypeError: Object [object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object], has no method ‘delete’</p>
</blockquote>
<p>Thanks, Chrome. The variable name would have sufficed.</p>
]]></content></entry><entry><title type="html">JavaScript modulus weirdness</title><link href="https://lpar.ATH0.com/posts/2011/04/javascript-modulus-weirdness/"/><id>https://lpar.ATH0.com/posts/2011/04/javascript-modulus-weirdness/</id><published>2011-04-27T19:06:43+00:00</published><updated>2011-04-27T19:06:43+00:00</updated><summary>A useful but probably inadvisable trick.</summary><content type="html"><![CDATA[<p>I just became aware of an interesting JavaScript ‘feature’. The code</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="nx">y</span> <span class="o">=</span> <span class="nx">x</span> <span class="o">%</span> <span class="mi">1</span><span class="p">;</span>
</span></span></code></pre></div><p>is equivalent to</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="nx">y</span> <span class="o">=</span> <span class="nx">x</span> <span class="o">-</span> <span class="nb">Math</span><span class="p">.</span><span class="nx">floor</span><span class="p">(</span><span class="nx">x</span><span class="p">);</span>
</span></span></code></pre></div><p>because ECMA-262 says:</p>
<blockquote>
<p>… the floating-point remainder r from a dividend n and a divisor d is defined by the mathematical relation r = n − (d * q) where q is an integer that is negative only if n/d is negative and positive only if n/d is positive, and whose magnitude is as large as possible without exceeding the magnitude of the true mathematical quotient of n and d.</p>
</blockquote>
<p>So if d is 1 then q is the largest integer that’s smaller than n/1, so r = n - Math.floor(n).</p>
<p>I will not be using this feature in my code.</p>
]]></content></entry><entry><title type="html">Why TeX?</title><link href="https://lpar.ATH0.com/posts/2011/04/why-tex/"/><id>https://lpar.ATH0.com/posts/2011/04/why-tex/</id><published>2011-04-05T19:59:31+00:00</published><updated>2011-04-05T19:59:31+00:00</updated><summary>Or LaTeX, or ConTeXt.</summary><content type="html"><![CDATA[<p>Recently someone on Stack Exchange asked <a href="http://tex.stackexchange.com/questions/13370/why-are-there-no-alternatives-to-tex-or-why-is-tex-still-used">Why are there no alternatives to TeX, or, why is TeX still used?</a></p>
<p>Here are some reasons.</p>
<h3 id="it-works">It works.</h3>
<p>It sounds trite, but TeX has a robustness and reliability that other software lacks. Recently, there was a discussion of a bug in LuaTeX triggered when a document hits 3,987 pages. I can’t imagine creating a document with over 1,000 complex pages using something like Microsoft Word or OpenOffice Writer.</p>
<h3 id="its-predictable">It’s predictable.</h3>
<p>If you’ve ever wondered why your word processor is formatting something a particular way, well, sometimes there’s really no way to answer the question. Microsoft’s OOXML spec resorted to defining many aspects of formatting by <a href="http://en.wikipedia.org/w/index.php?title=Office_Open_XML&amp;oldid=314111559#Criticism_of_ECMA-376_1st_edition">saying that they had to be the same as particular versions of Word</a>; even Microsoft couldn’t specify what that behavior actually was. Pro typesetting software like Adobe InDesign <a href="http://piracy.ssrc.org/adobe-logic/">isn’t much better</a> when it comes to maintaining compatibility between versions.</p>
<p>With TeX, there are fewer ghosts in the machine. Even if the details underneath are pretty scary, at least you can always see exactly what macros you are applying to a piece of text and what parameters you have tweaked. Nothing is hidden, and there’s more of a feeling of being in control.</p>
<h3 id="it-keeps-working">It keeps working.</h3>
<p>I’ve used a lot of word processors over the years. Wordwise, View, LocoScript, 1st Word Plus, MacWrite, WordStar, WordPerfect, AppleWorks, DisplayWrite, Word Pro, ClarisWorks… They’re all dead and gone now. Good luck reading any files you still have stored in their special file formats. In fact, there have been discussions on <a href="http://www.macintouch.com">Macintouch</a> recently about the problems of converting a large number of legacy ClarisWorks documents into something readable, and that product was only declared end-of-life in 2007. Yet if I still had a copy of my dissertation, I could typeset and print it today, because I wrote it in TeX.</p>
<p>ConTeXt is the newest and most rapidly changing TeX macro package. Even so, switching from a 2 year old version to today’s bleeding-edge beta is mostly a non-event.</p>
<h3 id="it-runs-everywhere">It runs everywhere.</h3>
<p>Using TeX, I can produce finished documents on Mac, Windows, Linux, or any Unix-like OS. I don’t need a high-end CPU, I don’t even need a high resolution display.</p>
<h3 id="you-can-edit-it-using-whatever-tool-you-prefer">You can edit it using whatever tool you prefer.</h3>
<p>TeX files are just UTF-8 text files. Edit them with TextWrangler, vim, Emacs, jEdit, pretty much any text editor you want. It helps to have syntax highlighting, but it’s not essential.</p>
<p>Edit on your laptop, on someone else’s laptop, on a tablet, on your phone. Anywhere there’s a text editor.</p>
<p>Put your documents in version control. They’re just text, so you can diff them. They’re small and compress really well, so you can keep every version forever and not run out of space. Store them on a remote server and edit via SSH. Transfer them in a fraction of a second across a modern network connection.</p>
<h3 id="its-cheap">It’s cheap.</h3>
<p>I use the word ‘cheap’ rather than ‘free’ because really, I’m not at all averse to paying for software. However, my budget is limited.</p>
<p>There are some solid proprietary page layout systems that can deal robustly with large documents. Adobe FrameMaker, for example. MSRP for that is $999. If you want something a bit cheaper, there’s InDesign, for $699. Both are a bit pricey for my liking.</p>
<p>Or there’s TeX, which is where FrameMaker got its typesetting algorithms from anyway. Cost: $0. I think it’s something of a bargain.</p>
<h3 id="it-gets-out-of-the-way">It gets out of the way.</h3>
<p>Recently, a lot of writers have been discovering the joy of ultra-minimalistic tools which get out of the way and let you focus on the actual writing. There are programs like WriteRoom, DarkRoom, jDarkRoom, Byword, OmmWriter, and so on, which attempt to remove distractions and give you just text on an otherwise empty screen. Then there are tools like Markdown, reStructuredText and wiki syntax, markup languages which allow you to edit plain text with minimal annotations and convert it into something with pretty formatting later on.</p>
<p>All of these tools are rediscovering something that was lost when we moved from word processors like WordPerfect, which used plain text with embedded formatting commands, and entered the WYSIWYG world of the 90s with its endless buttons, sliders, ribbons and rulers.</p>
<p>Being a markup language, TeX has that minimalist essence. It’s just text.</p>
<h3 id="its-extensible-on-the-fly">It’s extensible, on the fly.</h3>
<p>Sometimes I’m writing some documentation, and I suddenly realize I’ll have to repeatedly refer to some kind of thing — a set of menu entries, say — and format them in a special way throughout the text.</p>
<p>In a normal word processor, I stop writing. I decide whether I need a paragraph style or a text style. I decide what existing style it needs to be based on. I click around to create my new style and give it a name. I adjust its formatting to be distinctive so I can see what I’m editing. I map it to a key. And then I try to remember what I was about to write before my multi-minute jaunt into wordprocessorland.</p>
<p>In TeX, I make up an imaginary macro off the top of my head — <code>\Menu{File — Quit}</code> — and keep on writing. After I’m done writing whatever was in my head, <em>then</em> I worry about extraneous details such as how it’ll look on the page and whether it needs to be based on the look of anything else. Even if I decide I need a more elaborate calling pattern — say, if the macro needs some arguments — it doesn’t matter, because the plain text nature of my made-up-on-the-spot macro makes it easy to find and replace.</p>
<p>Obviously, actually applying the formatting is harder than with a word processor. But once I’ve done it once, I can re-use that magic incantation endlessly.</p>
<h3 id="it-handles-vector-art-properly">It handles vector art properly.</h3>
<p>One place a surprising number of word processors fall down is incorporating images into the text. Somehow it seems to be acceptable to offer fonts that are infinitely scalable vectors, and then fail to offer any reliable way to insert and adjust a vector diagram. Want to bring your process diagram into OpenOffice? Sorry, can’t read the SVG, why don’t you just draw it again with the horrible OpenOffice Draw?</p>
<p>In business, it’s not at all unusual to receive documents that have diagrams as horrible resized bitmaps, or tables as embedded objects that look like crap, for pretty much this reason.</p>
<p>With TeX, I can use any vector graphics tool I like, and there’s almost always a way to get PDF out — either directly, or via a print-to-PDF driver. Once I have PDF, it’s painless to place it onto the page <em>as vectors</em>. So like everything else, it scales correctly for the display. The only things in my documents that end up as ugly bitmaps are the screen captures, and that’s the way it should be.</p>
<p>There are more reasons if you’re a mathematician or scientist. I’m just listing reasons why a person who wants to write ordinary everyday business and personal documents might choose to use TeX to do so.</p>
<p>Nevertheless, I would absolutely use something more modern that met the same basic requirements. If you know of a word processor that runs on any modern computer, can deal with 5,000 page documents, imports vector art in standard formats and handles it in vector form, writes to tagged PDF with working hyperlinks, is guaranteed to be around and supported for the next 40 years, will let me edit without having to learn a new user interface or have anything but my text on the screen, has output the quality of FrameMaker or InDesign, is arbitrarily extensible, and costs under $100, do please let me know.</p>
]]></content></entry><entry><title type="html">Engines of TeXnology</title><link href="https://lpar.ATH0.com/posts/2011/03/engines-of-texnology/"/><id>https://lpar.ATH0.com/posts/2011/03/engines-of-texnology/</id><published>2011-03-23T01:41:51+00:00</published><updated>2011-03-23T01:41:51+00:00</updated><summary>Modern TeX and fonts which aren’t Computer Modern.</summary><content type="html"><![CDATA[<p>Back in 1978, when the TeX project began, there were no scalable fonts. If your printer supported 10 point and 12 point text, those were the two sizes you could use in your documents. Even when the Macintosh came along, you still had a fixed set of text sizes, unless you were rich enough to have a PostScript laser printer.</p>
<p>TeX, on the other hand, had METAFONT — a system for defining vector fonts, which could then be rasterized at any size, for any printer that could handle a bitmap image. So for years, TeX was the only way a lot of people could create documents using a wide range of typeface sizes and styles.</p>
<p>Then around 1990, Adobe Type Manager (ATM) went on the market. If you installed it on your Macintosh or Microsoft Windows system, you could use PostScript fonts on your desktop at any size, and ATM would handle the rasterization for your screen — and for your printer, if it wasn’t a Postscript printer. Suddenly you could have any font size you wanted, anywhere.</p>
<p>Fast forward 20 years, and vector fonts are ubiquitous; even my phone has vector fonts. Type 1, TrueType, OpenType… but not METAFONT. Like Plain TeX, METAFONT was way too complicated for most graphic designers. So nowadays, like everyone else, I want to be able to use the dozens of attractive vector typefaces installed on my computer, rather than <a href="http://www.faqs.org/faqs/fonts-faq/metafont-list/">the rather anemic selection of METAFONT fonts</a>.</p>
<p>Then there was TeX’s way of getting output to the printer. First you ran your source TeX file through TeX itself; that spat out a DVI file with just the typeset text. Then you took the DVI file, and ran it through a converter which would insert the diagrams from their files, embed a set of fonts generated by METAFONT, and output a PostScript file. Then you either sent your PostScript file to your PostScript printer, if you were lucky enough to have one; or else you ran the PostScript through another converter (such as GhostScript) to turn it into your printer’s proprietary printer dump format (such as <a href="http://en.wikipedia.org/wiki/ESC/P">ESC/P</a> or <a href="http://en.wikipedia.org/wiki/Printer_Command_Language">PCL</a>, and copied <em>that</em> to your printer. It was all tedious but necessary in 1990. Today, it looks insane.</p>
<p>Then there’s the whole character encoding issue. Back in 1990, the only thing that could reliably be translated between different computer systems was plain ASCII text, so TeX had macros for curly quotes, accented characters, typographic dashes, dingbats, non-Roman alphabets, and so on. Nowadays, every major OS supports Unicode, so you can put Cyrillic or Greek text in your document on the Mac and be reasonably confident it’ll still be there if you open the file in Linux.</p>
<p>So TeX has been adapted to the modern world. pdfTeX got rid of the DVI stage, and went straight from TeX source files to PDF files; it later added support for <a href="http://en.wikipedia.org/wiki/Microtypography">microtypography</a>. XeTeX got rid of METAFONT fonts, and allowed direct access to OS-installed vector fonts; it also added Unicode support. LuaTeX extended pdfTeX by adding Lua as an extra scripting language, allowing more complicated functionality to be supported than was feasible with TeX macros, and also added OS font support. LuaTeX has now been adopted as the successor to pdfTeX.</p>
<p>Since I wanted the most up-to-date Unicode and font support, I set about trying ConTeXt on Linux and Mac, using both LuaTeX and XeTeX. I created a document using a custom set of fonts — one OpenType, one Type 1, and one TrueType.</p>
<p>XeTeX was far easier to set up. Whereas LuaTeX requires that you set up environment variables and run a script to scan your fonts, XeTeX just calls the OS font routines. However, LuaTeX gets points because it’s the only supported engine for the latest ConTeXt release, Mark IV.</p>
<p>On the minus side, XeTeX on Linux is a bit buggier than on the Mac, as it’s a recent port; I had trouble with some Type 1 fonts. LuaTeX is not without bugs either: the ConTeXt mailing list recently discussed a bug triggered by a 5,000 page document, which caused LuaTeX to crash on page 3,987. That bug is fixed in a recent beta. Meanwhile, if anyone wants to try assembling a 4,000 page document in Microsoft Office, I’d be interested to know if it’s possible.</p>
<p>Since my documents are well under 3,987 pages, I’ve been happy with LuaTeX so far. So I had picked my TeX platform: ConTeXt running on LuaTeX. Now I had to sort out my macros and other necessary tools.</p>
]]></content></entry><entry><title type="html">Which TeX?</title><link href="https://lpar.ATH0.com/posts/2011/03/which-tex/"/><id>https://lpar.ATH0.com/posts/2011/03/which-tex/</id><published>2011-03-15T20:07:59+00:00</published><updated>2011-03-15T20:07:59+00:00</updated><summary>Plain TeX, LaTeX, and ConTeXt.</summary><content type="html"><![CDATA[<p>When I posted that I was <a href="/2011/03/10/going-back-to-something-that-works/">going back to using TeX</a>, I mentioned that TeX had changed a lot in 20 years, but didn’t really go into too many details. Time to remedy that.</p>
<p>TeX is two layers of software. Underneath is the core of TeX, written in a variant of Pascal. These days it gets translated to C before being compiled to a binary. On top of the TeX core, you have a set of macros which provide all the handy <code>commands</code> you use to typeset documents.</p>
<p>There are a number of different macro packages. Knuth’s own is known as “Plain TeX”; it’s what I used back when I last wrote TeX documents. It’s extremely flexible, and I managed to make it format my dissertation in a way that was so un-TeX-like that the examiners asked what I used. Unfortunately, Plain TeX is rather ugly to use. For example, here’s the code of <a href="http://ctan.mirror.ac.za/macros/plain/contrib/misc/split.tex">a Plain TeX macro for placing two pieces of text side by side</a>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-tex" data-lang="tex"><span class="line"><span class="cl"><span class="k">\def\xsplit</span>#1#2#3#4#5<span class="nb">{{</span>
</span></span><span class="line"><span class="cl">  <span class="k">\setbox</span>1=<span class="k">\vbox</span><span class="nb">{</span><span class="k">\hsize</span>= #1 #4<span class="nb">}</span>    <span class="c">% First column
</span></span></span><span class="line"><span class="cl">  <span class="k">\setbox</span>2=<span class="k">\vbox</span><span class="nb">{</span><span class="k">\hsize</span>= #3 #5<span class="nb">}</span>    <span class="c">% Second column
</span></span></span><span class="line"><span class="cl">  <span class="c">% If the boxes are output side by side at this point, they
</span></span></span><span class="line"><span class="cl">  <span class="c">% will be aligned at the bottom instead of the top.
</span></span></span><span class="line"><span class="cl">  <span class="k">\ifdim\ht</span>2&gt;<span class="k">\ht</span>1   <span class="c">% Column two is longer than column one
</span></span></span><span class="line"><span class="cl">    <span class="c">% Fill bottom of column one with glue
</span></span></span><span class="line"><span class="cl">    <span class="k">\setbox</span>1=<span class="k">\vbox</span> to <span class="k">\ht</span>2<span class="nb">{</span><span class="k">\hsize</span>= #1 #4 <span class="k">\vfill</span><span class="nb">}</span>
</span></span><span class="line"><span class="cl">  <span class="k">\else</span>
</span></span><span class="line"><span class="cl">    <span class="k">\ifdim\ht</span>1&gt;<span class="k">\ht</span>2   <span class="c">% Column one is longer than column two
</span></span></span><span class="line"><span class="cl">      <span class="c">% Fill bottom of column two with glue
</span></span></span><span class="line"><span class="cl">      <span class="k">\setbox</span>2=<span class="k">\vbox</span> to <span class="k">\ht</span>1<span class="nb">{</span><span class="k">\hsize</span>= #3 #5 <span class="k">\vfill</span><span class="nb">}</span>
</span></span><span class="line"><span class="cl">    <span class="k">\fi</span>
</span></span><span class="line"><span class="cl">  <span class="k">\fi</span>
</span></span><span class="line"><span class="cl">  <span class="k">\hbox</span><span class="nb">{</span><span class="k">\box</span>1<span class="k">\hskip</span>#2<span class="k">\box</span>2<span class="nb">}}}</span>
</span></span></code></pre></div><p>I remember spending most of a summer vacation poring over a copy of Knuth’s <cite><a href="http://www.amazon.com/gp/product/0201134470/ref=as_li_ss_tl?ie=UTF8&tag=a0ef8-20&linkCode=as2&camp=1789&creative=390957&creativeASIN=0201134470">The TeXbook</a></cite>, slowly assembling my own set of macros. I based my page layout on that of Apple’s <cite><a href="http://www.amazon.com/gp/product/0201622165/ref=as_li_ss_tl?ie=UTF8&tag=a0ef8-20&linkCode=as2&camp=1789&creative=390957&creativeASIN=0201622165">Macintosh Human Interface Guidelines</a></cite>. I had found the book particularly readable, and reasoned that Apple probably knew what it was doing as far as designing page layouts for technical documentation. Bending TeX to my will wasn’t much fun.</p>
<p>It’s a problem lots of people had. So to get away from all that, Leslie Lamport wrote an alternate set of macros called LaTeX. He provided standard templates for letters, technical articles, reports, books, and overhead projector slides. (Kids: Ask an old person what an overhead projector was.) LaTeX also had macros for bibliographies, tabular data, simple diagrams, indexes, and pretty much everything else needed for academic documents. Its book — <cite><a href="http://www.amazon.com/gp/product/0201529831/ref=as_li_ss_tl?ie=UTF8&tag=a0ef8-20&linkCode=as2&camp=1789&creative=390957&creativeASIN=0201529831">LaTeX: A Document Preparation System</a></cite> — was about half the thickness of Knuth’s book, more focused on end users, and came with a handy quick reference card.</p>
<p>LaTeX spread through academia faster than Far Side cartoons. It was particularly popular with mathematicians, physicists, chemists, computer scientists, and anyone else who needed to be able to typeset mathematical equations. (It was also about the only way to typeset Tibetan in 1990, which led to my helping out some humanities students.) LaTeX is probably the most popular TeX macro package. There’s even a <a href="http://www.lyx.org/">full graphical editor</a> for LaTeX, so you can avoid the markup language entirely. If you have a mental image of what a TeX document looks like, chances are it’s the look of a standard LaTeX template.</p>
<p>I had toyed with returning to TeX a year or so ago, and picked up a copy of Lamport’s book in order to try out LaTeX. There’s a problem with LaTeX, though. If you don’t care about page design, it makes it really easy to put together a document that looks exactly as specified by its templates; but if you want to design your own page layout from scratch, you quickly enter a world of pain. That’s probably why almost all LaTeX documents look alike.</p>
<p>So I did some more research, and decided to try a newcomer to the TeX package market: ConTeXt. Its development started in 1990; it attempts to make TeX behave in ways familiar to people used to modern DTP packages. It’s more flexible than LaTeX, yet easier to use than Plain TeX. Here’s how you put two paragraphs side by side in ConTeXt:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-tex" data-lang="tex"><span class="line"><span class="cl"><span class="k">\defineparagraphs</span><span class="na">[sidebyside][n=2]</span>
</span></span><span class="line"><span class="cl"><span class="k">\setupparagraphs</span><span class="na">[sidebyside][1][width=.45textwidth]</span>
</span></span><span class="line"><span class="cl"><span class="k">\setupparagraphs</span><span class="na">[sidebyside][2][width=.45textwidth]</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">\startsidebyside</span>
</span></span><span class="line"><span class="cl">First paragraph goes here.
</span></span><span class="line"><span class="cl"><span class="k">\sidebyside</span>
</span></span><span class="line"><span class="cl">Second paragraph goes here.
</span></span><span class="line"><span class="cl"><span class="k">\stopsidebyside</span>
</span></span></code></pre></div><p>It’s still a bit long-winded, but that’s because it’s completely general. The first chunk is the setup; you can adjust the number of columns, define each column’s width differently, give different columns different text styles, and so on, and give each setup its own name and pair of <code>macros</code> to apply to your paragraphs, as in the second chunk of text.</p>
<p>So, I had chosen a macro package; but there were more decisions to make…</p>
]]></content></entry><entry><title type="html">Going back to something that works</title><link href="https://lpar.ATH0.com/posts/2011/03/going-back-to-something-that-works/"/><id>https://lpar.ATH0.com/posts/2011/03/going-back-to-something-that-works/</id><published>2011-03-10T02:39:09+00:00</published><updated>2011-03-10T02:39:09+00:00</updated><summary>TeX. It’s not pretty, and it’s not easy, but it works.</summary><content type="html"><![CDATA[<p>Last week I had a bad experience with several pieces of office software.</p>
<p>It started with a simple enough task: I had some existing documentation, and I needed to extend the “How to perform common tasks” section. There were two sub-headings to add, each of which needed a few bulleted paragraphs of instructions.</p>
<p>I fired up LibreOffice, opened the document, and started typing — but something was wrong. When I clicked to turn my instructions into a bulleted list, the indentation was wrong. It didn’t match the similar bulleted lists above or below in the document.</p>
<p>I assumed I had mixed up the styles somehow, perhaps applying bullets to the wrong paragraph styles, so I checked the style of the correct paragraphs, then applied that style to the new ones. Still wrong.</p>
<p>Perhaps my correct paragraphs had somehow been modified? I selected both the correct and incorrect ones, and applied the style they were supposed to be in. They stayed determinedly different.</p>
<p>I tried fiddling with the rules manually, then re-applying the styles. The rulers reset to the tabbing defined in the styles, but the text continued to be indented incorrectly. I even tried creating a whole new style, in case the style definition had somehow become corrupt. Still the newly-type text would not match indents with the existing paragraphs.</p>
<p>Finally, I pondered the possibility that LibreOffice had a pretty severe formatting bug. I opened the document in IBM Lotus Symphony, which was forked from OpenOffice 1.x and (of course) reads and writes standard ODF documents. Hurrah! My paragraphs were all indented correctly!</p>
<p>I thought I was done. I made a few last edits, went to the top of the document, and refreshed the table of contents.</p>
<p>Oh dear.</p>
<p>Now my table of contents had garbage in, entries with a page number and no text, pointing at pages that had no headings on (including the front cover).</p>
<p>I cussed, saved the document, and quit Symphony. I opened the document in LibreOffice again, and refreshed the table of contents — now it looked right once more. I nervously scrolled down, and was somewhat surprised to discover that my paragraphs were all indented correctly. I hurriedly saved out a PDF before anything else went wrong.</p>
<p>So it was that I was forcibly reminded of how much I hate office suites, and WYSIWYG word processing in general. That well-known commercial office suite from Redmond is no better than the ODF gang; a few quick searches will unearth countless tales of horror involving corrupt files, misnumbered pages, font problems, and so on.</p>
<p>Meanwhile, I had another piece of documentation to start writing, and the thought of doing so in LibreOffice now filled me with a mixture of rage and dread.</p>
<p>I’m not a luddite, I quite like GUI software when it works. On the Mac, Apple’s iWork suite does a good job, at least with the kind of short document I find myself writing. However, I don’t have a Mac at work, so that wasn’t an option. So I returned to a piece of software I hadn’t used in 20 years: <a href="http://en.wikipedia.org/wiki/TeX">TeX</a>.</p>
<p>Madness? Perhaps. I appreciate that TeX is perhaps not a tool for everyone; though it’s really no worse than word processors of the 80s, which ordinary people nevertheless learned to use. I suspect that most people just don’t have the patience any more. They don’t want to sit down and learn something, which is why we have Microsoft Word, and why hardly any office documents even use the style system properly. Which, I suppose, is how a major formatting bug gets into released code without being noticed.</p>
<p>It turns out that quite a lot has happened in the TeX world in the last couple of decades. Obviously computers have gotten a lot faster; I remember watching my 8MHz Atari ST grinding away at my dissertation. As I recall, it took about a second per page to typeset my text to DVI; I would then wait about 2 seconds per page to flip through and inspect the pages in the DVI viewer.</p>
<p>These days the console output scrolls past too quickly to read. TeX dumps its output directly to PDF, which loads instantly into an integrated PDF viewer, which of course supports antialiased text. Plus, my screen has four times the resolution. So even before considering software features, it’s a very different experience these days.</p>
<p>So what of the software? Modern TeX supports OpenType fonts, and accepts diagrams in PDF or bitmap format. It handles Unicode, so you don’t need to use escapes for accented letters and other special characters. It can place hypertext links in your PDF documents, and use color and other effects. And yet, TeX documents written in 1980 are not merely readable today; they can still be typeset into beautiful documents.</p>
<p>So from my point of view TeX has a lot of advantages:</p>
<ul>
<li>The source files are plain text, so I can stick them in bzr for version control.</li>
<li>I can edit my documents with vim, meaning I can easily do things like searching and replacing control sequences and styles.</li>
<li>The output is of higher quality than any office suite. CTAN has a sample of text typeset by Microsoft Office, next to the same text <a href="http://www.ctan.org/documents/zen/zen.pdf">typeset by TeX</a>. While the differences are subtle, the overall effect is that the well-typeset text is simply less fatiguing to read.</li>
<li>Web page captures look a lot better in TeX than in a word processor. I can render a web page to PDF using <a href="http://code.google.com/p/wkhtmltopdf/">wkhtmltopdf</a>, crop out the bit I want, and pull it into my document — and because all the text stays as vectors, it’s searchable and looks good at any resolution. Much better than using a bitmap screen capture, and good luck pulling SVG or PDF into Office.</li>
<li>Similarly, I can draw diagrams in Inkscape, save as PDF, and pull straight into my document. Much better than trying to draw anything with the tools provided in an office suite.</li>
<li>I can be confident that what I write today will be readable, editable and printable for years to come, by anyone willing to put in the time to learn how to install and run TeX and edit a text file in a markup language that’s really no worse than HTML.</li>
<li>TeX stays out of the way. It’s like writing HTML or wiki pages; you don’t need to mess with menus and mice to start a new section, you just type section{My new section} and carry on.</li>
<li>I can write my own macros. For example, I quickly built a macro for web site references. I provide the URL and title; the macro handles formatting the title to show that it’s a link, making it clickable, pointing it at the URL, adding a footnote, and placing the URL in the footnote in monospaced font for people who have printed the document.</li>
<li>It scales. While office suites can start to crap out at a hundred pages, TeX can easily deal with thousand page reference manuals.</li>
<li>It’s bug-free. Core TeX hasn’t had a significant bug found in it in years, and the length of <a href="http://www.tug.org/texlive/bugs.html">the complete known bug list for the TeX Live DVD</a> speaks for itself.</li>
<li>It’s free software, it runs anywhere, and on today’s computers it’s fast.</li>
</ul>
<p>If necessary, I can always turn my TeX into <a href="http://plastex.sourceforge.net/">HTML</a>, RTF, ODF, or whatever. But for now, I’m going to try writing new documents in TeX.</p>
<p>Want to see what TeX can do these days? Try <a href="http://www.tug.org/texshowcase/winawer.pdf">some pages from a German chess book</a> typeset with it, or take a look at <a href="http://www.tsengbooks.com/">sample spreads from humanities books typeset with TeX</a>.</p>
]]></content></entry><entry><title type="html">Java: Call by reference, or call by value?</title><link href="https://lpar.ATH0.com/posts/2011/01/java-call-by-reference-or-call-by-value/"/><id>https://lpar.ATH0.com/posts/2011/01/java-call-by-reference-or-call-by-value/</id><published>2011-01-18T18:49:15+00:00</published><updated>2011-01-18T18:49:15+00:00</updated><summary>It’s a bit of both.</summary><content type="html"><![CDATA[<p>My attention was drawn to <a href="http://www.reddit.com/r/programming/comments/f1d7r/huge_war_over_whether_java_is_pass_by_reference/">a trainwreck of a discussion on Reddit</a>, which was triggered by another trainwreck of a discussion on an enterprise Java community web site.</p>
<p>The vexed question: Is Java pass by value, or pass by reference?</p>
<p>My short answer, carefully phrased: Java passes both object references and primitive types by value.</p>
<p>I’ll now unpack that answer and explain it, and talk about why there’s so much confusion. To do so, I need to go back to the very early days of programming…</p>
<p>Once general purpose computers were built, it was quickly discovered that it would be really useful if you could call a chunk of code multiple times, from multiple places.</p>
<p>For instance, most early CPUs (including popular 8 bit CPUs like the Z80 and 6502) didn’t have a general purpose multiply instructions. It was very useful to be able to write a piece of code that would multiply two numbers together and return the result. Because you’d want to multiply numbers a lot from different parts of your program, there needed to be a standard way for the code to know where to jump to when it was done computing the answer for you.</p>
<p>In the early days, this was done in one of two ways. One was to have the caller put a return address into a register. When the multiply routine was done, it would jump to whatever address was in that register, resuming the main program, which could then use the result of the multiplication.</p>
<p>The PDP-8 used a slightly different approach: the instruction to call a subroutine would store the return address in a reserved piece of memory immediately before the subroutine. The subroutine code would be called, would find the return address immediately before it in memory, and could therefore jump back there.</p>
<p>The problem, of course, is that soon programmers wanted their subroutines to be able to call other subroutines, or even call themselves. Both of these methods of passing return addresses failed to allow that. The PDP-8 approach was also ugly because it meant you couldn’t store subroutines in ROM.</p>
<p>So by the time of the PDP-11 and 6800, the call stack had been invented. With a call stack, when you called your multiply subroutine the address of the next instruction after the call was placed on the call stack automatically by the CALL instruction. The processor then jumped to the subroutine code. The code did its multiplication and put the result in a register as before, then pulled the address off the top of the stack and called it — hence jumping the CPU back to the point immediately after the CALL instruction. Popular 8-bit home computer CPUs including the 6502 and Z80 had hardware call stack support.</p>
<p>This was a big improvement, but still not ideal. The problem was, the subroutines and the code that called them had to agree on which registers to use for which values before the call, and which registers to find the results in after the call.</p>
<p>So later CPUs, like the 68000, added instructions to make it easy to push additional values onto the stack — not just return addresses. Now to call your multiply subroutine you’d push the two values onto the stack and CALL the subroutine. The subroutine would pull two values from the stack, multiply them, and push the result onto the stack before returning. Your code would then pull the result from the stack and use it. The combination of return address and subroutine parameters was called a stack frame. This call model was the one used on the PDP-11, and hence became the call model for the C programming language.</p>
<p>Now, stack-based parameters work well, but there’s a potential problem once you start dealing with values that can occupy a large amount of memory — such as strings. How do you pass a string to a subroutine?</p>
<p>This problem had been tackled before the invention of call stacks, of course. The general answer was that rather than copying the data around everywhere, you would just pass around a pointer to the start of the string. Not only is it a lot more efficient, you also don’t use up as much stack space — and in early computers, stack space was a significant concern.</p>
<p>So in most languages, when you passed an integer and a string to a function, what actually happened was that the value of the integer was placed on the stack; but a pointer to the string was placed on the stack, rather than the value of all the characters in the string itself. These two approaches were named ‘call by value’ and ‘call by reference’, respectively. (For example, see “<cite><a href="http://www.cs.colorado.edu/department/publications/reports/docs/CU-CS-016-73.pdf">Semantic Models of Parameter Passing</a></cite>”, Richard E. Fairley, 1973.)</p>
<p>When object-oriented programming was invented, the exact same issue applied to objects. The value of an entire object, with all its methods and fields, could be very large. Rather than placing the actual value of the object on the stack, instead a reference to the object was placed on the stack.</p>
<p>For now, though, let’s stick with strings. When you pass a string to a C function, the function may be able to change the text of the string, but it can’t change the fact that your string variable will still be looking for the string at the same memory address once the subroutine returns.</p>
<p>So <em>at the language level</em>, function parameters are conceptually passed by value, even though those values may actually be the addresses of an object or string. Hence <a href="http://en.wikipedia.org/wiki/The_C_Programming_Language_%28book%29">K&amp;R</a> states:</p>
<blockquote>
<p>One aspect of C functions may be unfamiliar to programmers who are used to some other languages, particularly Fortran. In C, all function arguments are passed “by value”. This means that the called function is given the values of its arguments in temporary variables rather than the originals.</p>
</blockquote>
<p>This description is clear for C, because C always makes pointers visible. Your string is manipulated using a <code>char *</code> pointer variable. It’s handed to the subroutine as a <code>char *</code>. It’s clear that the subroutine gets a copy of that pointer, not access to your pointer. Whatever the subroutine does, the caller’s pointer variable will still point to the same address when the subroutine is done.</p>
<p>Java handles parameter passing the same way in the JVM. Primitive values such as ints have their values placed on the stack; objects have the a copy of the address of the object placed on the stack. The called code can mess with the contents of the object, but when it returns, your variable will still point at the same object. That is, strictly speaking in Java the value of a variable is which object it refers to, not the value of the object.</p>
<p>This is, of course, a highly unusual definition of “value”.</p>
<blockquote>
<p>James Gosling goes to the bank and finds all the money has been emptied from his account. When he complains, the teller says “But your account has the same value it had yesterday — your account number still references the exact same account!”</p>
</blockquote>
<p>Another reason why people get confused about Java’s call semantics is that <em>you never actually see the addresses of objects</em>. Unlike in C, where you can mess with pointers (and indeed have to), Java hides that detail of the machine-level implementation. You’re simply not allowed to access the JVM’s pointers in the high level Java language. Variable names which are bound to the address of an object are automatically and invisibly dereferenced to the referenced object when necessary.</p>
<p>As I put it in <a href="http://lpar.ath0.com/2008/08/26/java-annoyance-final-parameters/">my earlier article about final parameters</a>, “The Java <code>Thing a</code> is really like C++ <code>Thing *a</code>, and Java’s <code>a.method()</code> is really C++’s <code>a-&gt;method()</code>, <strong>not</strong> <code>a.method()</code>.”</p>
<p>So in Java, you don’t need to explicitly dereference your object variable in order to call one of its methods; the compiler does it for you.</p>
<p>So when you pass a bunch of variables to a method, Java passes both the variables which were assigned object values and the variables which were assigned primitive values by value; it makes copies of all of them to give to the method code. It’s just that the variables which were assigned object values actually contain references to the object data, which will be automatically dereferenced when necessary. Most of the time this is very convenient, and it makes the language a lot safer by prohibiting various kinds of misbehavior with pointers.</p>
<p>So in Java,</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="line"><span class="cl"><span class="kt">int</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">3</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="n">String</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">&#34;three&#34;</span><span class="p">;</span><span class="w">
</span></span></span></code></pre></div><p>are two totally different operations. They only look like they’re the same concept because of some syntactic sleight-of-hand performed by the compiler.</p>
<p>If someone asks you what the value of y is after the above code runs, you might say that it’s the string “three”. In fact, though, the true value of y is a reference to the string “three”. You just never see that true value.</p>
<p>In C, on the other hand, the difference is explicit:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="kt">int</span> <span class="n">x</span> <span class="o">=</span> <span class="mi">3</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="kt">char</span> <span class="o">*</span><span class="n">y</span> <span class="o">=</span> <span class="s">&#34;three&#34;</span><span class="p">;</span>
</span></span></code></pre></div><p>The asterisk is the clue that two different sorts of things are being done here.</p>
<p>This distinction also comes up when considering the <code>==</code> operator. Java’s <code>==</code> compares the true underlying value of variables; <code>x == y</code> only if x and y are both references to the exact same object. To see if x and y have the same object value when dereferenced, you need to use a method such as <code>equals()</code> or <code>compareTo()</code>. Worse still, the default implementation of <code>equals()</code> is <code>==</code>, unless the class overrides it.</p>
<p>So what would call-by-reference look like? Well, in C we can do this:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="kt">int</span> <span class="n">x</span> <span class="o">=</span> <span class="mi">3</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="nf">f</span><span class="p">(</span><span class="o">&amp;</span><span class="n">x</span><span class="p">);</span>
</span></span></code></pre></div><p>This calls the function f, passing it a reference (the address of) the value in the variable x. The function is thus able to change the value in x, as it is then seen in the calling code.</p>
<p>This brings up a second reason why the discussion on Reddit is a trainwreck. People say that a language is call-by-value when a subroutine cannot change the value of a variable passed as a parameter. Unfortunately, because Java invisibly dereferences your object pointer variables, that’s not really true:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="line"><span class="cl"><span class="kd">static</span><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="nf">f</span><span class="p">(</span><span class="n">StringBuffer</span><span class="w"> </span><span class="n">o</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="n">o</span><span class="p">.</span><span class="na">delete</span><span class="p">(</span><span class="n">0</span><span class="p">,</span><span class="w"> </span><span class="n">o</span><span class="p">.</span><span class="na">length</span><span class="p">());</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="n">o</span><span class="p">.</span><span class="na">append</span><span class="p">(</span><span class="s">&#34;This is impossible.&#34;</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">public</span><span class="w"> </span><span class="kd">static</span><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="nf">main</span><span class="p">(</span><span class="n">String</span><span class="o">[]</span><span class="w"> </span><span class="n">args</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="n">StringBuffer</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">new</span><span class="w"> </span><span class="n">StringBuffer</span><span class="p">(</span><span class="s">&#34;Java is call by value.&#34;</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="n">f</span><span class="p">(</span><span class="n">x</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="n">System</span><span class="p">.</span><span class="na">out</span><span class="p">.</span><span class="na">println</span><span class="p">(</span><span class="n">x</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span></code></pre></div><p>In the above code, <code>f()</code> clearly changes what we’d colloquially call the “value of x”, as we see it at Java language level. However, it does so <em>without changing which object x points to</em>. To rephase in Java language specification terms, before the method call x is a reference to a string object which has the value “Java is call by value.” After the method call, x is still the same reference to the same string object, which now has the value “This is impossible.” But again, you never see the references which are being compared, so the situation is confusing.</p>
<p>Or as I wrote in <a href="http://lpar.ath0.com/2008/08/26/java-annoyance-final-parameters/">Java annoyance: final parameters</a>:</p>
<blockquote>
<p>It seems that the designers of Java wanted to make sure nobody confused their object pointers with the evil manipulable pointers of C and C++, so they decided to call them references instead. So Java books usually say that objects are stored as references, leading people to think that objects are passed by reference. They’re not, they’re passed by value, it’s just that the value [on the stack at JVM level] is a pointer.</p>
</blockquote>
<p>If you’re still confused at this point… well, I can’t say I blame you. We should probably both blame James Gosling.</p>
]]></content></entry><entry><title type="html">Multi-line comments considered harmful</title><link href="https://lpar.ATH0.com/posts/2010/12/multi-line-comments-considered-harmful/"/><id>https://lpar.ATH0.com/posts/2010/12/multi-line-comments-considered-harmful/</id><published>2010-12-31T16:05:02+00:00</published><updated>2010-12-31T16:05:02+00:00</updated><summary>Unless you’re using a really old C compiler, don’t use them.</summary><content type="html"><![CDATA[<p>Recently on the ruby-core mailing list, someone asked why Ruby doesn’t have multi-line comments. I did a few searches, and didn’t find much discussion of the evils of multi-line comments. I thought it was common knowledge that they were a bad thing and a historical mistake made by Kernighan and Ritchie, but apparently not. So, here’s my opinion on the matter.</p>
<p>Superficially, multi-line comments seem like a handy thing to have, especially if you often comment out blocks of code temporarily during development. However, as soon as you allow multi-line comments, you need to decide what to do about nested multi-line comments — that is, what should happen when the ‘start comment’ sequence occurs inside a comment.</p>
<p>Option 1 is to allow it and make it not special. This is bad because it makes it very easy to end up with a run-away comment:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="cm">/* set variables
</span></span></span><span class="line"><span class="cl"><span class="cm">param = 0
</span></span></span><span class="line"><span class="cl"><span class="cm">/* set maximum size */</span>
</span></span><span class="line"><span class="cl"><span class="n">maxs</span> <span class="o">=</span> <span class="mi">100</span>
</span></span></code></pre></div><p>Here ‘param’ ends up unset. This kind of bug can be really hard to locate.</p>
<p>Option 2 is to allow the start-comment sequence within a comment, and make comment pairs stack, so you need as many end-comment sequences as start-comment sequences. This at least makes errors like the above cause a compile-time failure, but it still makes them a pain to locate; you end up having to use something like vim’s ‘%’ command to play match-the-comment-delimiters until you spot which pair is mismatched. That’s no fun, especially once your comments contain pages of documentation. Ask a Java programmer…</p>
<p>Option 3 is to disallow nested comments, in which case multi-line comments can’t be used to comment out blocks of code which contain multi-line comments. That makes them pretty useless for temporary disabling of code; it would also cripple their use in rdoc.</p>
<p>Single-line comments have none of the above problems. You always know the comment will end when the next line starts. You can always comment out a block of code, no matter how many comments or comments-within-comments it contains. You never get runaway comments, and you never have to match up comment delimiters. The only downside to single-line comments is that it’s harder to comment out and un-comment-out multiple lines. That’s easily solved by using any good text editor.</p>
<p>All of which is why C++ introduced single-line comments, and C99 added them to regular C.</p>
<p>So in short, multi-line comments have no significant advantages, make parsing harder, and make errors more likely. I think Matz was entirely right not to put them in Ruby. As a rule, the only place I use multi-line comments is for JavaDoc, and that’s only because I have to.</p>
]]></content></entry><entry><title type="html">Mandelbrot remembered</title><link href="https://lpar.ATH0.com/posts/2010/10/mandelbrot-remembered/"/><id>https://lpar.ATH0.com/posts/2010/10/mandelbrot-remembered/</id><published>2010-10-17T16:37:26+00:00</published><updated>2010-10-17T16:37:26+00:00</updated><summary>The hours I spent drawing fractals.</summary><content type="html"><![CDATA[<p>Like many other people, I first saw the Mandelbrot Set in an issue of Scientific American in 1985. Before long I had written a program in BBC BASIC to perform the computation, and set my BBC Micro’s 2MHz 6502 churning away. Because it took so long to render an image — even at the Beeb’s meager 256x160 resolution in 8 non-blinking colors — I made the code preview by rendering every 16th pixel, then every 8th, and then finally fill in all the points. As well as Mandelbrot and Julia sets, I experimented a lot with Lindenmayer systems and generation of realistic-looking plants.</p>
<p>About a year later I upgraded to an Atari ST, with an 8MHz 68000 and the ability to handle 320x200 resolution in 16 colors. I had Computer Concepts’ FaST BASIC, a version of BBC BASIC on a cartridge for the ST, and soon had fractals rendering on the Atari. I built a fairly elaborate menu and dialog system for adjusting parameters, and added mouse-based selection and zooming. Rendering speed was improved, but it still took a few minutes to put together a complete image.</p>
<p>The trend continued over the next decade: every time I got access to a newer and faster computer, one of the first things I would do would be to see how quickly it could draw fractals. This continued until the mid 90s, at which point I could move my mouse around the Mandelbrot set and see the corresponding Julia sets drawn in real time.</p>
<p>By then, fractal imagery had become commonplace on album covers and posters. My fascination waned. Yet Benoît Mandelbrot’s influence stayed with me; his fractal geometry had changed my view of the world. One single simple equation, simple enough for a teenager to understand — and yet, hidden inside it was infinite complexity. Simple iteration could generate images that looked like objects from the natural world. Entire universes could be encoded in a tiny algorithm, if you were clever enough.</p>
]]></content></entry><entry><title type="html">Wave goodbye</title><link href="https://lpar.ATH0.com/posts/2010/08/wave-goodbye/"/><id>https://lpar.ATH0.com/posts/2010/08/wave-goodbye/</id><published>2010-08-05T14:47:23+00:00</published><updated>2010-08-05T14:47:23+00:00</updated><summary>Another product for the Google Graveyard.</summary><content type="html"><![CDATA[<p>So, <a href="http://googleblog.blogspot.com/2010/08/update-on-google-wave.html">farewell then, Google Wave</a>, perhaps the ultimate example (for now) of what happens when you let a bunch of software engineers design a product.</p>
<p>Good product design starts with a single problem. The product becomes a way to solve that problem. Technologies are developed and added strictly as needed to solve the core problem. Keeping that focus is perhaps the hardest part of product design; it’s always tempting to add one more feature or option, often simply because it’s technically easy to do so.</p>
<p>Another way of looking at it is that there’s a circular flow:</p>
<ol>
<li>Marketing finds out what the customer needs.</li>
<li>Designers develop the concept and write it up.</li>
<li>Product management plans development.</li>
<li>Engineering builds the product.</li>
<li>Technical writers fill out the documentation using input from the original design documents and from engineering.</li>
<li>Marketing takes the finished product to the customer.</li>
</ol>
<p>I’m simplifying; in reality there’s continuous information flow between the stages. They’re all important, though — for instance, if you marginalize design and let marketing dictate directly to product management and engineering, you can get <a href="/2010/02/11/google-buzz/">a disaster like Buzz</a>.</p>
<p>With engineering-driven development, the flow is linear, and rather different:</p>
<ol>
<li>Engineering comes up with a bunch of cool technologies, and throws them together into a big framework.</li>
<li>Product management comes up with some ideas for what the whole mess might be able to do, based on comparing functionality with already successful products.</li>
<li>Designers apply some lipstick to the pig, often by making it look like something else that’s familiar.</li>
<li>Technical writers look at the source code and the minimal design notes from engineering, and try to come up with some kind of documentation.</li>
<li>The whole mess gets thrown to Marketing, who try to sell it to the end user as the next great revolution in something-or-other.</li>
<li>After a year when almost nobody is using it, it’s quietly buried and never spoken about again in polite company.</li>
<li>Any technologies that people seemed to particularly like are incorporated into other products, usually after renaming them to disguise their embarrassing past.</li>
</ol>
<p>A special case of the above is when engineers decide that an existing product needs to be reimplemented using a new and more fashionable programming language or software technology.</p>
<p>I’ve seen quite a lot of engineering-driven development over the years. Without naming names, there’s a division at IBM that has a long history of it; you might be able to think of a few of their dead technology-driven products.</p>
<p>It’s not that engineering-driven development results in products that are useless. They usually do perform useful functions, it’s just that they don’t do any of them particularly well — or at least, not as well as products that were actually designed to solve specific problems.</p>
<p>So it was with Google Wave. It was a pretty good way to collaborate on documents, but  it was much more complicated and harder to learn than Google Docs. It was a neat tool for D&amp;D games, but not as good as (say) <a href="http://www.fantasygrounds.com/">Fantasy Grounds</a>. It was a replacement for e-mail, except nobody really wanted their e-mail replaced. It could help you plan when to have a meeting, except it was much more complicated than (say) <a href="http://www.presdo.com/">Presdo</a>. It was a good way to chat with friends, except it didn’t connect to XMPP and you had to log in to it. It was a useful tool for project planning, but lacked the focus of (say) <a href="http://basecamphq.com/">BaseCamp</a>. The live simultaneous updates feature was cool for working on a document, but the UI was much more cluttered and intrusive than Google’s own EtherPad.</p>
<p>The last of these comparisons indicates another sad feature of engineering-driven products: they often result in better products being killed, because the older narrowly-focused product with last year’s technology is perceived as competing with the big new project with all the cool stuff in it.</p>
<p>If you ask an engineer why an engineering-driven product failed, they’ll usually say that it’s all because <a href="http://techhaze.com/2010/08/r-i-p-google-wave/">marketing failed to communicate the product’s awesomeness</a> to the world. They understand the product, and they’re sure that if only everyone else could understand it, they’d love it too. They vow to make the next product even more awesome, by sticking even more disparate technologies into it. And so the cycle continues for as long as engineers are allowed to design products, until the company goes bust.</p>
<p>There are rumors that Google are working on a competitor to Facebook, perhaps focused around social gaming. I do hope that this time, they’re not letting engineers design the product, because Facebook could really use some open competition.</p>
]]></content></entry><entry><title type="html">It&amp;#39;s Time and Energy Wasting Time</title><link href="https://lpar.ATH0.com/posts/2010/03/its-time-and-energy-wasting-time/"/><id>https://lpar.ATH0.com/posts/2010/03/its-time-and-energy-wasting-time/</id><published>2010-03-14T16:12:23+00:00</published><updated>2010-03-14T16:12:23+00:00</updated><summary>DST is a stupid idea.</summary><content type="html"><![CDATA[<p>Once again, it’s time for every clock in America to be messed with. According to the most optimistic estimates from the Department of Energy, this will provide a savings of <a href="http://www.usnews.com/blogs/robert-schlesinger/2009/03/05/daylight-saving-time-is-supposed-to-save-energy--does-it-the-answer-is-mixed.html">0.03%</a> on the country’s annual electricity consumption. According to <a href="http://ideas.repec.org/p/iza/izadps/dp2704.html">actual measurements from a study in Australia</a>, it’ll achieve nothing. According to <a href="http://www.nber.org/papers/w14429">an NBER study of Indiana’s transition to observing DST</a>, DST increases electricity usage by 1%. So, either DST achieves almost nothing, or it wastes energy, we’re not quite sure.</p>
<p>However, energy usage isn’t the whole story. <a href="http://www.journals.elsevierhealth.com/periodicals/sleep/article/PIIS1389945700000320/abstract">According to studies</a> the DST shift will cause around 17% more car accidents on Monday, with a smaller increase in the fall because it’s easier to sleep in than to get up early.</p>
<p>DST doesn’t benefit farmers either, in spite of what you might have heard. <a href="http://article.nationalreview.com/print/?q=N2JhMmQxNjRkNjljZTdmNDM5MzFhNjcwMDc0YjE4ZDE=">They lobbied against its introduction</a>. Cattle don’t care what the clocks say, so DST just means the farmer has to get up and milk them at a different clock time.</p>
<p>For IT people, of course, DST is more annoying. It means checking every system that keeps time, to verify that it made the change on the correct date, and adjusting systems that don’t adjust themselves. That’s assuming your government doesn’t decide to change the date of the DST switchover, like <a href="http://news.cnet.com/Daylight-saving-change-could-confuse-gadgets/2100-1041_3-5823792.html">the Bush administration decided to</a>, causing hundreds of millions of dollars to be spent patching embedded systems, servers and desktops. (Since Java, Linux and IBM Lotus Domino all use their own independent time zone rule databases, I had to apply three separate fixes to some servers.)</p>
<p>Even non-IT people are <a href="http://www.rasmussenreports.com/public_content/lifestyle/general_lifestyle/march_2010/47_don_t_think_daylight_saving_time_worth_the_hassle">starting to catch on to the fact that DST is an annoying waste of time and energy</a>. Can we get rid of this stupid practice, please?</p>
]]></content></entry><entry><title type="html">8001050F</title><link href="https://lpar.ATH0.com/posts/2010/03/8001050f/"/><id>https://lpar.ATH0.com/posts/2010/03/8001050f/</id><published>2010-03-02T14:40:27+00:00</published><updated>2010-03-02T14:40:27+00:00</updated><summary>Leap year breaks DRM.</summary><content type="html"><![CDATA[<p>As <a href="http://lpar.ath0.com/2009/03/16/chronological-pitfalls/">I’ve written before</a>, date and time calculations are surprisingly difficult. What’s more, even the bits that aren’t difficult often get messed up. <a href="http://blog.us.playstation.com/2010/03/playstation-network-service-restored/">Sony have just demonstrated this</a>.</p>
<p>Apparently, a <a href="http://www.neogaf.com/forum/showthread.php?t=388872">firmware bug in the real time clock in some models of PS3</a> lead the RTC to think that 2010 is a leap year. This confused the PS3’s OS, which was then unable to connect to PlayStation Network. This, in turn, caused havok with all kinds of games, even single player games with no network play, because PS3 trophy support requires network connectivity. It also disabled all DRM-protected content. Sony advised people <a href="http://blog.us.playstation.com/2010/03/latest-info-on-playstation-network-status/">not to use their PS3</a> until engineers could find a fix, as content might get corrupted. In the event, the ‘fix’ was to wait until the next day, when the RTC moved to a valid (but incorrect) date, and the OS would once again recognize it.</p>
<p>I happened to be using my PS3 when the date hit March 1st 2010 UTC (or February 29th 2010 PS3 time, you might say). I was playing “inFAMOUS”, a game by Sucker Punch. I got an error message saying I’d been logged out of PSN; a little while later I got a trophy sync error. I finished the game that evening, so I qualified for more trophies, but of course I won’t have gotten them. I didn’t particularly care about the trophies, and PSN failures aren’t exactly unheard of, so I thought no more of the issue.</p>
<p>Not all games are as well-written as Sucker Punch’s, however. Many people reported that “Heavy Rain” crashed on startup; apparently it assumes that if the network is enabled, the PSN trophy server must be reachable. “Flower” also died.</p>
<p>There are a few observations I’d make about this whole situation:</p>
<p>Firstly, yes, it’s a stupid error to find in code. However, if you read <a href="http://catless.ncl.ac.uk/Risks">RISKS Digest</a> you’ll see the same error happening in a big system every few years.</p>
<p>Secondly, the scale of the failure was undoubtedly due to the system brittleness required for DRM. The existence of time-limited rentals requires that the DRM system not trust the system date, and fail to authenticate if the date appears incorrect. This means that even indefinite rentals (which are dishonestly called “purchases”) ended up with copy protection errors when you tried to run them; people reported that none of their downloaded games worked.</p>
<p>Thirdly, this kind of slapdash QA is all too typical of the video game industry nowadays. My impression is that the quality of game software is getting worse, now that consoles are assumed to have an Internet connection. It used to be expensive to recall and replace faulty discs, so games spent a long time in QA; now, the developers will just throw a faulty game out so long as it’s more or less playable, and plan to fix it with a point release. Games even get released to consoles with sound that doesn’t work properly (“The Orange Box” for PS3, for example). Sometimes a patch eventually fixes the problems, sometimes it doesn’t.</p>
]]></content></entry><entry><title type="html">The case of the Null Empty Nothing</title><link href="https://lpar.ATH0.com/posts/2009/12/the-case-of-the-null-empty-nothing/"/><id>https://lpar.ATH0.com/posts/2009/12/the-case-of-the-null-empty-nothing/</id><published>2009-12-01T23:56:21+00:00</published><updated>2009-12-01T23:56:21+00:00</updated><summary>The three billion dollar mistake?</summary><content type="html"><![CDATA[<p>Most programming languages have a null value which is used to indicate the absence of a valid value. Lisp and Ruby have <code>nil</code>, Python has <code>None</code>, Perl has <code>undef</code>, and so on.</p>
<p>LotusScript is a bit different. It’s modeled on Microsoft’s Visual BASIC, a decision that probably seemed sensible in the pre-JavaScript early 90s when Lotus picked a scripting language for Notes. As a result, LotusScript has three different null values. This can lead to some unexpected run-time crashes.</p>
<p>The first null value is <code>Empty</code>. This is the value of a variable of type <code>Variant</code> that has not yet had a value assigned. You can’t directly assign something to be Empty, but you <em>can</em> do something like this:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-vb" data-lang="vb"><span class="line"><span class="cl"><span class="k">Dim</span> <span class="n">empty</span> <span class="ow">As</span> <span class="kt">Variant</span>
</span></span><span class="line"><span class="cl"><span class="n">x</span> <span class="o">=</span> <span class="n">empty</span> <span class="c">&#39; x is now empty too
</span></span></span></code></pre></div><p>You can’t make non-Variant variables Empty; you’ll get a run-time error if you try.</p>
<p>The second null value is <code>Null</code>. It’s also used with Variants. Whereas Empty is the default null value of a Variant, Null is the usual null value resulting from an assignment expression. That is, it’s the null value you would typically return from a function that returns a Variant, in order to indicate an error, exception or missing value to the caller. (Though as noted above, you could return Empty if you really wanted to.)</p>
<p>Then there’s the third null value: <code>Nothing</code>. Nothing is primarily used with non-Variant variables. For example, NotesView.GetDocumentByKey will return Nothing if the document isn’t found. Also, if you declare an object variable but don’t initialize it, it is set to Nothing by default. Unlike Empty, however, you can directly assign variables to have a value of Nothing. So basically, it plays the role of both Null and Empty, but for object variables.</p>
<p>But while Nothing is primarily used with non-Variant types, you can also assign Notes objects to Variant variables, which means that Variants <em>can</em> end up being Nothing, depending on your code. Which led to my discovering a couple of interesting pitfalls.</p>
<p>To make life exciting, each kind of null in LotusScript has a different way of testing for it. <code>Isnull</code> and <code>Isempty</code> test for Null and Empty values respectively; but for Nothing, the syntax to check is <code>expr Is Nothing</code>.</p>
<p>(Why? My guess is that when object orientation was bolted onto BASIC, the developers at Microsoft decided to provide for null object references by creating a special predefined object called Nothing, because that was the easiest thing to code. Probably nobody cared that the language already had Null and Empty. Similarly, adding a new “Is” operator was probably easier than making the existing comparison operator work on objects.)</p>
<p>Not only is the syntax different for testing Nothing values, the behavior is different too. While Isnull and Isempty are safe when passed Nothing, <code>expr Is Nothing</code> will crash with a run-time error if the expression is Null or Empty. So if you have a Variant which may contain Nothing as well as either Empty or Null, you need to test it with Isnull and/or Isempty <em>before</em> testing for Nothing.</p>
<p>A second pitfall is that you can print Null and Empty values — they display as “Null” and &quot;&quot; (empty string) respectively — but a Nothing value will cause a run-time error if you try to print it.</p>
<p>The two pitfalls can combine, of course. If you want to print or log your Variant’s value for debugging purposes, you need to check for Nothing in order to avoid a crash when printing; however, that means you need to check for Null and Empty first, to avoid having the check for Nothing crash. So you end up with:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-vb" data-lang="vb"><span class="line"><span class="cl"><span class="k">If</span> <span class="n">Isnull</span><span class="p">(</span><span class="n">v</span><span class="p">)</span> <span class="ow">Or</span> <span class="n">Isempty</span><span class="p">(</span><span class="n">v</span><span class="p">)</span> <span class="k">Then</span>
</span></span><span class="line"><span class="cl">  <span class="n">Print</span> <span class="n">v</span>
</span></span><span class="line"><span class="cl"><span class="k">Elseif</span> <span class="n">v</span> <span class="ow">Is</span> <span class="k">Nothing</span> <span class="k">Then</span>
</span></span><span class="line"><span class="cl">  <span class="n">Print</span> <span class="s">&#34;v is Nothing&#34;</span>
</span></span><span class="line"><span class="cl"><span class="k">Else</span>
</span></span><span class="line"><span class="cl">  <span class="n">Print</span> <span class="n">v</span>
</span></span><span class="line"><span class="cl"><span class="k">End</span> <span class="k">If</span>
</span></span></code></pre></div><p>Here’s a summary:</p>
<table>
	<thead>
			<tr>
					<th>Null value</th>
					<th>Applies to</th>
					<th>Purpose</th>
					<th>Test for it using</th>
					<th>Outputs as</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td><code>Empty</code></td>
					<td>Variants</td>
					<td>Value of uninitialized Variant</td>
					<td><code>IsEmpty(expr)</code></td>
					<td>&quot;&quot;</td>
			</tr>
			<tr>
					<td><code>Null</code></td>
					<td>Variants</td>
					<td>Indicates an error, exception or missing value</td>
					<td><code>Isnull(expr)</code> or <code>expr = Null</code></td>
					<td>“Null”</td>
			</tr>
			<tr>
					<td><code>Nothing</code></td>
					<td>Variants or object variables</td>
					<td>Unitialized object, error, exception or missing value</td>
					<td><code>expr Is Nothing</code></td>
					<td>Run-time error</td>
			</tr>
	</tbody>
</table>
<p>On the bright side, it could be worse, as Visual BASIC has four more null values to worry about: <code>Missing</code>, <code>vbNullString</code>, <code>vbNull</code>, and <code>vbNullChar</code>.</p>
]]></content></entry><entry><title type="html">RPM cheat sheet</title><link href="https://lpar.ATH0.com/posts/2009/11/rpm-cheat-sheet/"/><id>https://lpar.ATH0.com/posts/2009/11/rpm-cheat-sheet/</id><published>2009-11-20T20:08:19+00:00</published><updated>2009-11-20T20:08:19+00:00</updated><summary>Common tasks and how to achieve them.</summary><content type="html"><![CDATA[<p>The worst thing about commercial Linux is RPM. I can never remember the command line incantations required for even fairly simple tasks.</p>
<p>While yum eventually takes away the pain of applying software updates — so long as you’re not in a hurry — there are all kinds of other tasks it doesn’t handle. I therefore rely on an RPM cheat sheet I’ve assembled over the years. Here’s a copy for anyone else who might find it useful.</p>
<table>
	<thead>
			<tr>
					<th>Command</th>
					<th>Purpose</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td><code>rpm -e package-1.2.3-gm</code></td>
					<td>Erase named package from system</td>
			</tr>
			<tr>
					<td><code>rpm -i package-1.2.3-gm.rpm</code></td>
					<td>Install package file into system</td>
			</tr>
			<tr>
					<td><code>rpm -U package-1.2.3-gm</code></td>
					<td>Upgrade package</td>
			</tr>
			<tr>
					<td><code>rpm -F package1 package2</code></td>
					<td>Upgrade packages to latest versions in an appropriate order</td>
			</tr>
			<tr>
					<td><code>rpm -Fvh *</code></td>
					<td>Upgrade a bunch of packages from the matching RPM files</td>
			</tr>
			<tr>
					<td><code>rpm -q package</code></td>
					<td>Returns full name and version of installed package</td>
			</tr>
			<tr>
					<td><code>rpm -qp package.rpm</code></td>
					<td>Same for a non-installed package</td>
			</tr>
			<tr>
					<td><code>rpm -qi package</code></td>
					<td>Returns misc details about package</td>
			</tr>
			<tr>
					<td><code>rpm -qpi package.rpm</code></td>
					<td>Same for a non-installed package</td>
			</tr>
			<tr>
					<td><code>rpm -qa</code></td>
					<td>List all installed packages</td>
			</tr>
			<tr>
					<td><code>rpm -qf file</code></td>
					<td>Which package put this file here?</td>
			</tr>
			<tr>
					<td><code>rpm -ql package</code></td>
					<td>List of files in an installed package</td>
			</tr>
			<tr>
					<td><code>rpm -qlp package.rpm</code></td>
					<td>Same for files in a non-installed package</td>
			</tr>
			<tr>
					<td><code>rpm -qRl package</code></td>
					<td>List dependencies of an installed package</td>
			</tr>
			<tr>
					<td><code>rpm -qR package.rpm</code></td>
					<td>List dependencies of a non-installed package</td>
			</tr>
			<tr>
					<td><code>rpm -ivh package.src.rpm</code></td>
					<td>Install a source RPM, spec goes into /usr/src/RedHat/SPECS</td>
			</tr>
			<tr>
					<td><code>rpmbuild -ba package.spec</code></td>
					<td>Build from installed source installed</td>
			</tr>
	</tbody>
</table>
<p>Also, to list installed software packages in order of size, with descriptions:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sh" data-lang="sh"><span class="line"><span class="cl">rpm -qa --queryformat<span class="o">=</span><span class="s2">&#34;%10{size} %{NAME} - %{SUMMARY}n&#34;</span> <span class="p">|</span> sort -k1,1nr
</span></span></code></pre></div><h4 id="notes">Notes:</h4>
<ul>
<li>Wildcards work with filenames, but not with package names.</li>
<li>Any package filename argument can be replaced with a full URL of where to get the package from.</li>
<li><code>--test</code> to see what a command would do without actually doing it.</li>
<li><code>-v</code> for verbose output.</li>
</ul>
]]></content></entry><entry><title type="html">Documentation as an indicator of code quality</title><link href="https://lpar.ATH0.com/posts/2009/09/documentation-as-an-indicator-of-code-quality/"/><id>https://lpar.ATH0.com/posts/2009/09/documentation-as-an-indicator-of-code-quality/</id><published>2009-09-25T20:00:04+00:00</published><updated>2009-09-25T20:00:04+00:00</updated><summary>If it’s worth running, it’s worth documenting.</summary><content type="html"><![CDATA[<p>I often have to shunt around Lotus Domino databases, as well as all kinds of log files and bundles of XML data. I’ve got a cable modem connection to my home office, but still, uploads can take a while. So data compression is still important to me, and the newer LZMA algorithm can make a big difference.</p>
<p>Here’s an example using a random database template:</p>
<table>
	<thead>
			<tr>
					<th>bytes</th>
					<th>file</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td>9437184</td>
					<td>dct.ntf</td>
			</tr>
			<tr>
					<td>2618157</td>
					<td>dct.ntf.gz</td>
			</tr>
			<tr>
					<td>2256744</td>
					<td>dct.ntf.bz2</td>
			</tr>
			<tr>
					<td>1806715</td>
					<td>dct.ntf.lz</td>
			</tr>
			<tr>
					<td>1784916</td>
					<td>dct.ntf.7z</td>
			</tr>
			<tr>
					<td>1775175</td>
					<td>dct.ntf.lzma</td>
			</tr>
	</tbody>
</table>
<p>Switching from bzip2 to LZMA is a bigger improvement than the switch from gzip to bzip2 was. However, notice that there are three LZMA-compressed files. The first was created using lzip; the second, using 7-zip; the third, using <a href="http://tukaani.org/lzma/">lzma-utils</a>, now renamed xz or <a href="http://tukaani.org/xz/">xz-utils</a>.</p>
<p>I don’t like that there are competing LZMA archive formats, but since that’s the world I’m in, I decided I had to make a choice which one to use. The obvious answer is to go with the one with the best compression, but in my view 0.3% isn’t enough of a difference to make that the sole criterion. So I’ve tried my usual approach to evaluating open source software: I’ve looked at the user interface and documentation.</p>
<p>7-zip fails immediately because it doesn’t behave like a Unix program. It produces 10 lines of output when successfully compressing a single file, and there doesn’t seem to be any way to get it to shut up. So, it’s a two horse race.</p>
<p>The xz-utils site has no documentation I can find. Searching the Ubuntu documentation site locates <a href="http://manpages.ubuntu.com/manpages/karmic/en/man1/xz.1.html">the xz man page</a>, however.</p>
<p>In contrast, lzip’s web site has a link to go straight to <a href="http://nongnu.askapache.com/lzip/manual/lzip_manual.html">the user manual and tutorial</a>. (Yes, there’s also a standard Unix man page.)</p>
<p>Comparing the two, I see that xz has many more options. It has all kinds of tweaks to specify how much memory it uses, tweak various internal details of the LZMA algorithm, and filter the data. None of these options are adequately explained. To quote Ted Nelson quoting <a href="http://en.wikipedia.org/wiki/Roger_Gregory_%28programmer%29">Roger Gregory</a>, “An option means the programmer didn’t have a clear idea of what the module was supposed to do.” Or as <a href="http://www.sensible.com/">Steve Krug</a> puts it, “Don’t make me think.”</p>
<p>In contrast, lzip’s user interface is much simpler, and closer to the Unix philosophy of “do one thing, and do it well”. The only two tweaks to the LZMA algorithm lzip provides are adequately explained if you know the basics of how compression algorithms tend to work, and there’s a table showing how they correspond to the compression levels -0 to -9. The only borderline gratuitous option is to split the compressed file into chunks, and that’s at least a useful one. It also gets the SI units right.</p>
<p>So, lzip wins by a landslide on UI and documentation.</p>
<p>You might be thinking I’m being superficial here; surely documentation alone isn’t a good way to evaluate software? So this time, I took a look at the source code.</p>
<p>Lzip’s source is around 5,680 lines of code (excluding comments), supplied with an autoconfigure script and test suite. It compiles to a 85,753 byte binary.</p>
<p>XZ Utils’ source is around 31,183 lines of code (excluding comments). It compiles to a 516,779 byte binary.</p>
<p>In XZ’s favor, its source code is much better commented (30% vs 10% comment-to-code ratio). Then again, at 6× the size, it had better be. So on balance, I think lzip still wins.</p>
<p>So once again, my “look at the documentation” heuristic worked. The question is, are there any good exceptions to prove the rule? That is, examples of excellent code that has terrible documentation?</p>
<p><strong>Update:</strong> The GNU project decided to go with xz rather than lzip, of course, and implemented xz support rather than lzip support in GNU tar.</p>
]]></content></entry><entry><title type="html">Small, cheap and ubiquitous</title><link href="https://lpar.ATH0.com/posts/2009/08/small-cheap-and-ubiquitous/"/><id>https://lpar.ATH0.com/posts/2009/08/small-cheap-and-ubiquitous/</id><published>2009-08-31T14:26:39+00:00</published><updated>2009-08-31T14:26:39+00:00</updated><summary>The metaverse isn’t happening.</summary><content type="html"><![CDATA[<p>WIRED magazine has finally noticed that the long term trend for technology is <a href="http://www.wired.com/gadgets/miscellaneous/magazine/17-09/ff_goodenough?currentPage=all">cheap, simple and ubiquitous</a>.</p>
<p>Back in the 1990s everyone was excited about “cyberspace”. We were going to build a whole new world in virtual reality, with virtual banks, virtual shopping malls, and virtual libraries. We would drive around in virtual cars and be represented by 3D avatars that looked just like us. Even the web would be replaced with cyberspace — remember VRML?</p>
<p>I always thought that was a stupid idea. We already have a world that’s far higher resolution and more interactive than can possibly be experienced via a screen, or even via special goggles and exotic input devices. Rather than have massively powerful computers try to simulate a virtual world, what made more sense was for lots of small and cheap computers to become ubiquitous in the real world we already have.</p>
<p>Rather than a virtual library, I want a real library where the books all have RFID, and an augmented reality application can just guide me to the book I want. Rather than a virtual mall, let me search the real mall from my phone.</p>
<p>There’s certainly a place for virtual worlds and cutting-edge hardware; broadly speaking, that place is the video game industry, at least as far as the average person is concerned.</p>
<p>Ask a photographer what the best camera is, and he’ll probably tell you: it’s the camera you actually have with you. A cheap camera in your pocket is better than a $3000 SLR at home. Similarly, you’ll get more done at the coffee shop with the $300 laptop that you carry in your shoulder bag than the sleek 17″ behemoth you leave at home.</p>
]]></content></entry><entry><title type="html">Last night I dreamed of mainframes</title><link href="https://lpar.ATH0.com/posts/2009/07/last-night-i-dreamed-of-mainframes/"/><id>https://lpar.ATH0.com/posts/2009/07/last-night-i-dreamed-of-mainframes/</id><published>2009-07-10T19:35:17+00:00</published><updated>2009-07-10T19:35:17+00:00</updated><summary>This web site is named after a piece of mainframe terminology.</summary><content type="html"><![CDATA[<p>This week saw the <a href="http://www.share.org/Volunteers/ProgramsandProjects/ArchitectureProgram/CICSProject/tabid/168/Default.aspx">40th anniversary of IBM CICS</a>, the <a href="http://en.wikipedia.org/wiki/CICS">Customer Information Control System</a>. It had 7 releases before being re-engineered as CICS TS (Transaction Server); <a href="http://www-01.ibm.com/software/htp/cics/">CICS TS</a> has just seen the release of version 4.1. I’m going to take a guess that they don’t use agile software development methods in the CICS department at Hursley. Yet for all its age, CICS keeps up with the times: it now supports Atom feeds, Java, and <a href="http://soa.sys-con.com/node/837728">Web Services</a> — REST as well as SOAP.</p>
<p>Of course, that’s not why 90% of Fortune 500 companies use it. It’s one of those rather dull products that runs invisibly, year after year, processing millions of transactions reliably and actually getting the answers right. Key parts of its behavior are formally specified in Z notation. It’s the back-end software that processes your ATM transactions and airline reservations. Yet in spite of that, it seems to have a fan following — there’s an <a href="http://www.facebook.com/group.php?gid=4907254593">I ♥ CICS group</a> on Facebook. If you’re wondering what you’re missing, the University of Maryland has some <a href="http://www.helpdesk.umd.edu/systems/mvs/general/88/">screenshots of their CICS system</a>. Of course, these days you can do your CICS development using Eclipse and give your applications a web interface.</p>
<p>Another really old IBM product that’s still in service is <a href="http://www-01.ibm.com/software/data/ims/">IMS</a>, a database so old that it predates the relational model, let alone SQL. Built to track all the parts required to build the Saturn V rocket for the Apollo moon missions, it’s still being used today, 41 years later. It’s the product you use if your database is 60 terabytes in size. After CICS has processed your ATM transactions, chances are at some point the movement of the money will be noted in the Federal Reserve’s massive IMS database.</p>
<p>Like CICS, IMS has kept up with the times, with <a href="http://www-01.ibm.com/software/data/ims/toolkit/">support added for web technologies</a>. Ironically, the fact that XML is hierarchical makes IMS a better match for XML processing than the <a href="http://xml.sys-con.com/node/190434">more modern relational databases</a> — you can translate your entire document directly into IMS fields, preserving the hierarchical element structure directly, and then perform XPath queries via IMS’s JDBC interface.</p>
<p>I don’t use CICS or IMS myself. I only occasionally use a <a href="http://en.wikipedia.org/wiki/IBM_5250">5250</a> emulator, mostly to perform <a href="http://www-03.ibm.com/systems/i/">System i</a> administration tasks; I haven’t logged in to z/OS in over a year. The mainframe I do use runs Linux, and I like it that way — Unix is quite old enough for me. Yet there’s something oddly fascinating about these mainframe products and their continued existence; it’s almost like discovering there are trilobites still living in the back of your filing cabinet.</p>
]]></content></entry><entry><title type="html">Chronological pitfalls</title><link href="https://lpar.ATH0.com/posts/2009/03/chronological-pitfalls/"/><id>https://lpar.ATH0.com/posts/2009/03/chronological-pitfalls/</id><published>2009-03-16T19:19:59+00:00</published><updated>2009-03-16T19:19:59+00:00</updated><summary>Handling time zones is hard.</summary><content type="html"><![CDATA[<p>Since the US just changed time zone, and the EU will be changing time zone soon, it seems like a good time to refresh an old posting of mine about dates and times, and how hard it can be to do the right things with them in software.</p>
<p>I’ve spent a lot of my career in the computer industry working on computer-based calendar systems and organizers of various kinds. Here are a few pitfalls to be aware of.</p>
<ul>
<li><strong>Time zones expressed as letters (e.g. CST) are ambiguous, and hence useless.</strong></li>
<li><strong>Time zone offsets are not always an exact number of hours.</strong></li>
<li><strong>Both 00:00 and 24:00 are valid times</strong> (as per ISO) and refer to different moments of a given date. 00:00 is the midnight which begins the day, 24:00 is the midnight which ends it, and is also 00:00 of the next day.</li>
<li><strong>Rounding of durations isn’t obvious.</strong> People expect a duration in hours or minutes to be rounded to the nearest unit, up or down. However, they expect a duration in days to always be rounded up. Even if the event finishes after one hour of the final day, that day still counts towards the event duration.</li>
<li><strong>Minutes do not always consist of 60 seconds.</strong> Sometimes there are leap seconds. For example, 2005 had a leap second on December 31st, and so did 2008. Or to look at it another way…</li>
<li><strong>Never store time as a number of seconds from an ’epoch’ date.</strong></li>
</ul>
<p>All of our local time zones are defined as offsets from UTC. For precision, UTC is defined by atomic clocks, whereas older time standards such as GMT were based on astronomical observations. However, UTC is kept in sync with older time standards by having leap seconds added or subtracted as necessary. Whenever UTC drifts far enough from UT1 or astronomical time, a leap second is scheduled.</p>
<p>Lots of systems store the date and time as the number of seconds since (say) January 1st 1970. The problem is, the exact dates on which the leap seconds in our calendar will occur cannot be determined in advance, because they depend upon the subtly varying rotational speed of the earth. The earth’s rotation changed measurably after the 2004 tsunami in Asia, for example. Hence given a date and time in the future, there is no way to calculate how to represent it exactly as a number of seconds from an epoch moment.</p>
<p>Another way of looking at it, is that if you have any epoch dates in 2006 stored in your computer, they’re now going to be off by a second because of the leap second announced for 2005, until your date and time library is updated.</p>
<p>Of course, you can ignore leap seconds. But if you do, any calculation that asks for the number of seconds between two moments in time may give the wrong answer. It won’t be <em>very</em> wrong, just a few seconds off, but that might be wrong enough to cause a very expensive error. (See <a href="/2008/09/16/the-fractious-leap-second-debate/">The Fractious Leap Second Debate</a> for more on this subject.)</p>
<p>It’s also really difficult to get the right values of epoch time internationally, as <a href="http://www.ucolick.org/~sla/leapsecs/epochtime.html">different countries have different numbers of legally counted leap seconds</a>.</p>
<p>Continuing the list:</p>
<ul>
<li><strong>Leap years.</strong> February. Get it right, OK?</li>
<li><strong>Time stamps should never be given in local time</strong> unless you also specify the time zone for every single time stamp. Otherwise, your timestamps are ambiguous for the hour which recurs when people switch back from daylight savings time to standard time.</li>
</ul>
<p>Consider the following sequence:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-txt" data-lang="txt"><span class="line"><span class="cl">Oct 31 01:55 Log in from 192.168.0.1  
</span></span><span class="line"><span class="cl">Oct 31 02:05 Log in from 192.168.0.2
</span></span></code></pre></div><p>Are these two events 10 minutes apart, or 70 minutes apart? Without the time zone information, you have no way to tell.</p>
<p>Of course, the right thing to do is timestamp in UTC.</p>
<p>On a related note:</p>
<ul>
<li><strong>You must always store a time zone along with a date</strong>, even if the date has no associated time.</li>
</ul>
<p>The reason for this is simple: June 5th in Australia is not the same day as June 5th in San Jose. Specifically, June 5th in Australia is ending and everyone’s going to bed before June 5th in San Jose gets started. An event that happens on June 5th in Australia may happen on June 4th in San Jose, so you need to know the time zone of the event in order to display the date correctly to the user.</p>
<p>If you don’t store a time zone, then basically there’s an implicit time zone, most likely the time zone that will be in effect on the date in question, at the location where the date is being measured. For an event, that will be the location where the event is happening. Obviously, implicit time zones aren’t very helpful for end users distant from the event in question, because they have to (a) realize without prompting that the correction has to be made and the date has to be adjusted, and (b) guess what the time zone is and how it will affect the date as seen from their time zone.</p>
<p>In Lotus Notes, you’ll need to use a formula like this:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-txt" data-lang="txt"><span class="line"><span class="cl">ost := @If(StartTime = &#34;&#34;; @Time(9; 0; 0); @Time(StartTime)); 
</span></span><span class="line"><span class="cl">tm := @TimeMerge(StartDate; ost; TimeZone); 
</span></span><span class="line"><span class="cl">@If(StartTime = &#34;&#34;; @Date(tm); tm);
</span></span></code></pre></div><p>This treats a date with no time as being basically the same as a date starting at 9am in the appropriate time zone. The choice of 9am is arbitrary and based on conventional business hours; there’s no answer which is always precisely correct.</p>
<p>In other words…</p>
<ul>
<li><strong>Automatically adjusting dates and times in a calendar is hard.</strong> People often complain because their electronic calendar gives them the wrong answer when they fly half way across the world and change time zone. They think it’s a fault in the software, and that it must be badly designed. The truth is that <em>there is no right answer</em>.</li>
</ul>
<p>Consider the following schedule:</p>
<blockquote>
<p>2004-10-10 10:00 Team conference call.<br>
2004-10-10 12:00 Lunch with Mike.<br>
2004-10-10 13:00 Conference session 2: Designing Groupware</p>
</blockquote>
<p>Suppose Mike and I fly 8 hours west. What happens? The first item on my schedule is a phone call. It happens at the same instant in universal time, no matter where I happen to be. Therefore to show me the right time, the software has to shift the displayed time by 8 hours. It might have to shift the date too, as a result.</p>
<p>The second item on my calendar is going to happen at noon in whatever time zone Mike and I happen to be in as we travel. We may not even know in advance what that time zone is going to be. So the right thing for the software to do is probably not to shift the time at all.</p>
<p>The third item is a physical event, but in this case the time and date are always going to be relative to the time zone in effect at the location where the event is taking place. So, the correct thing to do is almost certainly to leave the date and time alone.</p>
<p>So should the software adjust the display of the dates and times in this example? The “correct” answer is “definitely yes, maybe, and definitely not”.</p>
<p>One approach might be to have a flag in each event specifying whether the time and date should be corrected when the user changes time zone, or whether they should be allowed to float and effectively change. The flag could be part of the time zone field — if you specify a time zone field the date and time are adjusted, otherwise they float. I’ve never seen an electronic organizer that actually worked that way, though.</p>
<p>Lotus Notes does not change the time and date of an event when you change time zone. This is a common misconception. Notes actually leaves the date and time exactly the same; it is not modified in any way. An event stored and displayed as starting at instant T, is still stored and displayed as starting at instant T. However, the way instant T is indicated depends on what time zone you are in, so it looks like a different time or date, but it actually isn’t.</p>
<p>In contrast, the Palm OS date book does alter all the times and dates when you change time zones. If you change the time zone from San Jose to Australia, the system date and time will change, but all your events will be moved. If you set an alarm for a net radio show or a conference call, the alarm will probably happen at the wrong time. See immediately above for more explanation.</p>
]]></content></entry><entry><title type="html">Bitten by the specialness of Java arrays</title><link href="https://lpar.ATH0.com/posts/2009/02/bitten-by-the-specialness-of-java-arrays/"/><id>https://lpar.ATH0.com/posts/2009/02/bitten-by-the-specialness-of-java-arrays/</id><published>2009-02-18T21:25:48+00:00</published><updated>2009-02-18T21:25:48+00:00</updated><summary>Using arrays for string manipulation and bugs it can cause.</summary><content type="html"><![CDATA[<p>Suppose you have some text in Java that you want to manipulate. There are classes like StringBuffer for doing so, but let’s imagine that you choose to use a char array for some special reason.</p>
<p>Now suppose that several pages of code later, perhaps in a different piece of code entirely, you decide to use the value of the variable. At that point, you’ve forgetten that you didn’t use a StringBuffer, so you do the usual thing and call the toString() method.</p>
<p>Here’s some code to simulate what happens:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="line"><span class="cl"><span class="kt">char</span><span class="w"> </span><span class="o">[]</span><span class="n">s</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">&#34;Results of some computation&#34;</span><span class="p">.</span><span class="na">toCharArray</span><span class="p">();</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Lots of code later</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="n">System</span><span class="p">.</span><span class="na">out</span><span class="p">.</span><span class="na">println</span><span class="p">(</span><span class="n">s</span><span class="p">.</span><span class="na">toString</span><span class="p">());</span><span class="w">
</span></span></span></code></pre></div><p>When I compile and run the above, it outputs <code>[C@1bc4459</code>, which isn’t at all what you might hope.</p>
<p>There are two obvious questions which occur to me. The first is to wonder if this behavior of Java is deliberate. Is it considered useful in some way, or just an accident of implementation?</p>
<p>The second and more important question is: How can I detect such errors before code goes into production? Eclipse doesn’t catch it, and nor does PMD.</p>
]]></content></entry><entry><title type="html">Getting IPv6 enabled</title><link href="https://lpar.ATH0.com/posts/2009/01/getting-ipv6-enabled/"/><id>https://lpar.ATH0.com/posts/2009/01/getting-ipv6-enabled/</id><published>2009-01-20T15:42:14+00:00</published><updated>2009-01-20T15:42:14+00:00</updated><summary>128 bit IP addresses, here we come!</summary><content type="html"><![CDATA[<p>I’m not usually someone who likes to live on the bleeding edge of technology, but I decided that this year I wanted to get enabled for IPv6.</p>
<p>When you type in a web URL, the address gets looked up in DNS, and turned into a raw IP address. It’s a bit like looking up a telephone number. The number is what the network actually understands.</p>
<p>The early 1970s Internet had 256 host addresses, and an additional 16 network addresses. Those ran out pretty quickly, so in 1981 the Internet was redesigned to have the familiar 4 byte addresses in common use today; for example, 208.77.188.166.</p>
<p>Unfortunately, the people who redesigned the Internet in 1981 still didn’t really expect everyone to use it. They certainly didn’t expect that people would be connecting coffee machines, telephones and toasters to it. Our house has 10 devices that connect to the Internet, and we’re not particularly gadget-obsessed.</p>
<p>That’s why your home Internet access is probably via a wireless router. The router uses NAT to make everything in your home appear as a single device with a single address, at least as far as the rest of the Internet is concerned. The downside is, you end up with all kinds of problems with incoming connections, because the router has to know where to send each packet of incoming data. The shortage of IP addresses is also why most ISPs make you pay extra if you want a static IP.</p>
<p>So if you’ve ever had trouble chatting via IM, if you’ve ever had trouble with video chat or voice over IP, if you’ve ever had difficulties sharing files, if you’ve ever been unable to set up a web site or FTP server on your home computer — it’s all indirectly because of the IPv4 address shortage.</p>
<p>There’s a solution: IPv6. It expands the address space from 4×8 = 32 bits to 128 bits. That’s over 4 quadrillion IP addresses for each star system in the observable universe. If we assume they’re all like the solar system, and that every planet has an earth-like population, that’s 67,000 IP addresses per person. Not that the address space is being carved out that way, but it illustrates that there’s plenty of room for growth.</p>
<p>As well as solving the address shortage problem and getting rid of NAT issues, there are a lot of other technical reasons why IPv6 is better than IPv4, and it was standardized 10 years ago. So why aren’t we using it?</p>
<p>One problem is that because America built the Internet, America also got in early and hogged all the IPv4 addresses. So while the addresses might be running out, most US corporations aren’t really feeling the pain yet. This is why most of the ISPs offering IPv6 are in Asia.</p>
<p>A bigger issue is that the IPv6 and IPv4 Internets were initially disconnected. That is, if you had an IPv6 connection, you couldn’t reach IPv4 hosts, and vice versa. That problem has only recently been solved in a painless manner.</p>
<p>The first part of the solution is 6to4. It provides a standard way to take an IPv4 address, like the address issued by your ISP to your cable modem, and convert it to IPv6. Your router can take IPv6 traffic from your network, wrap it up inside IPv4 packets — setting the IPv6 it calculated as the reply-to address — and send the data to a 6to4 gateway. The gateway is a system which has both an IPv4 and an IPv6 connection. It unpacks your data and sends it over the real IPv6 Internet. The IPv6 Internet can then reply by stuffing IPv6 data inside IPv4 packets and sending them to your router. Your router unpacks the data and sends it across your home network as real IPv6.</p>
<p>The net effect of all this is that with the right router, it can look as if every machine on your home network is connected directly to the IPv6 Internet, even if your ISP only offers an IPv4 connection.</p>
<p>RFC 3068 is the second piece of the solution. It defines a magic IP address, 192.88.99.1, which is automatically routed to your closest 6to4 gateway.</p>
<p>So, if you can ping 192.88.99.1, you can have IPv6 right now — as long as you have a router that understands IPv6 and 6to4.</p>
<p>Once again, Apple are leading the industry. While big names like Linksys haven’t bothered to implement 6to4 in home routers yet, Apple’s Airport Extreme (and Time Capsule) make it simple.</p>
<p>You might need to take your computer off the network then reconnect in order to force it to notice, but then you should find that your computer suddenly has an IPv6 address that starts with “2002:”, the standard prefix for 6to4. If that’s the case, you should then be able to browse IPv6-only web sites like <a href="http://ipv6.google.com/">ipv6.google.com</a>. You can also go to <a href="http://www.ipv6.org/">www.ipv6.org</a> to verify your IPv6 address; and if you go there from different machines on your home network, you should see that each of your machines now has a distinct address.</p>
]]></content></entry><entry><title type="html">Java annoyance: final parameters</title><link href="https://lpar.ATH0.com/2008/08/26/java-annoyance-final-parameters/"/><id>https://lpar.ATH0.com/2008/08/26/java-annoyance-final-parameters/</id><published>2008-08-26T23:04:30+00:00</published><updated>2008-08-26T23:04:30+00:00</updated><summary>Why you should always use them.</summary><content type="html"><![CDATA[<p>First, the summary:</p>
<p><strong>Q: What does it mean when a method I’m calling declares that its parameters are final?</strong></p>
<p>A: To you, nothing. It’s a safety feature for the author of the method.</p>
<p><strong>Q: OK, so when should I declare method parameters as final?</strong></p>
<p>A: Absolutely always.</p>
<p><strong>Q: Isn’t that just annoying busywork?</strong></p>
<p>A: Pretty much so, yes. You must be new to Java.</p>
<hr>
<p>And now, the lengthy discussion.</p>
<p>Way back in the days when the closest thing to a decent programming language available to me was C or Pascal, I disliked functions with <a href="http://en.wikipedia.org/wiki/Side_effect_%28computer_science%29">side effects</a>. At the time they mostly seemed to me to be a nasty hack to get around the fact that there was no easy syntax for returning multiple values.</p>
<p>Today, I’m even less of a functional programmer than I was in college; but I still see functions with side effects on their arguments as evil. Sometimes a necessary evil for performance reasons, but evil nevertheless. (Obviously side effects on an object by its own methods aren’t anywhere near as big of a problem, though I like that Ruby distinguishes them from side-effect-free methods by a special naming convention.)</p>
<p>So my deeply ingrained habit is to treat function/method parameters as unmodifiable, whatever the programming language. I had actually forgotten that this was a habit until I started running PMD on my Java code, and promptly had it warn me that every single method parameter ought to be declared <code>final</code>. This in turn made me think about Java’s method call semantics, and how badly chosen and useless the word “final” is on method parameters.</p>
<p>In C and C++, the <code>const</code> keyword is used all the time when library functions accept string parameters, and provides the caller with a guarantee that the function will not modify the string. For example:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="kt">int</span> <span class="nf">strcmp</span><span class="p">(</span><span class="k">const</span> <span class="kt">char</span> <span class="o">*</span><span class="n">s1</span><span class="p">,</span> <span class="k">const</span> <span class="kt">char</span> <span class="o">*</span><span class="n">s2</span><span class="p">);</span>
</span></span></code></pre></div><p>You might naively expect that in Java, <code>final</code> performs a similar function — but it doesn’t really.</p>
<p>First off, in Java all Strings are immutable. So whether arguments are final or not, your strings will never be modified by being passed to a method.</p>
<p>Secondly, in Java all objects are passed as a value consisting of a pointer to the object. The Java <code>Thing a</code> is really like C++ <code>Thing *a</code>, and Java’s <code>a.method()</code> is really C++’s <code>a-&gt;method()</code>, <strong>not</strong> <code>a.method()</code>.</p>
<p>To look at it the other way, if you could have an actual object in a variable x, Java’s <code>foo(x)</code> would really be doing a C++ <code>foo(&amp;x)</code> — but in Java, you never get to touch the actual object x.</p>
<p>It seems that the designers of Java wanted to make sure nobody confused their object pointers with the evil manipulable pointers of C and C++, so they decided to call them references instead. So Java books usually say that objects are stored as references, leading people to think that objects are passed by reference. They’re not, they’re passed by value, it’s just that the value is a pointer. If you’re confused again, try going back a couple of paragraphs.</p>
<p>Anyhow, the upshot of pass-by-value with objects represented by pointer values, is that as a caller of a Java method, the presence or absence of <code>final</code> on parameters tells you absolutely nothing. Even if the parameters are all final, the method can still modify the value of any objects you pass in, unless the objects themselves are special immutable ones like the String class. Contrariwise, even if the parameters aren’t final, the method can’t make your variables end up pointing at a different object.</p>
<p>This is undoubtedly why JavaDoc ignores <code>final</code> on parameters when generating documentation.</p>
<p>What about the value to the author of the method? Well, reassigning parameters is pretty much universally viewed as a bad thing to do, and Eclipse will warn you about it.</p>
<p>If you’re not convinced it’s unwise, consider the case where you have a constructor with a parameter ’name’ that gets set as the initial value of a field, also called ’name’. If parameters are final, there’s no way to accidentally modify the parameter when you think you’re modifying the field. Yes, Eclipse warns about parameters masking fields too, but still… more safety is good if the cost is low.</p>
<p>So let’s consider what would happen if we made all parameters <code>final</code> by default.</p>
<p>There may be a rare occasion where you genuinely need to change values passed in to a method before performing some computation. Since every object in Java is manipulated as a pointer, it’s computationally trivial to introduce a temporary variable that’s a copy of the parameter, and then either change it to point to a different object or not. So instead of</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="line"><span class="cl"><span class="kt">void</span><span class="w"> </span><span class="nf">foo</span><span class="p">(</span><span class="n">Object</span><span class="w"> </span><span class="n">x</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">x</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="kc">null</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">SOME_DEFAULT</span><span class="p">;</span><span class="w"> </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="p">...</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span></code></pre></div><p>you’d have to do</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="line"><span class="cl"><span class="kt">void</span><span class="w"> </span><span class="nf">foo</span><span class="p">(</span><span class="n">Object</span><span class="w"> </span><span class="n">x</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="n">Object</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">x</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">c</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="kc">null</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">SOME_DEFAULT</span><span class="p">;</span><span class="w"> </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="p">...</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span></code></pre></div><p>No big problem.</p>
<p>How about performance? Well, it turns out that the final-ness of parameters isn’t part of the method signature. I also checked, and the compiled class files are byte-identical whether your parameters are final or not. So, no performance benefit either way.</p>
<p>Finally, no pun intended, the use of <code>final</code> on parameters is required when using inner (nested) classes for listeners or iteration. This crops up all the time in Swing programming, and a Google search shows that it’s a common cause of intense confusion.</p>
<p>So I don’t see any value to making the final-ness of parameters a matter of choice for method authors either. They should all be final, always. You won’t see any significant performance change, but you’ll get a bit more safety, and you’ll be a bit less likely to encounter a weird error message when attempting to use listeners and iterators.</p>
<p>So the actual word <code>final</code> on method parameters is just noise, providing no benefit to API users, programmers with good coding habits, or anyone using a tool like Eclipse that warns about reassigning parameter variables. The language <em>should</em> have made final parameters at least the default, and ideally the only option. It annoys me that I end up with my method declarations cluttered with <code>final</code>, <code>final</code>, <code>final</code>.</p>
]]></content></entry><entry><title type="html">SI unit prefixes: a plea for sanity</title><link href="https://lpar.ATH0.com/posts/2008/07/si-unit-prefixes-a-plea-for-sanity/"/><id>https://lpar.ATH0.com/posts/2008/07/si-unit-prefixes-a-plea-for-sanity/</id><published>2008-07-15T14:08:49+00:00</published><updated>2008-07-15T14:08:49+00:00</updated><summary>kilo = 1000, mega = 1,000,000, and so on.</summary><content type="html"><![CDATA[<p>Computer programmers can skip to the next sub-heading.</p>
<p>Computers work in binary. They measure things in binary numbers internally, at the hardware level. While you are seeing letters and decimal numbers on this page, the computer just sees streams of 1s and 0s. The successive digits in binary (moving left) count 1s, 2s, 4s, 8s, and so on, just like the digits in a regular base 10 number are worth 1, 10, 100, 1000. Powers of 10, powers of 2.</p>
<p>Way back in the mists of primordial computer history—or the 60s, as we also know it—someone decided it would be a good idea to define a kilobyte as 1024 bytes, rather than 1000, because 1024 is the closest power of 2 to 1000. That is, a 10 bit binary number can count from 0 to 1023, just like a 3 digit decimal number counts from 0 to 999.</p>
<p>The problem is, this unusual definition of “kilo” wasn’t given its own symbol at the time; they just used the same “kilo” prefix used for the metric system. Nor was the unusual definition of “kilo” universally used, even in the computer industry. For instance, while the memory of the computer was measured in binary kilobytes, the speed was always measured in decimal kilohertz. The first hard disk, the IBM RAMAC, was measured in base 10 units. The idea that marketers decided to redefine disk sizes in base 10 to make them look bigger is a myth; they were measured in base 10 units right from the start.</p>
<p>As the years went on, computers got more memory, and got faster, and their network connections got faster. We ended up with more and more ways to store data. And people kept on randomly choosing whether to use base 2 ‘computer’ units, or normal base 10 units, when measuring computer stuff.</p>
<h3 id="welcome-back-programmers">Welcome back, programmers!</h3>
<p>Right now, CDs are measured in base 2, as per the official CD standard—your 650MB CD contains 650×1024×1024 bytes. On the other hand, DVDs are always measured in base 10 units—your 4.7GB writeable DVD has the normal 4,700,000,000 bytes.</p>
<p>The size of the memory in your computer is measured in base 2 units (megabytes) if it’s being used as RAM, but base 10 units if it’s being used as long term storage (SSD). The bus speed of the memory is always measured in base 10 units (megahertz), even if the quantity is base 2 units.</p>
<p>The file you download has a size, almost certainly reported in base 2 units by your web browser. But, you’ve guessed it, the speed of your network connection is always measured in base 10 units. A 1Mbps cable modem gives you 1,000,000 bits per second, not 1,048,576.</p>
<p>The hard disk in a Macintosh? Always specified in base 10 units. If you get a 40GB disk, you get 40,000,000,000 bytes. The disk space reported by Mac OS X? Always binary units. Even Apple aren’t consistent.</p>
<p>Let me be blunt: <strong>This is a mess.</strong></p>
<p>There is no logic to it. There is no consistency to it. You can’t work out whether a given measurement is base 10 or base 2, you just have to magically know—or guess, and hope that if you’re wrong the difference isn’t too important.</p>
<h3 id="the-solution">The solution</h3>
<p>There is a solution to this problem. The IEC has a set of <a href="http://physics.nist.gov/cuu/Units/binary.html">official binary prefixes</a>. When you want to refer to something in base 2 units, you can use the appropriate binary prefix instead of using the closest base 10 metric prefix, and your meaning will be crystal clear. (That still leaves the problem of what to do if you’re measuring one of the many computer-related things that are measured in base 10, but if we get everyone using binary prefixes it won’t be a problem any more, will it?</p>
<p>And that brings me to the thing I actually want to write about: knee-jerk conservatism.</p>
<p>It turns out that there are a lot of computer programmers who really get pissed off by the idea of having to write MiB for base-2 megabytes. “Megabytes have always been base 2, and always been written as MB”, they sneer. “Everyone knows that 1MB is 1024KB, unless you’re talking about DVDs, or reading manufacturer specs for a hard drive, or buying an SSD, and that’s just the manufacturers being stupid. Everyone knows that ‘K’ on a computer means 1024; except for speeds, where it means 1000, except for file download speeds where it means 1024, except when it’s the speed of your modem, when it’s 1000. Everyone knows that. What, are you stupid?”</p>
<p>I find it quite fascinating, really. Engineers generally pride themselves on consistency and clarity, yet when it comes to being consistent and clear in their use of measurements, well, you’d think you were asking them to drink decaf or something.</p>
<p>Change which makes things easier, more consistent, and less ambiguous is <em>good change</em>. It should be <em>embraced</em>. Clinging to confusing and inconsistent ways of working, just because it’s what you’re used to, doesn’t make you look superior—it makes you look like an ass. You’re not clinging to consistency with the past, because <em>the past usage was not consistent</em>. The computer industry has never been consistent in its use of units, it’s not being consistent now—but it’s time for it to start. And there’s only one way to do that.</p>
<blockquote>
<p>If you measure in base 2 units, report in base 2 units using the base 2 prefixes.</p>
<p>If you measure in base 10 units, report in base 10 units using the base 10 prefixes.</p>
</blockquote>
<p>This is not a big plot to make you report disk sizes in base 10 if you don’t want to. Go on measuring your hard disk in GiB and whining about the hard drive manufacturer conspiracy to defraud you, if you want; I don’t care. I just want you and your software to be clear, correct and unambiguous when you provide information to me. Leaving me to guess the meaning of ‘K’ and ‘G’ based on context is not good enough. It is <em>not</em> unambiguous; see above.</p>
<p>Now, get with the program already. All of you. Tell your friends. If anyone whines, point them at this article. And someone get Steve Jobs to lay down the law at Apple, their continuing inconsistency is really annoying me…</p>
]]></content></entry><entry><title type="html">Things that suck about Java</title><link href="https://lpar.ATH0.com/posts/2005/04/things-that-suck-about-java/"/><id>https://lpar.ATH0.com/posts/2005/04/things-that-suck-about-java/</id><published>2005-04-23T00:00:00+00:00</published><updated>2005-04-23T00:00:00+00:00</updated><summary>It’s not a short list.</summary><content type="html"><![CDATA[<ul>
<li>
<p>Many common tasks take an absurd amount of code. For example, try producing a date in RFC2822 format, in the local time zone. Isn’t Java supposed to be a good language for Internet programming?</p>
</li>
<li>
<p>What’s with the special types that aren’t objects, like <code>int</code>? I just want to have integers, and leave the compiler to determine the appropriate implementation. In the worst case, I don’t mind specifying how wide I want my integers in advance, but please, can we have them act like proper objects (i.e. everything else)?</p>
<p>I mean, it’s not like anyone is going to be using Java for systems programming, and need access to raw machine words, especially since there are no unsigned integer types available. (Bytes are signed?!)</p>
<p>In Java 1.5 they try to make it less ugly by having the compiler automatically wrap primitive types in object wrappers when necessary. Which is still ugly.</p>
</li>
<li>
<p>Why must arrays be unlike every other type? For instance, array objects use <code>variable.size()</code> to find out their upper bounds, but arrays use <code>variable.length</code>. They’re not like the other special types either, because they can’t be converted.</p>
</li>
<li>
<p>A related gripe is that a little more consistency in method naming would be nice. As it is, Strings have a <code>.length()</code>, while arrays have a <code>.length</code>, Arrays have a <code>.getLength()</code>, and ArrayLists have a <code>.size()</code>.</p>
<p>The class library is riddled with these kinds of little inconsistencies that make it difficult to remember how to use everyday objects. To pick another example, <code>HashMap</code> is camel-cased, but <code>Hashtable</code> isn’t — and of course, fussy Java will complain if you capitalize differently.</p>
</li>
<li>
<p>Apparently too little thought has been put into doing things right the first time. That makes for a horribly bloated and messy API. So we have arrays, <code>Array</code> objects, <code>ArrayList</code> objects, and <code>Vector</code> objects, all solving the same problem in subtly different and incompatible ways. Ditto <code>Hashtable</code> and <code>HashMap</code>.</p>
</li>
<li>
<p>No integer overflow detection. For a language designed to be safe that forces me to pick a size of integer in advance, that’s pretty stupid.</p>
</li>
<li>
<p>No abstract local functions. I happen to find map operations very useful at times.</p>
</li>
<li>
<p>Some arguments are passed by value, some are passed by reference; it depends on their type.</p>
</li>
<li>
<p>Similarly, the types that would be passed by value are copied during assignments, the types passed by reference are not. Hence, assuming you remember something has been passed in by reference and want to copy it, you specifically have to <code>clone()</code> it to make a copy — and if it’s in an array, you have to clone each dimension of the array manually.</p>
</li>
<li>
<p>Comparing pass-by-reference variables checks if they’re references to the same thing, rather than checking if they’re the same value. To check if they’re the same value, you have to remember that they’re ‘special’ and that you have to use <code>.equals()</code> instead of <code>==</code>. Except it doesn’t work on arrays.</p>
</li>
<li>
<p>Constructors have their own special unique syntax. The compiler spots immediately if I don’t use the special syntax, therefore it clearly knows that the method is the constructor anyway, therefore it’s just arbitrarily making me jump through hoops for it.</p>
</li>
<li>
<p>You have to include constructors in subclasses, even if the code is identical to that in the parent class.</p>
</li>
<li>
<p>Importing packages doesn’t import dependencies. For instance, <code>org.xml.sax.XMLReader</code> is no use without <code>org.xml.sax.helpers.XMLReaderFactory</code>, so why make me import them separately?</p>
</li>
<li>
<p>There’s no way to break string literals across lines, so you have to concatenate them at run time.</p>
</li>
<li>
<p>Some of the documentation is really awful. I mean, does anyone understand <a href="http://java.sun.com/j2se/1.3/docs/api/java/text/RuleBasedCollator.html"><code>RuleBasedCollator</code></a>? Quote: “&amp; Indicates that the next rule follows the position to where the reset text-argument would be sorted”. Is that even English?</p>
<p>There’s also an unfortunate tendency for people to assume that JavaDoc is documentation. Often, it’s more like an adventure game, where you click around in a maze of twisty turny JavaDoc pages for hundreds of classes, hoping that at some point you’ll find some documentation that actually tells you how to perform some task you need to perform, rather than just telling you what lots of random methods do.</p>
</li>
<li>
<p>Startup times are terrible. They have been improved in Java 5 and improved further in Java 6, but they’re still bad compared with pretty much any other commonly used language, even interpreted ones like Ruby.</p>
</li>
<li>
<p>Exceptions are a pain. The ability to throw and catch exceptions is a good thing in any language; the problem with Java is the insistence that every exception be explicitly dealt with or thrown up the chain.</p>
<p>In J2EE code, for example, we have the <code>SQLException</code>. It either indicates a syntactic error in the SQL code, <em>or</em> that the connection to the database is broken. There’s really nothing the application can usefully do with <code>SQLException</code> except report an error and die; yet because of the explicit exception rules in Java, code ends up bloated with repeated catching and rethrowing of <code>SQLExceptions</code>.</p>
<p>It’s not clear to me that forced exceptions do anything to make programmers deal with possible problems anyway; try running Azureus and watch how many stack traces it craps to the console. Good programmers don’t need to be force-fed exceptions, and bad programmers just catch and ignore the exceptions anyway.</p>
<p>The other side of the problem: if you’re implementing an interface that doesn’t declare any exceptions, you have to eat any exceptions that occur, no matter how deadly.</p>
<p>I’m not sure what the solution is, but with Java I get the feeling that the cure being tried is of marginal effectiveness, and possibly worse than the disease.</p>
</li>
<li>
<p>Generics were added too late. Now we’ve got a massive class library full of unnecessarily ugly APIs.</p>
</li>
<li>
<p>Convenient iteration syntax was added too late as well (in Java 6). There are all kinds of classes which sound like they ought to be iterable, but aren’t. Like Arrays, for example.</p>
</li>
<li>
<p><code>String</code> and <code>StringBuffer</code> make straightforward string handling unnecessarily painful. You can split a string, but you can’t modify it. You can find a string within a <code>StringBuffer</code>, but only in case-sensitive fashion. You can’t search a <code>StringBuffer</code> for a regular expression; you have to convert it to a String first — but to modify what you find, you have to convert back to a <code>StringBuffer</code> again, or create a new <code>String</code> (and pay the cleanup costs).</p>
<p>So in typical input parsing, you end up repeatedly converting between <code>String</code> and <code>StringBuffer</code> objects. Even assuming that’s what the compiler would have to do anyway, why should I be forced to do it all explicitly? And if “replace string” is only available for <code>StringBuffer</code>, how come “replace regexp” is available for <code>String</code>? The whole division between the two has long ceased to make any sense.</p>
</li>
<li>
<p>In Java, <code>null</code> is a primitive value. But, as mentioned above, primitives like ints aren’t objects, and so neither is <code>null</code>. Which, in turn, means you can’t use <code>null</code> for null objects (for example when making objects optional) — you need to clutter the API with more methods, create empty objects, or implement a null object class.</p>
</li>
<li>
<p>IO is ugly. To do the normal “buffered write to a file”, you have to create a <code>FileWriter</code> object, wrap it in a <code>BufferedWriter</code> object to add buffering, then wrap that in a <code>PrintWriter</code> object to get a stream you can print to. That is:</p>
<p><code>PrintWriter pw = new PrintWriter(new BufferedWriter(new FileWriter(new File(filename))));</code></p>
<p>And don’t forget to explicitly flush and close the <code>PrintWriter</code>, or you’ll lose data. So much for safety! Input is just as bad. Is it too much to ask that the 90% of cases (stream-based reading and writing of text) be optimized with some kind of 1-step BufferedPrintToFileFlushOnDispose class?</p>
</li>
<li>
<p>I find the use of <code>static</code> to indicate <code>class scope</code> unnecessarily confusing. To put it another way, I find it hard to remember that <code>final</code> means “static” (unchanging) and <code>static</code> means “class”…</p>
<p>Of course, the reason why “static” is used for class methods is that Java doesn’t really have class methods; static methods are static in the sense that they’re really global functions that can’t be overridden and are shared between all objects of that class. Perhaps the word “shared” would have been less confusing?</p>
</li>
<li>
<p>The insistance on a separate file for each class fragments the source code and makes it harder to keep track of where things are — or alternately, encourages the “one huge class” antipattern. The insistence on making the directory structure match the package naming adds the annoyance of having to navigate in and out of directories multiple layers deep even for a trivial project.</p>
</li>
<li>
<p>Date and time handling is broken (it uses POSIX epoch values internally), and the methods and classes are confusingly named. For example, <code>Calendar.getTime()</code> returns a <code>Date</code>, because <code>Date</code> objects are actually date and time objects.</p>
</li>
</ul>
<h2 id="things-i-really-like-about-java">Things I really like about Java</h2>
<ul>
<li>
<p>Unicode everywhere, no special effort required.</p>
</li>
<li>
<p>It’s pretty much portable between Linux and OS X, without having to worry about contortions like autoconf.</p>
</li>
</ul>
<p>I don’t include automatic memory management in the list, because that ought to be a given for any modern programming language.</p>
<p>I should also point out that for all its faults, Java is still better than C++.</p>
]]></content></entry><entry><title type="html">Contact</title><link href="https://lpar.ATH0.com/contact/"/><id>https://lpar.ATH0.com/contact/</id><published>0001-01-01T00:00:00+00:00</published><updated>0001-01-01T00:00:00+00:00</updated><summary/><content type="html">&lt;p>Contact: &lt;a href="mailto:meta@pobox.com">meta@pobox.com&lt;/a>&lt;/p>
</content></entry><entry><title type="html">Projects</title><link href="https://lpar.ATH0.com/projects/"/><id>https://lpar.ATH0.com/projects/</id><published>0001-01-01T00:00:00+00:00</published><updated>0001-01-01T00:00:00+00:00</updated><summary/><content type="html">&lt;p>Nothing to see here… Move along!&lt;/p>
</content></entry><entry><title type="html">Search</title><link href="https://lpar.ATH0.com/search/"/><id>https://lpar.ATH0.com/search/</id><published>0001-01-01T00:00:00+00:00</published><updated>0001-01-01T00:00:00+00:00</updated><summary/></entry></feed>