Nathan's Lucubrations; on computers, music and the outdoors

Sat, 29 Mar 2014

Thank You, Google

In the spirit of "Thank you for giving me the opportunity to explain this to you" (TL;DR - free software doesn't have "end" users, that's the point), I'd like to thank Google for forcing my hand.

You see, I've been thinking for some time now that I shouldn't be so reliant upon other people's servers, or more importantly, other people's closed source software. To be sure, I have rid my life as much as possible of things I cannot fix, such as Windows and OSX, but I had fallen into relying upon things such as Google Maps to share GPS tracks of my hikes.

It was pretty cool and handy to be able to post my GPS tracks (converted to KMZ in Google Earth) to my web server, and then tell Google Maps to load the link and show the topographical layer, then share a link to that with friends and family. As opposed to a static image that couldn't be explored, or sharing a file that would have to be downloaded and opened in a separate program, this allowed people to click on a link and instantly be able to zoom around and get a feel for where I had traipsed off to.

But then Google decided to "improve" the interface to Maps, and much like the "improvements" they've made to their standard search engine over the years, they have let some features evaporate. I now can't just paste in a simple URL to a KMZ file on another server. I can't even begin to figure out how to get Google Maps to let me reproduce the perfectly good functionality that had existed up until recently. I suspect I have to sign in to some picayune social network to accomplish the same thing now.

No thanks. I've been researching alternatives for quite some time now, and while it is not quite as slick as Google Maps, at least it does what I want, and I have control over what features do and do not exist in the product.

So while I had been thinking about doing this for a while, I'd like to thank Google for helping to make my choice clear, and helping me to remove one more piece of closed source software (Google Maps) from my life. Thank you Google!

EDIT: So, trying this again, it appears to be working now (2014-03-29). Not sure why, but it still stands that I'd like to have a photo gallery of my own, with a slideshow feature and be able to display a track overlaid on a topo map with links to photos geolocated on the map. Open source and open data required, plus I'd prefer something lightweight and not written in PHP, so phpMyGPX, while nice, doesn't quite fit my needs. I'm currently looking to Python and the multitudinous libraries thereof (mapnik, Kartograph, and gpxpy are just a small sampling). There's also some really interesting things going on at OctoMap, which just so happens to overlap with the current direction of the project at my day job, not to mention that it brings me back closer to the work at ROS that I had leveraged for another project at work and also had to do with mapping. Fun times!

posted at: 13:12 | path: | permanent link to this entry

Tue, 18 Feb 2014

Winter Overnight: Wotans Throne

On Sunday and Monday, I went on Bob Huey's overnight trip to Mt. Whitney, but we bailed and bagged Wotans Throne. Photographs.

posted at: 09:55 | path: | permanent link to this entry

Sun, 09 Feb 2014

Hike: Skinner Peak

I hiked Skinner peak with Bob Rockwell, Linda Finco, Dave Doerr, Tom Sakai, Mike Myers and Walter Runkle on 2014, February 08. Was a fairly blustery day, but a beautiful hike nonetheless.

Photos and GPS tracks.

posted at: 09:44 | path: | permanent link to this entry

Fri, 04 Jan 2013

Man Page a Day

Reading Hacker News, I came across someone's goal of reading a man page a day. The discussion around that post quickly turned to how to pick manual pages, and I decided to try to come up with a way to automatically load a random one in Emacs. Here's the result:

;; Taken from http://emacswiki.org/emacs/ElispCookbook#toc57
(defun directory-dirs (dir)
  "Find all directories in DIR."
  (unless (file-directory-p dir)
    (error "Not a directory `%s'" dir))
  (let ((dir (directory-file-name dir))
        (dirs '())
        (files (directory-files dir nil nil t)))
    (dolist (file files)
      (unless (member file '("." ".."))
        (let ((file (concat dir "/" file)))
          (when (file-directory-p file)
            (setq dirs (append (cons file
                                     (directory-dirs file))
                               dirs))))))
    dirs))

;; Taken from
;; http://stackoverflow.com/questions/3815467/stripping-duplicate-elements-in-a-list-of-strings-in-elisp
(defun strip-duplicates (list)
  (let ((new-list nil))
    (while list
      (when (and (car list) (not (member (car list) new-list)))
        (setq new-list (cons (car list) new-list)))
      (setq list (cdr list)))
    (nreverse new-list)))

;; Display a random manual page
(defun open-random-man-page ()
  (interactive)
  ;; Get manual page paths from the environment.
  (setq man-paths (parse-colon-path (getenv "MANPATH")))
  ;; What if MANPATH isn't set or is empty? We'll take a guess:
  (if (eq man-paths nil)
      (setq man-paths (list "/usr/share/man")))
  (setq man-dirs ())
  (dolist (man-path man-paths)
    (setq man-dirs (append man-dirs (directory-dirs man-path))))

  ;; Get a list of files in manual page paths.
  (setq files ())
  (dolist (man-dir man-dirs)
    (setq files (append files (directory-files man-dir nil "^[^\.].*"))))

  ;; Fixup the files to be a list of man pages.
  (setq man-pages ())
  (dolist (file files)
    (setq man-pages (cons (car (split-string file "\\." t)) man-pages)))

  (setq man-pages (strip-duplicates man-pages))

  (random t)
  (princ "Selecting random manual page from " t)
  (princ (length man-pages) t)
  (princ " possibilities." t)
  (manual-entry (nth (random (length man-pages)) man-pages)))


syntax highlighted by Code2HTML, v. 0.9.1

I'm sure there's a more elegant way of doing this, but it works, mostly. It doesn't filter out subdirectories (such as man1), and only gives you the default manpage if there is more than one (such as read). Some other things caught my eye though: on my main home machine, this code finds roughly 20k manual pages, which would take over 50 years to read if you only read one a day. Of course, you could read more than one a day, or focus on things you are using or interested in. Another way to use this code is as a starting point: fire up a random manual page, then research more from there, or at least after reading it you are aware of "the tip of the iceberg" (especially in the case of many libraries with man pages).

posted at: 10:43 | path: | permanent link to this entry

Sun, 15 Jul 2012

The Copy Constructor and Return Value Optimizations

Recently, I was tracking down a crash caused by mixing memory allocation/deallocation functions, and in the course of trying to create a solution, I came across something puzzling. I was attempting to recreate the canonical pedagogical example of passing or returning by value in C++, which normally makes use of the copy-constructor. Indeed this is what most textbooks on C++ claim. Yet the following code produces unexpected output upon execution:

/*BINFMTCXX: -DSTANDALONE
 */

// For std::cout and std::endl.
#  include <iostream>

class MyClass
{
public:
  MyClass():
    m_ii(0)
  {
    std::cout << "MyClass()" << std::endl;
  }

  MyClass(const MyClass&):
    m_ii(1)
  {
    std::cout << "MyClass::MyClass(const MyClass&)" << std::endl;
  }

  int m_ii;
};

MyClass myFunc()
{
  MyClass tmp;
  return tmp;
}

int main(void)
{
  MyClass a(myFunc());
  std::cout << a.m_ii << std::endl;
}  // int main(int argc, char* argv[])

Running this, I get

MyClass()
0

Only one constructor is called and it's not the copy-constructor. Why is this? You can try all sorts of methods to "force" the compiler to call the copy constructor, but ultimately, the compiler probably knows more than you. In the end, I tried modifying the class in the function before returning it, passing a value derived at run-time to make sure that couldn't be optimized; I tried privatizing the copy constructor as it obviously wasn't being called; I even tried throwing an exception in the copy constructor. Nothing worked! Until I tried this:

MyClass myFunc(const MyClass& orig_)
{
  return orig_;
}

int main(void)
{
  MyClass orig;
  MyClass a(myFunc(orig));
  std::cout << a.m_ii << std::endl;
}  // int main(int argc, char* argv[])

The key here is that the copy constructor is required. Previously, it was obvious to the compiler that tmp wouldn't exist outside of myFunc, so quietly eliding all those constructors (one for tmp, one to copy tmp into a) and destructors was the logical thing to do. Only when the compiler couldn't get away with that did we force its hand and make it use the copy constructor.

As an aside, the flag -fno-elide-constructors will force GCC to use copy constructors for all pass by value operations. Interestingly, if you make the copy constructor private, GCC will not compile the first example, claiming that the copy constructor is required for return by value.

posted at: 21:23 | path: | permanent link to this entry

Tue, 15 May 2012

Please . . .

Lately, there's been a spate of writings in response to a controversial one entitled "Please Don't Learn to Code". People have been exhorted to "Please Learn to Code", "Please Don't Become Anything, Especially Not A Programmer", etc, etc. While I'd be loathe to tell anyone what to do (anarchists never ruling and all that), I would like to offer some friendly advice to those willing to take it: learn.

Learn something, anything, just don't sit still. Those who don't learn history are doomed to repeat it, and if you're learning something, it's probably already history (of which I'll get more into in a bit).

In particular on programming: it couldn't hurt to know how to slap together a bit of code to quickly solve a problem. That's how a lot of great programmers got started. I'd also like to think that the original article is not discouraging people for fear of competition; he actually makes it quite clear that what he would like to discourage is more bad code coming into existence, and he thinks that by discouraging non-programmers from learning to code that this will help. That's where I think he goes wrong.

If anything, the people who should either learn how to code properly or not even bother are the ones who are already writing software. You think I'm joking? I've seen enough bad code to realize where Atwood is coming from. I'd rather that when someone wants a problem solved, they don't dredge up something entirely inappropriate and unmaintainable, but actually ask to have something designed properly from the get go. If someone has tried to learn how to write good software, but can't (or worse, won't), then they should stop giving their code to others. Please note that I didn't say they should stop coding, just that they shouldn't let their little monstrosities into the world.

And here's where we have the dichotomy. Should people, in general, have a better understanding of computers and how they work, even being able to program them, so that they can solve problems on their own? Most definitely yes. Programming is an incredibly liberating and empowering experience. You can create whole worlds, universes even, while programming. I can't recommend it strongly enough to everyone.

Now comes the other side of the coin: good software is hard to get right. It takes practice, perseverence, study and discipline. Should people release their dirty little one-off hacks, just to try to be helpful? I appreciate the sentiment, but that kind of thinking got us PHP. Programming is fun, and can be extremely useful in solving problems. But not all code is created equal.

Code to be released to others has to have some sort of value. If it only solves your problem, who cares besides you? It might be able to be worked into something more flexible, more reusable, possibly even something bug free. But is it really worth the effort? Especially when designing something properly from the start would get you the same results with less overall effort?

Again, I don't want to discourage anyone from learning, and here's where history comes in. You need to read. Sure, you may have written a script to automate some dreary task, and now you want to do more. Great! Pick up the classics. Read "Mythical Man-Month" and learn not just why planning is important, but why throwing more monkeys at the code won't help, and maybe most importantly, learn what we've lost. You do know that it used to be standard practice to have a fully working emulator for hardware before the hardware existed so that the systems programmers could work in parallell with the hardware guys, right? Or did you know that the mouse and teleconferencing have been around longer than most people think? Those nifty features in your current favorite programming language? Already in LISP fifty years ago.

The computing industry is full of history lessons that have been forgotten. It's also full of untold wonder. My advice is to learn, whether you are a new or old programmer. Learn to write good code; be a net positive and create gloriously beautiful works of art that solve incredibly hard engineering problems. When someone says it can't be done, ignore them. When someone says you shouldn't learn something, learn that thing.

And look at code, good code. How do you know good code? It's been around a while and people are still working on it. This might seem counterintuitive, but if it's so bad that it's unmaintainable, people will start over from scratch with something else. Granted, this is a pretty low bar, but if you look around at things like the Linux kernel you can learn all sorts of things. Don't be afraid to go on sites like GitHub and just start clicking on things. Find your favorite piece of software and download the source code, see if you can get it to compile.

Sure, you may not write practical code right away. You may be (rightfully!) shouted down for the first crummy patch you submit to an open source project. Just take your licks, learn from the experience, and improve your code. These things don't come overnight. And don't be ashamed if you can't learn how to code. Some studies suggest that a large percentage of the population can't learn to program. At that point you might want to move on to something else, so as not to slow down others by creating code they will have to fix. It's also okay if you don't like programming; there are enough of us who do. You don't have to be an expert at everything. You can't either.

I guess ultimately my practical advice would be to pick up Python and go through one of the many tutorials or books online. Why Python? It runs everywhere and is fairly easy to start with, but has enough power and extensions to make it applicable to just about anything. Plus it's not PHP or VisualBasic.

One last thing: that whole thing about Python having tons of extensions was a subtle hint. Don't reinvent the wheel. Sure, it's good practice to write code, maybe perform some katas, but don't create a piece of software that already exists unless you can do it better. Keep an eye out for libraries, extensions, toolkits and frameworks that will make your programming sessions that much more powerful.

posted at: 20:22 | path: | permanent link to this entry

Sat, 18 Feb 2012

Dear speedpatch,

Stop overwriting my gorram user ~/.bashrc. KTHXBYE.

(bug report and patch later; I'm kind of busy right now)

posted at: 12:13 | path: | permanent link to this entry

Tue, 13 Sep 2011

New Name: "Nathan's Lucubrations"

I probably should have thought of this earlier, but there are more than a few blogs entitled "Nathan's Musings". At least mine shows up fairly close to the top, but that also means it's too late to change it now. Or is it?

I've always been amused by words that have fallen out of fashion; it's funny where they turn up, and they have a certain flavor, a certain je ne sais quoi that make them interesting to me. Perhaps it's just that they are not common, something new (to me at least). Words like ablution and accoutrements.

I think we lose something when we let certain words fall out of use. Much like some foreign words (like simpatico) which the native speakers claim don't have an equivalent in english, forgetting words with different shades of meaning limits our expressiveness. Much as someone curses when they are angry and so they can't muster the concentration to form a proper epithet, we end up not saying exactly what we mean.

With all that said, I'm going to rename this blog to "Nathan's Lucubrations", mostly because it doesn't turn up a lot of search results in Google, but also because I like it. I can't guarantee all my entries from now on will be written at night, though ;)

posted at: 23:01 | path: | permanent link to this entry

The Best Music You've Never Heard of: Boom Boom Beckett

Yet again, I'm pressed for time, so I'll toss another entry into my ongoing attempts to edify the Internet and lift worthy works of art out of the shadows. This time, it's "Vélos" by Boom Boom Beckett, yet another band whose music I came across whilst randomly sampling Jamendo. Unfortunately, they only have one album and a single up on Jamendo, but I have to say that both please me, albeit in different ways.

"Vélos" is a nice little laid back jazzy album, which, while not a masterpiece, definitely has some very nice tracks. The whole album is technically competent, but "M.eur Chagall", "Salsa di Soy" and "Oat Flakes" definitely make this album worth downloading for any jazz fan.

The single is a remix of "Salsa di Soy", and it takes it in a more techno-ish direction. Fairly amusing, especially if you've ever had an disagreement with a fellow performer over chords or notes.

posted at: 22:23 | path: | permanent link to this entry

Mon, 12 Sep 2011

The Best Music You've Never Heard of: Mud&Dust

Not a lot of time for an entry today, so I'm going to fall back on an idea I've had for a while. There's a lot of music out there, not all of it good. Used to be, the labels would find "good" music (for some definition of "good") and publish it. These days, the labels are (mostly) engaged in fucking people over through the legal system, especially since they've been made irrelevant by the Internet. The Internet, however, is not always that "good" in selecting "good" music (again, for some definition of "good"). What is an audiophile to do?

Well, I have some experience making (and listening) to music, so I figure I have as much of a right as anyone to post what I think is "good". Besides, it's my blog; if you don't like the music I like, go write your own blog. Hopefully you will find my selections at least interesting, and be thereby edified. If not, I'll give you a full refund.

Today's selection is Mud&Dust, a Trance/Psychedelic group with what I consider excellent programming music on an album also called Mud&Dust.

Oh, by the way, I will be posting only music that is available in the public domain or a reasonable creative commons license, because, a) you can try it for free, and b) we all really need to start boycotting big labels and their ridiculous copyrights. Big labels can suck it.

posted at: 17:11 | path: | permanent link to this entry

Sun, 11 Sep 2011

Linux Plumbers Conference

I just got back from the 2011 Linux Plumbers Conference. Definitely glad I went. It's been a while since I've done any serious hacking on the Linux kernel, so there was a lot of learning on my part. I'm glad to see that there is still a lot of momentum and excitement in the community. It's also nice to hear people admit some of Linux's shortcomings, and more importantly, discuss ways to remedy those shortcomings.

The energy was inspiring, and some of the conundrums brought up have tweaked my interest. I thought I'd jot a few things down that I think might be worth revisiting, and hopefully I will get time to look into them in future posts:

I hope to delve deeper into these topics later; who knows, if I manage to scrounge up enough time, I might even be able to test out some solutions to them.

posted at: 14:53 | path: | permanent link to this entry

Mon, 05 Sep 2011

Wither Bastille?

One of my favorite Debian packages is Bastille, a collection of scripts to harden computers. Sure, I could do all these things myself by hand, but it's nice to have an automated method that covers most things I would do anyway.

Bastille is fairly thorough, and happens to cover more than just Debian. Unfortunately, it seems to have become unmaintained, and while the version packaged for Debian still works fairly well, there have been some cracks. For one, even the experimental Debian package of Bastille doesn't support the (current) stable distribution of Debian. There is a quick fix for the "not a supported operating system" problem, but the previous packaging of Bastille has a statoverride umask problem where it sets the permissions of critical executables to 0000 (no read, write, execute or anything for anyone, not even root!).

I'm hoping that something better comes along, or someone starts maintaining it; it's tempting to do it myself, but to be honest, I have neither the time, inclination nor expertise to keep Bastille current for anything other than Debian.

posted at: 15:19 | path: | permanent link to this entry

Thu, 01 Sep 2011

Bash Completion is F*cking Magic

In case you don't have it installed, I highly recommend the bash-completion package (Debian and derivatives should be able to "apt-get install bash-completion" and source (via ". /etc/bash_completion") the scripts to get this working; pretty sure it comes standard and is sourced by default on fresh installs of squeeze). Among other things, it manages to autocomplete filenames. On other hosts. Over ssh. Without any (very) noticable delay (or maybe the beer is just slowing me down that much; I'll have to check later to see what bash-completion does behind the scenes).

I was going to post something more comprehensive on rapid prototyping and unit testing in C++, but that will have to wait until I get my RCS -> Git sh*t sorted out. In the meantime, have fun with bash. I know, I know, you zshers and kshers are probably silently chuckling at us knucklehad bash users, but hey, at least we're (finally) catching up, right?

More links to goodies to come soon! And maybe comments for the blog. Happy hacking!

posted at: 21:26 | path: | permanent link to this entry

Fri, 22 Apr 2011

Usability, cron and nice

So I'm typing along, when all of a sudden, my system comes to a crawl. Windows go blank, apps don't respond to key presses. Normally, I wouldn't be surprised. But wait a moment; this isn't Windows or OSX; it's Linux. WTF is going on? I check top:


top - 08:04:54 up 32 days, 21:15, 15 users,  load average: 6.06, 3.74, 1.92
Tasks: 205 total,   1 running, 203 sleeping,   0 stopped,   1 zombie
Cpu(s):  1.6%us,  1.3%sy,  0.0%ni,  0.0%id, 97.1%wa,  0.0%hi,  0.0%si, 0.0%st
Mem:   4107088k total,  2512484k used,  1594604k free,   420900k buffers
Swap:  2654200k total,   450656k used,  2203544k free,   462820k cached

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
 2569 root      20   0  140m  51m  12m S    3  1.3 322:06.24 Xorg
  768 npsimons  20   0  190m  21m  10m S    1  0.5   5:36.34 gnome-panel
  355 root      20   0     0    0    0 S    0  0.0 127:30.59 kcryptd
 3454 npsimons  20   0  132m 8868 5948 S    0  0.2   4:51.28 metacity
 4011 npsimons  20   0  134m  10m 6112 S    0  0.3   4:09.77 gnome-terminal
11960 root      30  10  2328 1180  488 D    0  0.0   0:02.63 sxid

The one thing that catches my eye is sxid, a security checking program I installed that automatically checks changes in status or permission on suid executables. But why is it running now, instead of late at night when I'm not around? Checking /etc/crontab, I find this:


25 6	* * *	root	test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )

WTF?! Who thought it was a good idea to start cron jobs at 06:30? And the entries for weekly and monthly are similar. Okay, simple, change them to slightly after midnight; if I'm still on the computer by then, that will be my indication to go to bed.

But then I have another thought: there's plenty that gets run from cron, and only sxid is causing problems; why? sxid is fairly new, but it should at least have a crontab that nice's it properly, right? No:


#!/bin/sh

SXID_OPTS=

if [ -x /usr/bin/sxid ]; then
	/usr/bin/sxid ${SXID_OPTS}
fi

Programmers/packagers, here's a hint: even though your software may be "system" software that runs in the background, you still need to think of usability. Don't be like Symantec. This isn't Windows or iOS; our OS *can* walk and chew bubble gum at the same time. Don't abuse the privilege, and take a look at other cron scripts where use of nice(1) and ionice(1) are standard.

And yes, I should probably send a patch instead of just bitching. Just for reference, here's how I fixed it (which I partially cut and pasted from the debsums daily crontab):


#!/bin/sh

SXID_OPTS=

if [ -x /usr/bin/sxid ]; then
	nice -n 19 ionice -c 3 /usr/bin/sxid ${SXID_OPTS}
fi

posted at: 08:50 | path: | permanent link to this entry

Sun, 17 Apr 2011

Climbing Morris Peak

Went for a hike on Friday with other CLMRGers to Morris Peak. Not a real strenous challenge, although it did leave my calves a bit sore. Nevertheless, it's always good to get out in the fresh air and sunlight with friends.

posted at: 17:21 | path: | permanent link to this entry

Wed, 13 Apr 2011

Of "Bolero", Saxophones, and Forgotten History

"And some things, which should have not been forgotten, were lost." - "Lord of the Rings"

They say that those who forget history are doomed to repeat it. I've always wondered when I hear this, what's the cycle rate? Is it constant, or does it vary for different fields?

Joking aside, sometimes things which are "forgotten lore" can explain why things are as they are today. This is also an important point as to why public domain and freely accessible records (assuming there are records) are important: without an accessible record of history, how can we learn from our mistakes? How can we understand progress (or, lacking progress, simply the state of the world)?

One of the things that has piqued my curiosity was why Ravel had composed "Bolero" for not just B-flat tenor and B-flat soprano saxophones, but also the F-natural sopranino saxophone. Who had heard of such a thing? Everyone knows that saxophones come only in alternating B-flat and E-flat transposing models, except for that relic of history, the C melody. So, when it came time to play the F-natural sopranino part of "Bolero", I simply picked up my B-flat soprano and played it's part again; after all the passages were identical, right down to the phrasing and articulation (excepting that it was for an F sopranino).

Couple of years later, during a private lesson, my instructor points out "Universal method for the saxophone" by de Ville. Turns out, there were actually two series of saxophones, one pitched in F/C (the "orchestral" series) and the one we all know and love today in Eb/Bb (the "military band" series).

"Universal Method" is out of print, and if it hadn't of been for efforts like the one at The Internet Archive, knowledge like this might have been lost. And that's just stuff from the first ten pages! History, indeed, has much to teach those willing to listen.

posted at: 21:55 | path: | permanent link to this entry

Thu, 07 Apr 2011

Why Blog?

Why have a blog? I've always thought that blogs are kind of egocentric, self-centered little pieces of fluff, not worth much. Blogs aren't really anything new; they're basically homepages, and I've had one of those long enough. So why have a blog?

I guess I'm trying to have a place to write down my thoughts. Of course, I could easily enough do that and keep them to myself. I guess I'm also trying to find a way to contribute, give back to this wonderful thing called the Internet. Because for all it's failings, I've found many, many good and worthwhile things there (and those are just two examples off the top of my head).

And yes, I'll admit, I'm trying to grab some attention, make my mark, or at least get you curious enough to look at my resume.

posted at: 19:08 | path: | permanent link to this entry

Thu, 24 Mar 2011

Really cool Debian package: binfmtc

This is something I really keep meaning to tell people about: binfmtc. It may not seem like much, but being able to rapidly iterate a prototype, or just test something to learn about how it works is tremendously powerful. I think it was Brooks' in "Mythical Man-Month" who said that interactive programming should not be overlooked as a very powerful tool.

The real nifty thing, though, are the included example utilities, realcsh.c and realksh.c. No, those aren't replacements for Korn shell and C shell. They are actual scripting shells for C and, wait for it - kernel mode scripting! That's right, with root privileges, you too can be mucking about in kernel space, right on your very own commandline! Dangerous but awesome!

Just to give you and idea, here's my Template.cc I've been using over the past months to work on exercises from Thinking in C++, Volume 2:

/*BINFMTCXX:
 */

// -*- Mode: C++ -*-
// Copyright (C) 2011 Nathan Paul Simons (C2T9uE-code@hardcorehackers.com)
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// Alternatively, the GPL can be found at
// http://www.gnu.org/copyleft/gpl.html

// For copy().
#include <algorithm>

// For std::cout and std::endl.
#include <iostream>

// For std::ostream_iterator<>.
#include <iterator>

// For EXIT_SUCCESS.
#include <cstdlib>

int main(int argc,
         char* argv[])
{
  using namespace std;

  if(argc < 1)
    return EXIT_FAILURE;

  copy(argv,
       argv + argc,
       ostream_iterator<char*>(cout, "\n"));

  std::cout << "Hello, world!" << std::endl;

  return EXIT_SUCCESS;
}

Just 'M-x insert-buffer RET Template.cc' and you're good to start hacking! You can add compiler flags either to the line starting with /*BINFMTCXX: or put them in the environment variable BINFMTCXX_GXX_OPTS. I prefer the latter, as I use quite a few, which I initially picked by running 'g++ --help=warnings | awk '{print $1}' | sort | egrep "\-W"' on the commandline and weeding out the ones that didn't apply to C++ from there, then additionally eliminating flags that were more annoying than helpful (such as -Wabi, -Waggregate-return, -Winline, -Wpadded, and -Wunreachable-code). You can also link to external libraries this way, but it doesn't always work cleanly for linking to external object code (.o files); your safest bet is relying on libraries that only require header includes, or just including implementation source files (.cc files).

posted at: 17:12 | path: | permanent link to this entry

Sun, 20 Mar 2011

Show, don't tell

It's an old maxim that in writing, you should show, don't tell. Don't say a character is happy, have him literally jump for joy. To some extent, this precludes a third person point of view, obviating the need for an omniscient narrator. Sometimes that can be a good thing, to let your audience get a better feel for being in the situation you are describing, helping them suspend their disbelief.

This carries over into other fields. For instance, there are those who hold that any film that starts with with textual exposition has points against it. Some even go so far as saying that telling or showing too much can ruin the horror of an unseen nemesis (cf. Alien vs. Aliens).

Even more interesting is where it carries over to other seemingly unrelated fields, say web design. Or programming. Far too often, I will see code like this:

// Count the number of doodads.
int ii;
for(ii = 0; doodads[ii] != NULL; ii++);

Is it concise? Sure. Will it work? Maybe, if doodads has a NULL pointer as its last element. But is that comment really necessary? I've always believed that code should tell the "how" and comments should tell the "why"; if your code doesn't tell the "how", then it needs to be rewritten to be more understandable. Two simple changes could make this code better:

size_t num_doodads;
for(num_doodads = 0; doodads[num_doodads] != NULL; num_doodads++);

Change the variable name and the comment becomes unnecessary. Better yet, if you are using an STL container, let it do the work for you:

const size_t num_doodads(doodads.size());

That's if you really need the number of doodads and are assuming it won't change; it's probably best just to use the member size() call everywhere you need it. Also, don't rule out iterators; they may seem like a silly concept at first, but the nice part is that they work with any container, so changing out containers becomes dead simple, with the proper forethought:

typedef vector<int> Container;
typedef vector<int>::iterator Iterator;
Container myCollection(10);
for(Iterator itr(myCollection.begin());
    itr != myCollection.end();
    itr++)
  cout << (*itr) << endl;

By changing two tokens (the two vector tokens in the typedefs, to say deque or list), you can get different performance characteristics and tune for your particular application. Of course, you have already profiled the code to make sure that the biggest slowdown is because of using vector, right? In the end, though, this really helps readability, because to other programmers, it is clear that you are using a Container and you are iterating through all its elements; the underlying implementation doesn't matter.

Quotes to live by:

Programs must be written for people to read, and only incidentally for machines to execute. -- Abelson & Sussman, SICP, preface to the first edition
Any fool can write a program that the computer can understand. It takes a good programmer to write a program that other people can understand. -- Martin Fowler
I can't tell what the hell his code does, it's mostly comments. -- Adam Radford

posted at: 17:13 | path: | permanent link to this entry

Mon, 14 Mar 2011

First blog post - testing

I finally got around to installing blog (I hate that word) software. For now, I'm still learning how to use it, but you can expect me to randomly post about computers (software, Linux and programming mostly), music (performance, jazz and big band mostly), and the outdoors (hiking, climbing, search and rescue).

A little about myself: I play saxophone (alto and soprano) and clarinet in the local big band (which I also administer the website and mailing list for) and saxophone (alto, tenor, baritone, and soprano) and percussion (cymbal pit) in the local community orchestra. I've dabbled a very wee bit in music theory and composition, mostly electronica, but would like to get more into that someday.

I'm also a member of the China Lake Mountain Rescue Group. I like to hike, rock climb and backpack, plus it's nice to feel I've helped people.

For my day job, I write software. These days it's mostly C++ and preferably Debian GNU / Linux. I administer my own email and web server (which you're reading this from) and home network, also using Debian.

posted at: 00:00 | path: | permanent link to this entry

powered by blosxom