Jacques Mattheij

technology, coding and business

Domain Knowledge or a Lack Thereof

I believe that a lack of domain knowledge is the root cause of a lot of very bad software that gets developed and I think that it is up to computer programmers and their managers to deal with this. Acquiring domain knowledge is an essential component in the development of software that really works well for its users. A programmer that has to automate a warehouse but that has never picked an order and doesn’t have a clue about actual logistics is going to be writing far less effective software than someone that has done a few shifts on the floor. And that’s purely practical knowledge in a field that is reasonably well understood. There are many other examples where the effects of the differences between someone automating some solution with or without domain knowledge would be far harder to see.

Programming and systems analysis are like architecture in many ways. An architect has to have a reasonably good understanding of what a customer is going to do with a building if they’re going to do a good job of designing that building. An enclosure for a machine would have to match the guts of that machine just like a building encloses a company. Having the loading docks of a warehouse on the fourth floor is usually not what you want.

Software is much more intertwined with the institution commissioning it and the people using it than any building ever will be, with the exception of engineered structures such as the CERN ring. If all should fail a building, no matter how mismatched can always at least be used for storage. I’ve seen fire-stations converted to houses and industrial buildings converted to office space. But software that doesn’t match is unusable.

Imagine architects designing a fire station without consulting with fire-men and fire station chiefs and without understanding the basic operations of a fire-station and how the situation develops when a fire is called in. When utility matters, domain knowledge is very valuable.

Over the years I’ve worked on a large number of projects in a variety of industries. One of the things that I absolutely love about software is that it is everywhere, there isn’t an industry that doesn’t have software component in it nowadays. And for each and every one of those projects there was a large amount of domain knowledge to acquire. That’s hard work, and you probably can’t put it on the bill but it is an absolute requirement if you want to deliver a half decent product.

What that translates into is that when I worked for a company making CNC equipment that I learned how to use a mill and a lathe manually. Only when I understood how you work metal by hand did I reach a level where I could confidently write software to work metal by numerical control.

Working for a manufacturer of sails I soaked up piles of books on sail making and sailing and I actually spent some time on a boat. Half the library on that subject was digested for breakfast, lunch and dinner. Add another helping on fabrics and their properties and on stitching and cutting techniques! Knowledge like that helps a lot when you have to lay out your ‘panels’ on the cloth, and then afterwards when those panels have to be combined to form a sail. In that particular case I took great care to make sure that the panels had their major lines of stress run along the threads in the weave, even if that meant that we might get one or two fewer panels from a piece of fabric the resulting sail would be stronger and it would last longer. Quantity or quality is a business decision and if you’re not aware of this then you might accidentally make that decision for your employer without anybody being aware that a decision has been made. The software used the exact same terminology that the sailmakers used, and used it consistently.

When working for a company that did colour calibration software and pattern checking I read and learned about colour spaces and imaging hardware. All kinds of history there, from manual inspection to semi automatic inspection all the way to the present day. Industry is funny that way, you start out with a simple assignment (can you read values from this sensor) to sucking you in into a project that has a century of history behind it with lifetimes of domain knowledge that you need to absorb before you can even begin to properly automate the solution to some problem. It is also funny in that it all ends with knowledge about physics.

If there is a message in this blog post then it probably is that if you are currently working on a project that requires domain knowledge but you don’t have any of that knowledge yourself that you should probably take the shortcut of stopping your work and to first educate yourself about the field that you are operating in, and then to return to whatever problem you’ve been assigned to solve.

Programming without domain knowledge for a discipline that is steeped in it is like an architect designing a building without knowing its true purpose.

If you are working in some industry spend time on the shop floor, become a user of your software if there is any opportunity to do so. It will make you a far more effective programmer and it will reflect itself in the usability and the perceived quality of your software. The combined knowledge about the domain you are operating in and your IT knowledge is far more valuable than any of the two in isolation.

Domain knowledge is not optional, it is essential. The one common factor between the failed projects I come across is that they were automated by people that had little love for and little or no knowledge of the domain they were operating in. Companies and institutions should make time available to get their IT staff up to speed on the inner workings of the company and should allow their IT staff to be embedded on the floor for a taste of what the real world looks and feels like.

So stay clear of the trap of little or no domain knowledge and get your hands dirty, learn to see through your users eyes by acquiring the knowledge associated with the field you are working in, don’t treat IT as a world that only communicates with its users through tickets and requirement documents, step down from that ivory tower.

How to Make a Quick Buck

In 1992 I had bought a license to a little known real time micro kernel based operating system called QnX.

QnX was a pretty interesting development for me, it was the first time that I used an OS that used message passing for its internals and that ran the file system, the network system, the scheduler and all other i/o as separate processes. Quirky, but interesting and an opportunity to learn. Because QnX was mostly used in Industry I was a pretty strange customer, a single person shop that bought a license stood out as an oddity for the importer of the software, LS Technologies in the dutch harbour town of IJmuiden.

After a couple of visits there to talk over strategies on how to solve certain problems using QnX, one fine monday morning I got a reasonably panicked phone call from the owner of the QnX import business, his brother had a bug they couldn’t solve and he thought maybe I should go there and have a look.

So I drove to IJmuiden in my rickety old car (a 25 year old Citroen DS that was just as likely to deliver you at your destination as it was likely to get you stranded), and found myself in front of an office building at the waterfront.

Housed there was a company that brokered cargo capacity for a very large percentage of the worlds shipping companies. If you wanted to ship 12 containers from Shanghai to Boston you made a request to your shipping broker. He would then send a telex to the company in IJmuiden which would then fan out your telex to a few hundred shipping companies within a specified amount of time. That telex would then be responded to within another specified amount of time and the bid criteria were evaluated and the results would be sent back to the broker. On a good monday morning a million or so telexes would not be an exception.

After arriving there I was ushered into a room with a pretty tense atmosphere. Four guys in suits stood behind a single man behind a computer typing frantically at the keyboard, sweating profusely (and it wasn’t all that warm). ‘Who is Jan?’, I ask.

The guy behind the keyboard looks up and says ‘You’re the guy my brother sent, the ‘whizz kid’?’.

So he jokingly tells me that his brother suggests I can fix this, he doesn’t believe it, but he’s willing to give me a chance if I can fix it in the next five minutes. It’s pretty clear that he feels he’s wasting his time and that he wants to get back instantly. The four suits stand aside for a bit so I can get closer to the screen and the keyboard. So I ask him to explain the situation.

He goes: “it’s worth 2500 guilders on the spot if you solve this problem we’re having, this morning at 8 all our systems froze. Yesterday we did a huge update, tested everything and it looked pretty good. We have our own home built message switch on top of QnX, the whole thing is a large constellation of C programs, yesterday it worked flawless, now it is a total lock up, and we can’t find the cause”.

So I spent a few minutes interviewing the guy and then did one thing, I typed ‘date’ on the command line. And it came up with yesterdays date, whereas all the messages that are being queued are set to be transmitted today… The system took each and every message as being embargoed. What had happened is that someone unplugged the box and plugged it back in again. Somehow the bios clock must have been set to the wrong date & time (no NTP) and when it came back up again it simply used the wrong date. Whoever installed the machine set the date properly the last time after boot but never bothered to update the system hardware clock.

The four guys in suits were laughing pretty hard and relieved. ‘Quick money!’, one said, and another started teasing Jan about having to pay up and make good on his promise.

They were so focused on the big software change they had pushed yesterday that they completely forgot the most basic check. So he went to the bank, got me 2500 guilders in cash (I’d never even seen a thousand guilder note before that day) and gave it to me saying ‘win win’.

Good guy. No, great guy. We ended up working together for years, I became lead dev on the project at some point and we are still in contact, though he is retired now.

When you’re looking for a bug it’s terribly hard to not get bogged down in details at the expense of seeing the bigger picture. An outsider doesn’t have those details so that helps tremendously. The lesson I took away from that day is that when I’m stuck I ask an outsider.

Disqus Bait and Switch, Now With Ads

Looking at the site earlier today I suddenly noticed a couple of links to sites that I would never ever think of endorsing through my blog.

A ‘what is this’ link explained that this was disqus’ way to thank me for using their comment system, a chunk of my webpage in between the comments section and the article body was claimed in order to attend visitors to my website to interesting content which they claim I ‘recommend’. I do no such thing.

Here is what it looked like:

This is really not nice. Those links are indistinguishable from the links on the left hand side which are links inside the blog, so it doesn’t really stand out as an advertisement, it makes my site look stealthy and sneaky. IF I would place advertising on my site it would certainly stand out and be labelled as such. Stealthy advertising is one of the least nice ways of advertising on a site, the end user will think that such advertising is an endorsement by the site owner rather than a paid spot, and the word recommended increases that perception.

Apparently somewhere in December disqus decided that they could pull this stunt without an active alert to the website owners that use the disqus plug-in. There is a degree of trust between a SAAS or plug-in provider and the user that the offering will not be changed in important ways without active notification, and that changes will default to ‘off’. That’s called grandfathering and it is one way in which you can show those users that helped you to grow that you appreciate the relationship.

The fact that disqus holds on to the comments is a sign that I trust them to do the right thing with my data, I absolutely never expected them to suddenly claim a chunk of my pages for advertising purposes, especially without notifying me first. That I am apparently entitled to a share of the take makes no diffence to me, if I want advertising on my blog I will put it there myself, and if I decide to endorse another website by linking to it that is my decision, not theirs. I do not ‘recommend’ any of these links and I don’t think I need to be surprised by finding out that I apparently endorse a bunch of companies.

Naming this euphemistically a ‘discovery’ feature doesn’t do much either, it’s advertising, so call it advertising, calling it a recommendation and making it blend in is illegal in lots of places, and even if it isn’t illegal it is not what you should do. Advertising should be clearly labeled as such, and it should stand apart from the content of a site.

So, bye-bye disqus, no more comments on my blog.

postscript: some people claim that the blog owners themselves do not see the ads, I am currently not logged in to disqus and not at my normal location so maybe that is why I suddenly saw the ads where there were none before (including yesterday). If that is true it is a lot nastier than I already thought it was.

postscript2: Hacker News Comment thread

Computers I Have Known

Over the years I’ve owned quite a few computers. An endless series of PC compatibles that mostly differed from each other in CPU speed or memory capacity. But before the PC era computers were a bit different in that they differed vastly from each other. The advent of the PC homogenized personal computing to a large extent, this is now due to the proliferation of mobile platforms and various tinkerer devices (Raspi, Arduino, etc) changing again but for the longest time it seemed as though x86 was what computing was all about.

The very first computer that I owned outright was a TRS-80 pocket computer. It was actually manufactured by Sharp and marketed by Radio Shack in the USA and Tandy in Europe. I’d befriended a number of Tandy store managers in and around Amsterdam, they let me play with the bigger machines so when I’d finally delivered enough papers and repaired enough TVs to buy a computer it was a fairly natural decision to get a TRS-80 of some kind and at 549,- guilders it was just within reach. The paper route was pretty steady income, the TVs mostly hit and miss (scan the garbage on wednesdays and fridays for likely candidates for fixing up or parts, then sell the TVs through classified ads for 25 guilders a piece). But eventually I got there and my first computer was mine. I still have it and it still works!

A cassette interface was another 150 guilders or so so I ended up writing out all my first programs into a copybook. 2K of RAM isn’t a whole lot so most programs were under a hundred lines or so.

The next step up was a pretty big one. From the pocket computer I went on to a ‘dragon 32’. The dragon was a clone of the TRS 80 color computer, it had an interesting mix of hardware and software, with the software doing the job where other computers of that time would have used a piece of hardware. For instance, the sound interface and the cassette tape interface were entirely in software. This taught me a lot about timing, phase locked loops in software and serializing memory to tape and back again. I fixed a friends computer (burned out RAM chip) and we realized that the chips were 64 Kbit x 1, and there were 8 of them. So our ‘dragon 32’ was really a dragon 64! The 6809 chip that powered it could address 64K, the memory was laid out with 32K of RAM in the low part, then 16K of ROM and then another 16K of ROM + peripherals in the final portion. The controller could bank switch each 16K block between ROM and between RAM, an undocumented feature. We found out how to move the BASIC rom to RAM and had endless fun documenting and modifying the BASIC interpreter using 6809 assembly.

Because I couldn’t afford a disk drive I wrote a disk simulator that would seek to a specific spot on the tape and then hit the ‘stop’ button on the cassette drive, then switch to record or play mode depending on whether I wanted to read or write a block. Auto-reverse cassette recorder doubled the storage space available :) I’m pretty sure Sony never foresaw that putting electrical push-buttons on their cassette recorders instead of the usual piano keys would allow some crazy dutch kid to use them as random access storage.

The dragon could interface to a TV or, if you fiddled around a bit with it to a monitor. I scavenged a ‘real’ monitor from a studio TV camera that I found in a dumpster, an old tube driven beast with a super sharp 8” black and white display. It kept losing sync as it warmed up but it had a ton of thumbwheels to adjust Hsync, Vsync and so on. Especially in winter this was lots of fun since the room I lived in didn’t have any heat. Effectively that old tube monitor was both my screen and my heater :)

My friend Henri and me had the same machine, we’d write assembly programs and then we’d call each other and transfer our code in ‘hex’ by typing it in line by line on the other end with a checksum to make sure we had not made any mistakes. Human modems!

Then came the KIM-1. In many ways this was a huge step down from the dragon. The KIM-1 was a very barebones computer, basically nothing but a board with a couple of 7 segment displays and a keypad that wouldn’t look bad on a calculator. The KIM-1 had only a few hundred bytes of memory and a 6502 CPU. This was interesting because it allowed me to learn 6502 assembler. Tape interface was through an FSK chip. What’s funny is that this was such a restrictive environment that you ended up having to be extremely creative in order to do anything useful at all.

Ever tried to play ‘snake’ on a couple of 7 segment displays?

Next up, one of my big loves, the BBC micro model ‘B’. The ‘beeb’ as it was known at the time was an absolutely amazing machine. Excellent hardware build quality, a switching power supply, several rom slots which you could use to install software available at boot time (exmon, word and a ton of others). What really set the BBC apart from the rest was the language that came with it, Acorn Soft structured basic. A basic which - unlike other basics at the time - allowed you to define functions and procedures by name rather than by line number. This opened up the world of structured programming for me and I distinctly remember that resounding click when I got it. Suddenly I could write programs several times larger without getting bogged down. Names are so much easier to remember than line numbers, and it made it much less of a chore to renumber a programs lines. (remember the renum command and how you had to re-set your whole internal symbol table about what lived where? No? lucky you!).

Mass storage ended up being two 160K teac 5 1/4” floppy drives, and the internal memory was expanded using a thingy called a ‘solidisk’ to 128K, using a technique called bankswitching. Every one of the 16 rom slots could be paged in for read or write into a 16K segment of the memory map.

After the BBC micro I moved on to the Atari ST. The ST was a serious step up from the 8 bit era. The Motorola 68000 that powered it could address a lot more memory. The initial run of the ST (the 260) had 256K of ram, then the 520 came and after that the 1040 with a full meg of RAM. That was an amazing amount of memory for that time and it seemed as though I would never write a program that would fill it all. (this didn’t take long, Jenny Yips laws of computing have held true over the years: eventually computer programs will fill every cycle, every byte of RAM and every bit of secondary storage that you’ve got). The ST came with something else as well, it had a hard drive interface and you could use this to connect a small selection of 5 1/4” hard disks to it. I eventually got a 20M hard disk and bought a C compiler. This bootstrapped my career as a free lance programmer and I proceded to write computer games profesionally for a studio in Leiderdorp (Aackosoft, long since bankrupt, two titles that I wrote that shipped were ‘FlightDeck’ and ‘Indy 500’.).

After the ST there was a brief period where I used an Acorn Risc Machine, but since it was a pre-production demo unit and it took forever for the machine to pick up more steam in the marketplace I ended up abandoning it. This was a real pity because it was an extremely powerful computer for the day, the chip that powered it (the ARM) is no used in countless mobile platforms and has survived where lots of others have not.

Next up, the PC era. I worked for a bank for a bit and got my first introduction to PCs there. The first PCs seemed quite underpowered compared to the computers that I’d been using and for the longest time I didn’t get what all the fuss was about. Even though the ST only had a megabyte of RAM the CPU was already using larger registers than the CPU in the PC and it could address that megabyte without resorting to bank switching or other tricks. But PCs got better with every new generation of CPU and by the time the 286 came out I got an el-cheapo mother board from some taiwanese manufacturer and a ‘hercules’ graphics board. A bit more scrounging got me another drive (a Seagate 40 MB unit) and this eventually gave me enough experience to start offering my services as a PC programmer as well. This was important because economically speaking the ST was doomed forever to be a ‘game computer’ (though you’d be surprised to see what we did with it, including a full CAD-CAM program directly driving lathes and mills!), and the PC was the choice of just about every business.

Programming the PC (after the ST with its linear memory space) really felt like a step back in many ways. But over time it got better, and after I discovered the QnX operating system it really came into its own. I wrote tons of software for the PC platform either for Windows or for QnX. Cad systems (for instance, for classical sail designs), process control, a whole suite of software around the idea of digitizing pictures, printing them on credit cards and distributing these (you probably have a descendant of that system in your pocket right now), editors, database applications, a good chunk of a message switch for telex messages used to broker shipping capacity and so on, and finally my own 32 bit QnX clone called ‘Unite!’, a multi-tasking multi-user operating system with built in networking and primitive clustering capabilities.

Around the time the world wide web launched I used SGI machines for several years. IRIX, SGI’s version of Unix was a really nice implementation and was quite fast. Hardware accelerated graphics meant that you could do reasonably complex 3D scenes with acceptable frame rates. It also doubled as my first web server, hooked up to a nearby provider using what was probably the longest run of coax on the internet at that time ;) The Indy as it was called was this funny little pizza box with a MIPS cpu running at 200 MHz, 32M of ram and internal 3.5” hard drive. It was quite fast and the operating system felt extremely well integrated with the desk top environment. To this day, whatever machine I’ve got I try to re-create that feeling as much as possible.

SGI eventually bit off more than they could chew with the acquisition of CRAY, the hardware was way overpriced compared to the PC offerings and eventually the company died and I was back to PCs.

In spite of the PCs (especially from the 386 onwards) dominance in the market, their utility and eventual performance and the fact that they powered a huge part of my professional career there was something special about those funny little 8 bit machines.

Apart from the operating system exercise (which, together with games programming taught me more about computers than anything else) I have over the years come to feel more and more out of touch with the machine. Those 8 bitters you could actually know, you’d be aware of each and every memory location and what was going on there, you could know those computers exhaustively, until there was literally nothing left that you did not know.

Nowadays when I boot my trusty Ubuntu machine (24G of ram, 48T of attached storage, 2.6GHz clock, one of those 8 bitters would fit in a very small corner of that machine) I feel strongly that it is impossible for me to fully ‘grok’ that computer. I have to rely on trust rather than knowledge that everything is the way it should be and when I program I know I write on top of countless layers of code written by others rather than directly to the machine. API gluing rather than actual coding. Of course the effect of tying together a few APIs with some glue code will outmatch anything you could have achieved in a lifetime writing on an 8 bitter but still, there is some aspect that is missing there.

I don’t actually know the computer that I’m using for my day to day work any longer. Those oldies they had personality, they were quirky and strange, each computer completely different from the others in many ways, and knowing them intimately gave you a tremendous edge. In that sense they were more personable, more individual.

A man named Jim Lawless just mailed me, we seem to have more than just a title in common, read his post as well if you feel like it and spot the 7 differences :) : Computers I have known.

Introducing the Paper Bay

Over the last couple of weeks I’ve been working off-and-on on a little side project. The idea is that there are lots of people that are not in a position to visit a university or that don’t have a public library with ‘access’ at their disposal but that do need to be able to read scientific papers. Ever since the advent of the world-wide-web the funding for public libraries has slowly but surely dried up. There are fewer of them and they offer ever fewer facilities, including more limited or non-existent access to scientific journals. And that is a pity because libraries offer something the web does not, access to a wealth of copyrighted materials for a very small fee.

Scientific research costs lots of money. So much that most if not all research can trace its funding back to public money. Every paper cites the papers that it builds upon, and even if a piece of research is not funded directly with public money you won’t have to trace back very far through the citations before you hit papers that were funded with public money. So, effectively, *ALL* research that is conducted is funded directly or indirectly through public money.

Historically, publishing anything was a costly affair. Copyrights on scientific papers submitted to journals were routinely assigned to those journals by the scientists that wrote the articles. The copyrights didn’t matter much to them as long as their work made it out into the world, to get to an audience larger than the scientists themselves could reach. Quite a few of those journals even had such copyright assignment as a requirement. At that time nobody could foresee that the world would change to the point where this mechanism no longer made any sense at all. Lots of people are aware of this problem, but nobody is in a position to do much about it. The reason why is that the lobbying power and the legal armies that are at the disposal of the few publishing companies that find themselves in the luxurious position of holding hostage the last 70 years or so of the results of scientific research are so formidable that they serve as an effective deterrent against correcting this historic mistake.

It’s a beautiful business to be in: publish research that you took no part in, claim the copyrights to the results of that research, publish the research in a very expensive journal, publish reprints at exorbitant fees and finally, when a more efficient distribution method appears get rid of all the costly components of the business but keep the prices the same. According to one person I spoke to who is knowledgeable about the publishing field the profit margins dwarf even those of the publication of pornography.

In our current technological age storing and distributing 50 to 75 T of data (estimated amount of storage required to store all the papers produced historically) is an affair that even a private individual can afford. Passing a paper from a central service to a person that wishes to read that paper no longer takes a printed volume and a physical distribution network. Such a service can operate not on several 10’s of Euros/Dollars per reprint of a document (which was, even when it was needed excessive), but it can operate on very small fractions of pennies. And yet, the publishing industry that seeks rent on the content that (they claim!) has been assigned to them routinely charge excessive amounts of money for access to this information. Many words have been written about this subject, but in the end the publishers have pockets deep enough and lobbying power sufficient to protect their business interests against the very people that fund the research.

If you are living in a country that is poor, if you are a private individual (whose taxes have likely been used in part to fund the very research you might be interested in) and if you have a desire to enhance your understanding of how some aspect of the universe works, or if you want to help lift your country out of poverty by studying hard chances are that you will not be able to do so without paying exorbitant amounts of money to parties that did not contribute to the original research in a meaningful way.

A Small Detour

In the 1980’s, when computers were a bit more scarce and a lot less powerful than they are today, and when a half decent development environment was even more scarce I finally found my home on the Atari ST, an MC68K computer that was more suited to writing games on than software of a more productive nature. It came with your option of several not-so-hot and fairly buggy programming languages, mostly limited to BASIC and assembler. And then a little known company called The Mark Williams Company came out with ‘Mark Williams C’, a very good C compiler and a standard library implementation to go with it. I was hooked instantly, this was what I’d been looking for, a computer with a very powerful CPU and a more ambitious amount of memory than what my 8 bitters could provide, an environment to learn more about programming (I’d been reading Kernighan and Ritchie’s introduction to the C programming language back-and-forth but had no access to an environment where I could actually write programs and try them, so ‘desk checking’ was my lot until that point).

Mark Williams C really changed my life, it literally launched my career as a free-lance programmer. It came with a *fantastic* reference manual, that I kept with me until it fell apart from use and even my attempts at taping it together were no longer enough to keep it serviceable. Long after all my Atari machines had all died from old age and hard use that manual came with me, to Poland where I lived for a while, and then back to the Netherlands.

The Mark Williams Company derived its curious name from William Mark Swartz, the father of the man that ran the company, Robert Swartz.

End Detour

Late in 2010, A young man named Aaron Swartz, the son of the above mentioned Robert Swartz worked very hard to achieve one of his goals, to ensure that everybody would have access to scientific papers, no matter whether they were affluent or whether they were affiliated with a university or not. He went about it in an unfortunate way which got him into trouble with the law. Aaron had already achieved several noteworthy victories for someone as young as he was but the combined might of the United States federal justice system and MIT (who insisted on labeling him a felon and jailing him) proved too much for him to deal with and he took his own life on the 11th of January 2013. Volumes have been written about Aaron’s saga, I won’t go into the details but if you feel like reading more about it I recommend this slate article.

What really bothers me that someone so young, so nice and accomplished and so idealistic would be pressured to such an extent for trying to do something that was good by any definition of the word that I’m familiar with.

Most of the work I do is born from a love for my profession, this work was born in anger and frustration at a system that causes the best and brightest lights to be extinguished.

So, here is ThePaperBay.com, a way for those that seek scientific papers to make contact with those that have access. It’s my salute to the man that tried to give us access to all the products of science and a very small token of gratitude to his dad.

We should all wish for sons to be so proud of.

When Haskell Is Not Faster Than C

This article is in response to an earlier one comparing Haskell and C, which made the claim that Haskell beats out C when it comes to speed. On a Hacker News thread I made the bold claim that the C code is rife with problems and that it is tempting to fix it.

I’ve earned a good part of my life’s income to date taking other people’s C code, cleaning it up, making it work and then making it work better. In one sense the original program that this article is about is perfect, it takes the prescribed input, processes it and produces the desired output using the test set provided. That’s really all you can ask for in any program, under normal circumstances. Provided of course that the program produces its results in an acceptable time. What acceptable is is up to the user of such a program, in this particular case the writer of that article (linked at the end) used acceptable to mean ‘slower than Haskell’ and as a long time observer of the language wars this irks me.

For one, I think if you compare two languages side by side I think you should at least be as proficient in the one language as you are in the other, and you should be proficient in both. Second, you should if you are not proficient in one of the two limit yourself to highlighting the strong points of your favorite language rather than talking down the other language that you don’t know as much about. Third, a comparison on speed between Haskell and C is almost meaningless, speed is not Haskells strongest point and it would be folly to bench it against C for that particular reason.

The monetary gain from using a higher level language than C is made because the programmer spends less time writing/debugging/maintaining the software. As compilers get better and languages are better capable of using raw speed of the hardware without investing a lot of programmer time this trade-off will be made more frequently to the disadvantage of languages lower on the totem pole such as C.

I have no clue about the specific strengths or weaknesses of Haskell. I hear a lot about it but there are so many languages and there is only so much time. My own language repertoire is probably outdated, limited and not ‘hip’ by any stretch of the imagination but I think I know my old tools well, a bit like an elderly carpenter, please keep your fingers away from the chisels.

C may be old, but beating C for raw performance is quite hard (if it is possible at all, even FORTRAN still has its uses) and there are applications where the sheer number of computers working on a single problem outweighs the programmer cost advantage offered by an easy to use language (I’ve never heard anybody describe Haskell as ‘easy’, but it may very well be easier than C, I just do not know) by a considerable margin. The example chosen is quite apt because a lot of the problems in the field of computational genomics are exactly such problems. Other advantages from efficient code may translate into hard real time guarantees, improved battery life, lower charges from your service provider or a lower power bill. And since the environmental impact of computing is more and more on the radar optimization may find a new lease on life. That said, any optimization that you don’t know for sure that you need is likely to be premature and it is important to be aware of the cost of optimization and to make the appropriate decision when to employ it.

So this is an attempt to set the record straight and will give a level comparison between the ‘old’ version of the code as supplied by the original author and a re-written piece of code. I’ve purposefully not looked at other C entries in the language shoot-out section to keep things fair and to show what you can do to fix this code. A from scratch implementation would go for the end result in a much more direct way.

The time taken by the version as posted on http://paulspontifications.blogspot.nl/2013/01/when-haskell-is-faster-than-c.html on my machine (i7 920, 2.66GHz) when compiled with -O3 (a C compiler optimization directive) to process a 250M ‘fasta’ format file is about 7.4 seconds (average of 10 runs), so we’ll be using that as a baseline.

As we go the original program will be transformed into one that hopefully reads a bit easier and performs better as well.

The first re-factor will be a simple cleanup.

After turning on some compiler warnings (-Wall -Wextra) the first thing that jumps out is an unused variable ‘title’ in the ‘main’ function (happens to everybody without warnings on) and the fact that characters (signed entities) are used as array indices. Changing the base type of the arrays and pointers to ‘unsigned character’ removes these warnings and takes care of a potential problem if the program would ever be fed bytes > 0x7f, in which case it would start to refer to memory before the lookup table. You really don’t want to do that. C’s signed character type has tripped up many programmers, especially when used as an index. Main really has a type ‘int’ and you should declare it as such, and add a proper return value.

As usual when dealing with programs that are undocumented other than a few brief comments here and there part of the fun in doing things like this is figuring out how it does what it does. This one is fairly simple but still, the principle holds, I like puzzles.

C does not require you to set static global arrays to ‘0’, so the for loop in the main function can go, you also don’t need to declare empty blocks so the {} after the while can go as well.

First thing to hit is the loop that writes the output. This is a character loop that is a bit inefficient the way it is written. The fasta format uses 60 characters to a line and we can simply write out lines of 60 bytes in one go, adjusting the size for the last line to whatever is left. New runtime of the program is 5.2 seconds.

I don’t really like the way the feof / fgets bit at the beginning of the process function looks so I’ve changed it a bit using the return value of the fgets function as a guide whether we’re at the end of the input or not. A bit more fiddling to the output loop to make it look nicer (obviously no speed gain, that’s just cosmetics). What is not cosmetics is that the title string is messed up if it is longer than 132 characters, the remaining characters would be dropped. This is a problem because the FASTA format does not allow lines > 120 characters but if we receive input like this we have the tough choice of either keeping the input and performing the job or throwing an error. Silently discarding the excessive input seems wrong to me. If this were a contract job I’d aks for guidance at this point what the company policy is in situations like these ;) Some more looking at that loop and you see that you can simply drop the title variable altogether and simply use the loop that scans for the ‘\n’ character to process the whole title. End of file handling of this program (and bad input) are pretty weak, but those things are not specified so we’ll just leave them the way they are. For robust production code this would have to be substantially improved on.

Next up, the read loop. The read loop is also character based, just a minor tweak and instead of reading characters we’re reading lines using fgets. New runtime: 1.2 seconds. C has a nasty problem with looking ahead in the input stream, we need to know if the first character of the next line is a greater than sign, if it is then that’s the sign that we are looking at the beginning of a new sequence. This is done rather un-elegantly using a getc / ungetc pair, which effectively allows you to peek one character ahead.

That 1024 bytes buffer is a bit anemic, this is 2013, we’re processing 250M of data and we’re going to pull it all in anyway. Let’s use 256K buffers, we’ll still use exactly the same amount of memory + on average half an empty 256K buffer. That’s a very small price to pay. Runtime now 0.97 seconds.

So far we’ve been quite nice with our optimizations, no tricks, no gimmicks. The speed of the program is not fantastic but quite respectable.

But suppose your boss is at your desk breathing down your neck. It’s fast but really not yet fast enough, what can you do to make this code faster? ‘Use as much memory as you want’ he said when leaving…

Optimization is a funny game, the more you optimize the code the uglier it gets. Programs that have been optimized are - if you don’t stop where we’ve gotten so far - a lot harder to maintain and a lot harder to debug as well. So now we’re entering the twilight zone of optimizations, things that you really don’t want to do unless you’ve got an extremely good reason for doing them, and things that might subtly alter the way you can use your program, so you need to be vigilant against that. Since there is no clear specification here we have a lot of leeway but in a real world setting there would be all kinds of constraints.

A quick check of how fast the program runs when you disable ‘reverse_complement’ shows that this takes approximately 20% of the runtime. This means that even if we’d reduce that portion to ‘0’ there would still be 80% of the time used for other bits of work. Another quick check, cat’ing the file to /dev/null shows that this takes about 50 ms. Clearly raw IO speed is not what is holding us up.

That leaves the two loops that we’ve already optimized a bit as the main offenders.

One of the problems with those loops is that (unlike reverse_complement) we can’t do the work in parallel, so the usual ‘get out of jail free’ card does not help us here. If we were CPU bound for the larger part of the runtime the effect of multi-threading would be much more pronounced, but in this case we can never win more than 20% that way. Reading from an input stream is an inherently serial operation and writing to an output stream is too. When you’re optimizing there are a bunch of trade-offs that you can make, the most common one is space versus speed. If memory is significantly larger than the largest possible input sequence you could read all of the sequence into one giant chunk of memory. that would mean a single read. The interesting possibility that approach offers (versus the block oriented approach used by the original program) is that the linefeeds would remain where they are. Simply skipping them would be enough. (this skip would require two tests in the inner loop of the reverse_complement routine, which would incur a penalty, but that penalty is not as large as the one imposed by the way the linefeeds are processed now). A single read and a single write could then do the whole job.

A very quick check, increase the block length to something > than the input file length shows about 5% improvement, but we’re still going through those loops. I like the idea of a very fast scan, let’s see what we can do with that.

So, this is the first major departure from the original code, We start off with allocating buffers again, but this time we read huge chunks of data until all data has been read, and then we move all the data into one single buffer which we can then process in place.

To make reverse_complement a bit more universal we pass it two pointers to the data instead of the ‘block’ pointer.

Reading and writing the data now comes in at 0.22 seconds with 1M blocks. (reading from a file and writing to /dev/null).

Next up the processing. We leave all the data in place, we don’t mess with the linefeeds (we just skip them) and we stuff it all into one giant buffer. Runtime: 0.44 seconds. .22 of that comes for the reading/writing, and the other half is the actual processing.

Note that this change means that the program will need an end-of-file at some point in order to function, and that end-of-file should arrive before we run out of memory. This is a serious drawback and we should really do something about that, because now the program is no longer up to spec. It may be fast, but if it contains a bug like that the speed is not relevant. Make it correct first, then make it fast!

The problem is (like with many text protocols) that we have absolutely no idea how much data to read to get the next working set into memory. The only thing we have to go on here is that single ‘>’. Scanning for that character is expensive! It requires a full pass through the data just to figure out where the one sequence ends and the next one starts. And since this is crucial information we can’t really skip this step. The good news is, we had that scan anyway so whatever the reader gains in complexity is lost by the processing step (which will now only process one sequence).

The final result is a runtime of about .75 seconds, quite acceptable and this would put it #1 on the shootout if submitted. There are stil two bits of low hanging fruit left to optimize this code further:

The first is very obvious. If we’re processing multiple sequences then (in the case of the original program) we can process blocks in parallel on multiple cores using threads. In the current incarnation of the program you’d apply that technique to a full sequence. As shown above this would yield at most a 20% improvement, my best guess is that with the input streams given the yield would be lower than that (about 7%, 1/3rd of 20% because there are 3 input sequences).

The second is a bit less obvious. The reader loop now reads in as much as it needs or a bit more. Once detected the bit more is saved for the next round of reading. Every time that scan takes place it re-scans from the beginning of the sequence found so far. That’s fast (because it is in memory), but still very wasteful (because a sequence is larger than the CPU cache it is in fact very wasteful), you only need to scan the new part after you’ve done the initial scan. So you could improve on this by adding another scan in the first portion of the reader loop just after it re-cycles the saved portion. For every iteration of the loop after that one you only scan the bit that you just read in.

Total memory consumption of this version is about twice as good as the best C version in the shootout, and elapsed time slightly better. Using the threading and scan tricks above memory consumption should be about the same and elapsed time should be significantly better.

In the words of Colin Wright: “You can’t make a computer do stuff faster, but you can make it do less work”, and that really is the essence of optimization.

The realloc is not as bad as it looks, since it is almost always the last allocated block growing it is nearly free.

C gives you a lot of leeway in how you want to express your code. Over the years I’ve settled on a style that is pretty defensive, this helps in avoiding some of the pitfalls in the C language. When you read the code below you might think ‘I can do this quicker using a pre-decrement’ or you might think ‘I can push these two separate statements onto a single line’. These things are all true, and in fact they might give you a small performance boost at times. But for me such optimizations are not worth it unless we’re talking about an inner loop where a substantial amount of time is spent. And even then I’d work hard to get rid of the number of times we iterate through the loop before resorting to such micro-optimizations trading readability for speed.

I hope you enjoyed this little exercise, I certainlyh did. The final code is below.

(afterword: Joachim Schipper points out that memchr could be used to speed up the inner loop in the scanner for the ‘>’ character see here, that’s important because it makes the inner loop both faster and more readable, and this is a good illustration of why you want code review).

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define BLOCKLEN (1*1024*1024)

#define TRUE 1
#define FALSE 0

/* Initialised by calls to set_complement. Holds the complement codes. */

static char complement[256];

void set_complement(int c1, int c2) {
    complement [c1] = c2;
    complement [c2] = c1;
    complement [c1 | 0x20] = c2;
    complement [c2 | 0x20] = c1;
}

/*
 *  this walks two pointers towards each other, every time one of the pointers
 *  hits a linefeed the linefeed is skipped and the loop restarted. Whenever neither
 *  pointer is on a linefeed (the most common case) the characters are complemented
 *  and swapped.
 */

void reverse_complement(unsigned char * ptr1, unsigned char * ptr2) {
    unsigned char c;

    while (ptr1 <= ptr2) {

        if (*ptr1 == 10) {
            ptr1++;
            continue;
        }

        if (*ptr2 == 10) {
            ptr2--;
            continue;
        }

        c = complement[*ptr1];
        *ptr1++ = complement [*ptr2];
        *ptr2-- = c;
    }
}

/*
 * Fasta files do not have any parser friendly features such as length fields. This means 
 * that if you want to know if a sequence is complete you have to scan for the next '>' 
 * character of the title following the current sequence. This is quite time consuming, 
 * and even if you find it you still have a problem because you'll have read *too much* 
 * data from the input stream. That excess is then saved in a separate buffer to be re-used 
 * at the beginning of the next round of reading. 
 * 
 * This loop is pretty slow, it takes up about 40% of the total runtime of the program. 
 * There is a clear way to improve it, which is to scan only the part that was just read 
 * in after the first pass through the loop in read_sequence. I'll leave that as an exercise 
 * for those that want to beat this version of the code, there is an easy #1 spot in the 
 * language shootout waiting for you if you add that feature ;) (and multithreading if
 * you want to keep that #1 spot!)
 */

int sequence_complete(unsigned char * p, int n, unsigned char ** saved, int * savedsize)

{
    // skip the leading '>' for the title of the current block, we want the *next* block

    p++;
    n--;

    // now search the rest of the data for a sequence start

    while (n) {
        if (*p == '>') {
            // we've found a title for the next sequence, figure how how much excess we have
            // and save the remainder

            *saved = malloc(n);

            memcpy(*saved, p, n);
            *savedsize = n;

            return TRUE;
        }

        p++;
        n--;
    }

    return FALSE;
}

// read in a sequence, if we read in more than one whole one save the excess

unsigned char * read_sequence(int * s, unsigned char ** saved, int * nsaved) {
    int size;
    unsigned char * p;
    int read;
    int n;

    if (*saved == NULL) {
        // first round or a really lucky break
        size = BLOCKLEN;
        p = malloc(BLOCKLEN);
        read = 0;
    }
    else {
        // round which starts from excess data read during a previous round
        size = *nsaved;
        p = *saved;
        *saved = NULL;
        read = *nsaved;
        size <<= 1; // fix for bug spotted by Robert G. Jakabosky
    }

    while (!feof(stdin) || read) {
        p = realloc(p, size);

        n = fread(p + read, 1, size - read, stdin);

        read += n;

        // if the sequence is now complete save the excess for the next
        // iteration and process this sequence. Like that we don't need
        // to read all the way to end-of-file before we can start processing
        // if we have read more than one whole sequence this still works, it
        // just means that we will re-visit this on the next round through
        // the reader to fetch another whole sequence.

        if (sequence_complete(p, read, saved, nsaved)) {

            read -= *nsaved;    // compensate for saved portion
            break;
        }

        // if we did not read any data we can return now

        if (n == 0) {
            break;
        }

        // every time we reach the end of the block we scale up

        if (read == size) {
            size <<= 1;
        }
    }

    *s = read;

    return p;
}

void process_sequence(unsigned char * p, int size) {

    unsigned char * start;

    // skip the block title
    start = (unsigned char*)strchr((char*)p, '\n') + 1;

    // figure out start and end of this sequence and do the complement

    reverse_complement(start, start + size - (start - p) - 1);
}

void setup() {

        set_complement ('A', 'T');
        set_complement ('C', 'G');
        set_complement ('M', 'K');
        set_complement ('R', 'Y');
        set_complement ('W', 'W');
        set_complement ('S', 'S');
        set_complement ('V', 'B');
        set_complement ('H', 'D');
        set_complement ('N', 'N');
}

/*
 * process sequences one-by-one until we're out of sequences and end-of-file 
 * has been reached on the input and the readahead buffer is empty
 */

void process() {

    unsigned char * readahead = NULL;
    int nreadahead;
    unsigned char * p;
    int s;

    while (readahead != NULL || !feof(stdin)) {
        p = read_sequence(&s, &readahead, &nreadahead);

        process_sequence(p, s);

        fwrite(p, 1, s, stdout);

        free(p);
    }
}

int main() {

    setup();

    process();

    return 0;
}

Finally, this code is still terrible! Yes, really. It is fragily because it does not deal well with error conditions such as broken input and many others besides. Because the original does not and the specification doesn’t give any requirements I left it that way but I would never ever consider a piece of code like this finished. At a minimum it would require checks on all system / library call return values, unit tests for every function and so on. Even a ‘rivial’ little program like this is not trivial if you plan on putting it into a real world situation where people will run their business based on your code.

One thing that struck me about the FASTA format is that there is absolutely no attempt to detect/correct errors in the data, for a file format that stores information where mutations are not without effect you’d hope they would at least put in some safe-guards to make sure that mutations are of the biological variety rather than the digital one (bitrot).

Another thing that I noticed when I was finished and looked through the language shootout entries was OCaml #3, about 3 times as slow as the C version here, but only 12.8M of ram in use, I have absolutely no idea how it does that!

the language shootout entry

skybrian notes about battery life/cloud charges

FASTA file format

Original HN thread

@ay: I left you a message

A World Without Power

The 14th of August, 2003 was an interesting day in many ways. I’d just taken the family down to Toronto to spend a day there and pick up our newly minted passports at the Dutch embassy. We had some fun in the city seeing the sights, visited Niagara Falls and were on the way back on a sunny August thursday afternoon. What could possibly go wrong? We pulled into a gas station just outside of Barrie. We parked behind the person gassing up and waited our turn. The guy took his time, walked into the store to pay, got into his car and drove off. We moved up the line to the pump, I got out and put the nozzle into the fuel port but nothing happened. This normally means that the pump hasn’t been ‘cleared’, usually that takes 10 seconds or so (an annoying little bell starts ringing in the office over the blinking light indicating the pump that needs to be cleared). After a minute of waiting I went into the office. “Sorry bud, the power is out”.

Bummer! The car we were driving was our family car, one of those ford minivan affairs and it wasn’t exactly a paragon of fuel economy. 3.8 liter engine, still slow as could be and it drank like a fish. So when we pulled into the gas station the needle was at ‘empty’ and the fuel warning light was on. We were stuck for the duration.

I looked at Barrie from the highway down and noticed that there were lots of people in the streets, many more than you’d normally see in a place like that. Traffic lights were out. Billboards were dark. Little by little it dawned on me that this was more than just a trivial outage. I tried my cellphone, it still had a signal and called to the Island where we lived. We had a business there (a gas station, coincidentially) and I asked them if they had power. No, they didn’t. Oh oh. But the generator was up and running and as far as they were concerned it was business as usual. Maybe a bit more busy because some traffic from the highway pulled in on the island to gas up. I asked them to call the supplier (Wardlaw fuels in Sault Ste Marie, an awesome company to work with) to make sure they were going to be provisioned.

An hour and a half into the blackout a truck from OPG pulled into the station. The guy in it took all the ice his truck would carry, paid cash and drove off again. Now I was getting really worried. OPG is the “Ontario Power Generating Company”, they are the company that runs all the grid infrastructure, and more importantly they run the nuclear generators. If a guy with that much knowledge buys ice he must know something that the general public doesn’t know yet: that this outage is going to take a very long time, long enough that food will spoil. Nuclear power is funny in that it is excellent baseline power, but when you shut down a nuke it’s going to be down for a while. They go down quite quickly but they take forever to get back online.

I saw one guy walk around to the spot where the air hose for refilling tires was. A few minutes later the same guy walks by with the length of air hose coiled up and on his shoulder like it was the most normal thing in the world. Presumably he was going to use it to siphon fuel from one car into another. Let’s hope they were at least both his cars. Another guy made off with the fire extinguisher. I’ve heard it say that the veneer over our society is very thin and that it won’t take much to bring out the ugliness underneath but I had not expected to see that illustrated so clearly so quickly. Suddenly I didn’t feel safe and I did not want to wait for who knows how long next to an unfamiliar town in a vulnerable position like this with my wife and kid with me.

My mobile still worked, so I called the gas station on the Island again. The mood around us continued to detoriorate from resigned to menacing, people were getting angry with the operator of the station (just some kid that was clearly not the cause of the trouble). I asked the people at our gas station on the Island to please go to our house, get our other car (a honda civic hybrid, capable of doing 1200 km on a single tank if you were careful), load it up with fuel cannisters and drive down to where we were. They said they’d get on it, and that the station was being mobbed by people that wanted gas, some coming all the way from DesBarats and Sault Ste. Marie (a good 50 Km or 30 Miles away). They’d already gone through one full drop (50,000 liters) and another one was on the way. Our trusty diesel was doing just fine running the pumps and half of the freezers, they’d sold the food in so they could be switched off, the other half at a discount rather than to let it go bad.

We talked to some of the people stranded around us. One group was a bunch of motorcycle enthusiasts, guys that not only drive but build their own bikes. Lots of nice metalworking there so we talked for a bit about that. One girl that was stranded came from Toronto and was on the way to Muskoka, a popular place to spend the holidays. We waited… One of the bike guys went into town and scored a pizza. One of the pizza bakers had set up in the street and was selling pizzas for $5 as long as he had ingredients. We munched our pizza, talked some more and waited some more.

Barrie is about 500 km from the Island, and around 10 pm I saw our saviors roll into the station. Two kids with huge grins on their faces and music blaring loud from the open windows. I don’t think I was ever so glad to see my own car. The honda was a veritable bomb, it was filled with cannisters as many as they could cram in. We gassed up, then gassed the bikes of the bike guys (we swapped addresses, they invited us for a pig roast which we attended and they came to visit us on the island). The girl got enough gas to get back to Toronto, and we parcelled out the remaining fuel in the same way, just enough to get as many people home as possible. No charge, obviously (people were on the whole expecting to pay the gas station with a credit card or debit card). We made a lot of friends that day :), and quite a few enemies too (all those that we couldn’t help).

So, finally done we drove back to the island. It was the weirdest ride on Highway 17 North ever. Normally even at night there is light traffic there, this time not a single car. Just lots of wildlife, deer, moose and the occasional bear that had already taken over the highway so we went pretty slow. In none of the little villages on the road were there any lights. When we got back to the island it was 5:30 am or so, the gas station was still open, the pumps were still manned and going pretty much continuously. For 75 miles around there was no gas. The distribution point had huge tanks (millions of liters) that did a gravity dump into the delivery trucks, and then the truck would do a gravity dump into the underground storage tanks at the station. So none of that required power. And then the generator driven pumps would pull the fuel out of the underground tanks and deliver it to the customers just like normal.

The outage lasted 2 days and a bit. We went trough our monthly amount of fuel in that time and we made the Sault Star (the local newspaper) after the power was restored. (Good thing too, their presses were down just like everything else, we wouldn’t have been able to cope with the demand if there had been any publicity during the outage, word of mouth we could deal with, barely).

When we bought the station one of the first things I did was install that generator. I felt that what with the station being critical infrastructure for many of the islanders that we could not be dependent on Ontarios power grid. The island was fed by cables to a step-down transformer, and after that there was a ‘low voltage’ (not really that low, but low compared to long distance lines) distribution net on the island and every house had its own drop transformer. Outages were frequent, once every couple of months, and more frequently in the winter months. Whenever lightning struck it was 50/50 that the power would go out. I imagined a situation where the power was out for just a bit longer than normal and decided that we could not run that risk. My software background makes me abhor single points of failure and to run an infrastructure business without a back-up in place seemed unwise and ran against my nature (even if the partners in the bussines thought that it was a bit over the top they still helped installing the genny).

I didn’t have any idea that there would be such a massive power outage (there had not been one like that in decades). I also didn’t know that I was going to be one the main beneficiaries of having a back-up. I definitely didn’t plan to get our business in the newspaper this way and did not realize how many people would end up relying on our silly little out-of-the-way gas station with it’s puny 2x50K liter reservoirs for a critical resource (a typical highway station has a 1/4 of a million liters). But being prepared for the occasion sure didn’t hurt. What is really scary is that apparently none of the other (much larger) stations than ours had thought this scenario through. Critical infrastructure being down is annoying enough, but the knock-on effects are devastating.

Our house didn’t have any issues at all, we were ‘off the grid’ by that time so our business worked uninterrupted. One thing that I was very impressed with was how well the cellphone network dealt with the outage, for at least 24 hours all the base stations worked, after that point they slowly dropped out one by one as their batteries ran dry.

Infrastructure is invisible, as long as it works. And only when it fails do you realize just how much we are all dependent on it and how badly we are able to cope with such infrastructure being unavailable for any length of time. No power translates quickly into: no fuel, no water, no food and so on. If this had happened during the winter instead of a nice summer day the results would have been much more severe.

There is no moral to this story, but I’d like to add one: if you’re in the infrastructure business design as if lives depend on it. One day they may, even if you can’t foresee how that is possible. Even if you’re just running a lousy gas station on some barely accessible island.

Elon Musk and the Hyperloop

For a while now there have been tantalizing hints that Elon Musk is at it again. His usual way of approaching a problem is to look at an industry, find some fatal flaw in it, fix that flaw and then leave everybody else in the dust, wondering why they didn’t do what he did. He’s one of the most interesting people on the planet at the moment and there isn’t a week that I do not come across some bit of information that re-inforces that view. I’m not a person that will readily admit to being a ‘fan’ of someone but let’s leave it at that I find it hard to not be infected by his devil may care attitude towards all things holy in industry and convention. Recently there has been a lot of buzz regarding the ‘hyperloop’.

The Hyperloop is the code name for his plan to disrupt the transportation industry, and maybe to hedge his bets on Tesla (which attempts to do the same in a less revolutionary way), and because of the lack of details speculation runs rampant about what it could be.

I’ve seen the most fantastic interpretations of the hyperloop name, including space bound filaments kept aloft somehow that people carrying projectiles are fired into (doesn’t anybody think of the children, or the grandmothers) and other science fiction interpretations.

This is my attempt at putting together what it could be taking into account some of the common elements in Tesla, SpaceX and paypal.

One thing Elon Musk doesn’t dabble in is science fiction, he seems to be stuck solidly in the science and engineering departments so I’ll go with ‘make it as simple as possible, but no simpler’ principle. Airborne tunnels don’t have that simplicity component so I’ll happily discard them, they’re almost impossible to construct and they are terribly fragile once they’re up (and taking them down for maintenance would suck).

There are a few facts known from things that Elon has said on the subject:

“Cheaper than high speed rail”

“ground based”

“it leaves when you arrive”

“no rails required”

“It will revolutionize the transportation industry”

“It is not an evacuated tunnel”

That last one really piqued my interest. At first sight says very little, but that depends on how you interpret the sentence and I suspect that Elon may be playing a little practical joke on us here, let’s not forget he knows a thing or two about computers.

You can parse that sentence two ways to get a completely different meaning, depending on where you place your ‘brackets’, but in a spoken sentence these are invisible. So they’re a neat spot for a verbal trick:

It is not (an evacuated tunnel)

and

it is a (not evacuated) tunnel

So, in other words he may be putting the truth out there for everybody to see: it is a tunnel that is explicitly not evacuated.

Which I read to mean that he is saying that it is pressurized. Pressure is a lot easier to maintain than a vacuum is, especially if you’re building long stretches of tubing. A really good vacuum needs a considerable support structure because the atmosphere will happily crush your apparatus. There is also a low limit of how effective you can be (1 atmosphere, to be precise is the upper limit of diference that you can achieve by definition). Then there is the problem that to brace against that atmospheric pressure you have to push outward, which would be annoying because that is exactly where you want you vehicles to run, which means that if you want to make a high speed transportation device using a tunnel based on a vacuum that you’re going to have to make the tunnel double walled, which will greatly increase the cost. So clearly a vacuum would have all kinds of drawbacks and is a non-starter. Then there is the problem of convincing the general public to enter a cart in a tunnel that is evacuated, no way to refresh the air while it is moving and so on. Vacuum: bad idea.

So here is my vision for what ‘hyperloop’ stands for:

If you reverse the picture and you imagine a tunnel that is pressurized then there is a much easier way to make the whole thing work, in fact it would explain one of the two parts of the word ‘hyperloop’, the fact that it apparently is a loop, which means that it is going to recycle some critical component. (the other, the ‘hyper’ bit I assume refers to the maximum speeds attainable by such a system).

And that re-cyclable component may very well be the moving air inside the tunnel. If the pressure is supplied from the outside then it could leak away causing vehicles to have to work harder than they were designed for and the transit speed would suffer, but there is an elegant solution for this and it involves seeing the system as a whole rather than as bits and pieces.

A packet switched network of carriages that can be inserted and removed at various locations that are propelled into a slot on the ‘loop’ and taken back out again when they reach their destinations. Energy would be expended when accelerating a carriage to the speed of the loop, after that has been done on a parallel track the carriage is shunted into the loop, and energy expenditure drops rapidly. Such shunt points would exist every few thousand meters along the length of the loop, comparable to on-ramps on highways. The whole thing uses the carriages themselves as the impellers that cause the air to move through the tunnel system, effectively everybody is drafting with everybody else. So the pressurized air is pressurized by the combined motive force of all the carriages. The more carriages in the loop the lower the energy budget per carriage. Carriages would be electrically propelled, mostly seal the tunnel walls and use maglev principles or something similar to reach their speed. One hyperloop could be the ramp up to the next by keeping ‘packets’ for the same destination together, shunting them out to an intermediary phase and speeding up again for the next level. Downshifting would be the same but in reverse.

So this system would actually be cheaper and more energy efficient as usage goes up, compared with ordinary roads where congestion and fuel consumption goes up with usage.

There would be a fair amount of redundancy in the system, since if a carriage would for some reason slow down or if it would be really busy they could be made to move in such a way that a rearward carriage would start to help push the one in front of it, effectively reducing aeronamic drag on the rearward carriage to near 0, using the air between the carriages as a buffer medium and shock absorber. Pumping the remaining air between two carraiges out would effectively lock them together for the duration of the trip. Instant train formation, with some maximum length based on the radius of the loop, and even if the carriages would not be locked together from an energy consumption point of view if they get close enough the effect is much the same.

Loops around a city would be joined to other loops around other cities by long stretches of tubing, with the occasional spot for egress in case of emergencies. The whole thing resembles the internet loosely, both are packet switched, where the electrical wiring needs a return path for the electrons the tube system needs a return path to keep the moving air in the system. If traffic is light dummy carriages can be inserted into the system to keep the air moving, and as traffic increases more and more of these can be circulated out. That way the system would work even when there is only very little payload.

No vacuum (with associated risks and technical issues), simple, reasonably cheap to set up and maintain with all the active components in the carriage and with good economies of scale and redundancy. It would still cost a bundle to install such a system but compared to todays roads it will probably come in cheaper, especially in the long run asphalt is terribly costly to maintain. No traffic jams, just a fixed maximum capacity that can be expanded by installing parallel tubes.

I’m not sure what the end-points of such a system should look like, I’m imagining something akin to what I saw in a mailroom where they used pneumatic tube mail. And effectively, that is what this is, a scaled up version of pneumatic tube mail with some elegant tricks thrown in to make it energy efficient.

So, that’s what I think the ‘hyperloop’ concept stands for. Time will tell if I was right or not, I wished I had some drawing skills so I could give you an artists impression of the words above.

Thank HN: Our Friend Is Safe and Sound

Hello again, Hackernews.

I tried to post this on HN but the limit is 2000 characters.

Two weeks ago to the day I asked for your help in finding a lawyer for a HN’er that was about to be arraigned in front of a Delhi judge.

The original thread:

http://news.ycombinator.com/item?id=4739649

To say that the results were overwhelming would be an understatement but I don’t have more superlative words in my vocabulary.

We got offers from people for shelter, legal advice, money and all kinds of other help and most importantly, several pointers on how to quickly obtain a good lawyer.

A special mention for Shubham Goel who found us Rohit Kaliyar, advocate in Delhi.

Rohit met with his newfound customer on arrival in Delhi (our friend was snatched from her home in Pune in a bogus criminal case) so instead of facing a scared single young person the opposition faced a legal team that was briefed as good as time permitted and the result of that was that all efforts to keep our friend under some form of custody fell flat.

Right now she’s free, still there are people trying hard to ruin her life but at least for now the main threat is under control and a sense of normalcy has returned.

In the original thread there were a lot of requests for more details, we gambled on our combined reputations to keep these details from you but still ask for your help. That gamble paid off, and if at some point this story is to be told then we’ll leave that to the protagonist, rest assured that you won’t be bored if and when it ever comes to that. But for now the details of the background behind this will have to remain out of the public eye. Our friends’ peace of mind and safety depends on keeping her identity and circumstances as much of a secret as we can.

So, thank you Hacker News, for trusting us about the urgency of the request in spite of the lack of details and for pulling together when it really mattered. On behalf of our friend: “Thank you so much for being there for me and for helping to keep me safe.”.

We hope that there will not be any re-runs of this, and that our friend is now safe from further bogus prosecution but in India not much is sure in this respect, especially not when the opposition has significant clout with the police who will apparently not be deterred by such simple things as laws. Fortunately, with the help of a competent lawyer and a somewhat more solid judiciary it seems you can get a semblance of justice. But that does mean having to live a life on the run and in hiding, which isn’t much of a life at all. Working on that.

best regards to all & thank you again,

Jacques Mattheij (jacquesm) and Daniel Tenner (swombat)

Stick to What You Know, a Tale of an Investment Gone Wrong

After moving to ‘the Island’, a place I won’t make too obvious here to protect the innocent and the guilty alike we settled down and built a house. We got to know a lot of people and were quite happy to employ a few of the people there to help run our various businesses.

We had money in the bank and a very positive outlook on life, the breathtaking nature and some hard earned time-off had renewed the store of energy that I had come to rely on over the years. A couple of the local people that we got to know expressed their desire to run a company of their own, and it didn’t take long before an opportunity presented itself.

The Island had two stores, one a general store where you could buy just about everything but it was on the far side of the island. The other a gas station, right next to the only access point to the island by car (technically it wasn’t an island any more since the bridge had been put in but it definitely still felt like one). The owners of the gas station were getting quite advanced in age and working a company like that in Canada, especially during the harsh winters is pretty heavy. Operating a gas station is a funny business, you make almost nothing on the gas (1 to 2 cents per liter, and of that you have to operate and service the pumps, pay for inspections, deal with occasional theft and so on), but you make it all back in the store. If you run such a station wisely it can hold its own, stay afloat and provide employment for a fairly large number of people (2 people, 2 shifts, 7 days per week) and turn a profit. So with the old owners willing to sell (they’d tried selling it before but that had not gone through for some reason) and new people willing to step up there was a possible deal to be made.

We put together a package, bankrolled by us which would result in one family having a house, one new company subletting the large garage space next to the gas station and a group of individuals that would be employed and would be co-shareholders in the gas station. It looked like a pretty good plan on paper and with the blessing of the bookkeeper and the various authorities it was put in motion.

The first year things looked to be going quite well. The man that had stepped forward to manage the whole thing had many years of experience in retail and he did a good job of making the transition from the old owners to the new one. We kept the name and we re-established ourselves as a constant factor in the lives of the local population. The gas station was quite important to the locals, it had been around longer than many of the people and there was a large element of loyalty involved. Be nice, serve up a good product, improve the store bit by bit, what could possibly go wrong?

In the winter of that first year I got the first sign of trouble. We’d done pretty good over the summer but somehow there wasn’t enough money in the bank to cover the tax bill. I really didn’t understand what was happening, all the books seemed to be in order and yet, even after the best quarter we were down enough that extra money was required to plug the hole. After discussing the situation we borrowed the missing amount. The store manager back-pedalled on his original commitment, and wanted to be relieved. This was a major problem. Even before the whole thing had started I had made it more than clear that we were willing to bankroll the operation but that we did not have the time or the knowledge required to run a retail operation ourselves and that we were relying on everybody to do their part.

A solution was found, one of the other partners in the venture stepped forward and made a good case why she should be allowed to take the position. She had been one of the hardest workers over the summer and seemed absolutely reliable. So the management change was made and things were back on track.

For about another year things seemed to be going well. We survived the winter (which had always been touch and go, the energy bills were huge), spring arrived and we were set for a fantastic summer. That year things derailed spectacularly. At some point the fuel supplier called me on my personal number inquiring when the next payment would come in. Fuel is sold in ‘drops’, a typical drop is one truckload of a mix of diesel and regular, sometimes premium (if that’s still sold, we still had one pump serving premium). The original arrangment was that I had asked specifically not to be given a line of credit. In spite of that agreement the fuel supplier had delivered three drops without payment, about $150,000 worth of fuel! Their reasoning was that since we had such a good reputation that the money would be coming any moment, and in fact they were assured to that effect by the people running the station. The call came as a complete surprise to me, I didn’t have clue that we were in arrears on anything, let alone in excess of a hundred grand.

The decision to shut down the station and liquidate the assets was a tough one. But it had to be done, there was no way we were going to survive a hole this size. But that still left the question of how we had gotten into this situation in the first place. Little by little the truth dribbled out, I’ll likely never know all the details but it seemed that some people figured that since the cash isn’t counted on a daily basis, why not take that cash and visit the casino. Surely if you gamble a bit then you can make some money, pay back the difference and nobody will be the wiser. And then, if it doesn’t work the next time you go gambling, you just take a bit more. And so on. In a span of 3 months a business that was the 3rd largest employer on the island was destroyed by those that were supposed to be minding it.

I blame myself. Trust but verify should have been my motto, trust alone simply doesn’t cut it. I should have kept a much closer eye on things. Coming from a software background I had 0 insight in the retail business, the one thing that I thought would offset this was the fact that we had a retail expert on board and that the people we were dealing with were effectively destroying their own livelihood if they would do anything against the interest of the group. But apparently not everybody is smart enough to see even that far ahead. What a pity!

So, a lot of people lost their jobs, some their house and reputations. We lost a bunch of money, the station got sold and the amount it fetched was high enough to cover all the debts (it turned out that there were many more bills that had not been paid) with a little bit of money left over.

And a very expensive lesson was learned: If you invest, do it in a business that you understand, and keep a close eye on your investment otherwise you risk getting burned.