“Laser used to cool semiconductor”

I can imagine the marketing blurb now: “Now with lazer cooling!” (Yes, I know laser is spelled wrong, but marketing guys are very fond of their Zs. Which might explain why it’s so tempting to sleep through most of their presentations, but I digress.)

With some work, this sort of thing might someday be employed to deal with CPU heat, leading to computing speeds that can only be managed today using cryogenic equipment. I pity the person whose super-laptop’s internal cooling laser suddenly dies though. 😉

“Lesbian Necrophiliacs”

You don’t find an article whose title includes the phrase “Lesbian Necrophiliacs” too often. And it’s safe-for-work (and for my more prudish readers) too! 😉

Even without the title, the article is pretty interesting. Cloning has apparently evolved lots of times over the history of Earth, but it’s almost always a death sentence: if every creature is the same, then their immune systems are likewise identical, and the first virus that evolves a way to overcome it has the whole species as a smörgÃ¥sbord. I hadn’t heard of these critters until I stumbled on this article, or I’d have wondered about them too.

Comments in Code

My nephew just introduced me to geek&poke, a web-comic that only true geeks could love. Needless to say, I’m lovin’ it. 😉

While scanning through the recent strips, I ran across this one, which gave me a chuckle, and also got me thinking.

I’ve heard a lot of opinions on comments in programs over the last thirty years of developing software. They seem to be divided in to three camps. The first consists primarily of relatively new self-taught programmers, who think that comments (like documentation) are boring, unnecessary, and completely optional — after all, they understand their code, anyone wanting to use it should figure it out at a glance too! This type generally learns the folly of his ways the third or fourth time he has to go back and try to modify code that he wrote more than six months ago, and realizes to his dismay that without having the reasons why he did things that way fresh in his mind, he can’t understand it either. Unfortunately the vast majority of open-source developers are in this group.

The second is solely-college-educated developers, the ones who’d never even heard of a compiler until it was taught to them in a class. That type goes to the other extreme: every two-line function has to have its own twenty- or thirty-line comment header, describing when it was written, why it was needed, who wrote it, who approved it, who code-reviewed it, what each and every parameter is and is used for, what return values you can expect from it, and anything and everything else. This type either learns that all those comments are superfluous (and eventually graduates into the third camp), or has no real skill or interest in coding and just wants to get promoted to management as quickly as possible, where he forces everyone under him to adhere to that standard (because he has to read their work, and reading comments is soooo much easier than actually reading code — which is, I suspect, also the reason that college professors require that).

The third camp is where developers end up after lots of experience, after they realize that the code should be self-documenting. They pick their variable and function names in such a way that they don’t need documentation, anyone reading them can easily see what they’re used for. For these people, well-chosen names are the what, well-designed code is the how, and comments are reserved for the why — the reasons for things that can’t be determined from the code. As a very simple example, here’s an actual function copied directly from one of my programs:

bool isValidGregorianDate(int year, int month, int day) {
    if (year == 0) return false; // 1 BCE is followed by 1 CE.
    if (month < 1 || month > 12) return false;
    if (day < 1 || day > highestValidDay(year, month)) return false;

    // Due to Pope Gregory's reform in 1582, ten days are missing from the
    // Gregorian calendar, as compared to the Julian calendar in use before
    // that. There's no way to properly calculate which days unless you also
    // know the location, because different places adopted the change in
    // different years. All you can say for certain is that somewhere
    // between ten and thirteen days get skipped somewhere between 1582 and
    // 1923. This function will assumes that those changes happened in 1582,
    // so that Thursday, 4 October 1582 on the Julian calendar was followed
    // by Friday, 15 October 1582 on the Gregorian.
    if (year == 1582 && month == 10 && day > 4 && day < 15) return false;
    return true;
}

First, notice the function name, isValidGregorianDate. If you were reading through the code and saw a function with that name, it would be pretty bloody obvious what the purpose of it is, and any comments to that effect would represent valuable time wasted. Ditto for the parameters year, month, and day — between the names themselves and the context of the function name, their purpose is self-evident. If you want to know the valid ranges, they’re pretty obvious from the code itself, just in case you weren’t familiar with the Gregorian calendar.

Next, notice the first line within the function. If it were uncommented you might wonder why year zero isn’t accepted by the function, but a tiny little comment directly after it explains it — there is no year zero in the Gregorian calendar, and here’s why. Also notice the second and third lines, which have no comments because they’re self-explanatory, thanks in great part to a call to another self-descriptive function, highestValidDay (which calls another self-descriptive function, isLeapYear). An inexperienced developer would see that these functions would never be called from anywhere else and put the code for them right into isValidGregorianDate, with or without comments to explain what it’s doing and why, but that would be a distraction from the purpose of isValidGregorianDate. By separating them and giving them very descriptive names, none of that is necessary.

Finally, there’s the huge nine-line comment, which describes the reason for the one line of code immediately following it. Lots of care was lavished on the description for that one line, because a reader who isn’t intimately familiar with the history of the Gregorian calendar wouldn’t know that stuff — and that reader just might be the developer who wrote the code, some time later when he’s forgotten all of the details.

Out of curiosity, I scanned a dozen source-code files from my current project, counting the number of lines and the number of true comments (skipping commented-out code lines and TODO comments which are meant to catch my attention when I go searching for things that still need work). Out of 3,645 lines in those twelve files, there are 87 comments, mostly little one-liners tacked onto the end of the line they’re commenting (like “so it will call Update” or “otherwise it’s constant”), but occasionally detailed four- or six- or ten-line comments like the one shown in the example above. I don’t know how that measures up to anyone else’s code, but it’s fairly average for my own.

If you’re a developer, you’re probably wondering just how I could possibly know what lines will need comments when someone else looks at the function. The answer is easy enough: as I’m developing the code, I also read it as if I’m seeing it for the first time, and if any questions occur to that side of my brain, I add a comment to answer them. It’s something you pick up with enough experience, and I don’t know of any shortcut to it except knowing what you’re aiming for.

The basic thing to remember is that you’re not writing code for the compiler, you’re writing it for the human readers who comes after you. The compiler can understand literally millions of variations on a single function. Practically all of those would be gibberish to a human trying to debug or modify the function. If you need any more encouragement, keep in mind that that later someone might be you.

“The Pirate Bay torrents printable 3D objects”

Ever since I read Neal Stephenson’s The Diamond Age, I’ve been wondering what would happen when anyone could download a set of plans and print their own, for example, Star Wars toys. And more to the point, what would happen when those plans could be pirated.

Anything digital can easily be copied; the Internet is one huge digital copy machine. And anything that people want will be copied. There’s no effective way to prevent or police it, and I doubt there every can be. LucasFilm made a fortune on the Star Wars films, but (as I understand it) many times that on cheaply-made plastic toys from them — I had several myself when I was a kid. Lego continues to make money hand over fist, for a product that anyone with a RepRap could churn out by the thousands without thinking.

That sort of thing simply couldn’t happen in an age where anyone can download free (official, stolen, or knockoff) plans, or create their own, and have their own home 3D printer create whatever it is they want. Right now the products from such devices look pretty crude, but it wouldn’t take much interest from the masses to drive their creators to improve them.

When they do… well, life is going to be interesting for the Lego Corporation and any would-be LucasFilms.

“Password Sharing Among American Teenagers”

I’ve always stressed that passwords should never be shared with anyone, to everyone I discuss them with — the only passwords that my wife and I both know are the ones to the iTunes and e-book accounts that we both share.

Unfortunately there’s a problem when it comes to minors: parents only have a limited amount of trust in their kids, usually with reason, and insist on knowing their childrens’ passwords. It sounds like that’s leading to a problem: kids think that sharing a password with a boyfriend/girlfriend is an appropriate way to show trust in them, with some consequences that are pretty obvious to anyone who has lived through their own teenage breakups.

There’s a solution: accounts for children could have a second, and separate, password for their parents. Then the kids learn good password habits and the parents can still check up on them if they feel the need. It’s even something of an improvement, since the kids can’t change the password to one the parents don’t know, and parents could presumably fix forgotten passwords for them. Of course, that opens up a whole ‘nuther set of problems (password management for the sites and programs using it, how does the site make sure the parent is the one setting the parental password and not the kid, and the big one, the fact that it’s a change from the way things are — just to name a few obvious ones), but those could be dealt with, if the will existed. Meaning they won’t be dealt with, and kids will continue to share their passwords, with predictable consequences.

“Life-size Portal gun to shoot onto shelves soon”

I’m a big fan of the game Portal, and it’s fairly classic, but I’m baffled by this. Replica swords and other medieval weapons I can understand, even replica firearms, but a replica portal gun doesn’t even sound as interesting as a replica lightsaber (which I refuse to even consider until a blade portion actually appears when you turn it on).

Linux compiles and massive IOWait delays, Part III

Remember the last IOWait delay entry, a couple days ago? If you took a look recently, you’ll have noticed a big WARNING! label on the top. There’s a good reason for that.

Everything was going along fine, but I started noticing some little problems (such as, the restart button on the shutdown dialog wouldn’t actually restart the system, it only logged me out, and the login screen wouldn’t remember that I wanted to use gnome-shell instead of the Unity interface). Nothing to cause me any concern, or to indicate anything but minor trouble.

Then, yesterday morning, the update-manager informed me I had some updates. As usual, I looked them over, then told it to install them. That’s when things started going wrong… I won’t bother describing the odd behaviors, suffice to say that it was pretty obvious something major was hosed. Looking back on it, I’m pretty sure I know how it happened, too: when I copied the /usr directory to its new drive, I didn’t take any precautions for handling hard or soft links.

Well, no big deal. I’d just done a backup of my data the night before, and hadn’t done anything that morning, so I didn’t even bother trying to back up any more-recent changes, I just popped the virtual installation DVD in the virtual CD drive (it’s a virtual machine, remember) and told it to reinstall the OS — but since I had to do it anyway, this time I decided to format the entire system drive as BTRFS. (My data is on a separate EXT4 virtual drive… I don’t quite trust BTRFS that far yet.)

The installation went off without a hitch. There was one small glitch, but that was easily worked around. As usual, restoring my data and installing my normal set of applications was pretty much a cinch.

Unfortunately I could find no way to turn on compression during the install, but that was easily remedied by adding the compress tag to the /etc/fstab entry and rebooting. The only problem is that it only affects files written after it’s turned on, but I found a page that mentioned a way to get existing files compressed. A simple Bash script applied it to the directories I felt were safe to do that on:

#!/bin/bash

doit () {
    for i in $(find * -type f)
    do
        echo "$i"
        btrfs filesystem defragment $i
    done
}

cd /bin
doit
cd /etc
doit
cd /lib
doit
cd /lib64
doit
cd /sbin
doit
cd /usr
doit

After that, I ran the same tests as in the earlier article. After dropping the cache (as described there) and reapplying the cache-pressure setting, I modified one source file and recompiled, as usual. The cache was still only 1.1GB when it was done, so the compression must have worked (and maybe that is as good as I could get it). But where that test took a little over four minutes in my earlier try, it took just under two minutes this time! (It’s apparently accurate too — I ran it again and got the same numbers.) A recompile after that took either 15 or 16 seconds, slightly better than the 16-or-17 from earlier.

The system also “feels” faster. I don’t know why that might be, maybe the extra cache is helping it or something hidden was slowing my older installation down. Given the numbers, I’m willing to believe that it’s not just observational bias. Booting it is noticeably slower, apparently because the BTRFS system has to do something on startup, but since I rarely have to reboot I can live with that easily.

I’ll post further on this subject if anything new comes up.