Unlimited Vacation

I usually don't spend much time on LinkedIn, but I signed in to check on something, and noticed a post near the top of my feed that illustrated a misconception that bothered me. The CEO of a startup posted saying that he didn't like the concept of "unlimited vacation"1 because (he believes) what ends up happening is that high performers suffer because they don't take enough vacation, and under-performers get away with taking a ton of vacation.

Another poster commented that they didn't like these types of policies because they're just a way of allowing companies to get around state requirements to carry unused vacation days as a liability, and pay out those days when an employee leaves. (This is true, at least in California.)

I reject all of these problems and submit that an unlimited vacation policy -- assuming employees actually do have the latitude to make use of it generously -- is a net good for employees. As long as you create a healthy culture around it.

First up, the financial argument: frankly, I don't care if it makes it easier for the companies financials or not. If an unlimited vacation policy does make it easier, that's great for the company, but whether or not the policy (and its implementation) is actually good for employees is unrelated to that.

Under-performers: if they're taking a lot of vacation and are not performing well, this is a failure of management. Why is the employee's manager approving so much vacation when there is a performance problem? Why is this employee not on a PIP, or, failing that, why has the employee not been fired?

High performers: this is a bit more tricky, because you don't want to demoralize or send mixed or confusing messages to high performers. One option is to enforce a minimum vacation policy on top of the unlimited maximum. Enforcement can range from simply deactivating an employee's work accounts for a period of time to get them to take time off, all the way up to penalizing them at review time (lower raise or equity grant, delayed promotion, etc.). Better would be to simply promote a culture of healthy time-off practices. Employees will implicitly look to their managers for cues on what they should be doing in these instances, and if they see their manager taking a generous (but not abusive!) amount of time off, they'll tend to do the same. This needs to be done at every level: the CEO needs to take sufficient vacations just as much as the rest of management and the individual contributors do.

At this point in my life, I would think of an accrued/fixed vacation plan as a big negative if I were considering an offer from a new company.


  1. For those of you perhaps not familiar with the concept, unlimited vacation refers to a policy where employees do not accrue vacation days based on time worked, or have any other kind of fixed number of vacation days (though the company often will close down for some number of public holidays). Employees are expected to take as much vacation as they'd like, with their manager's approval. 

Relaunch

I finally decided to redo my website, and ditch WordPress in favor of a static site generator (I decided to use Jekyll). I also took the opportunity to simplify the design.

There's a bit more to do, and likely some broken links here and there (not to mention some broken WP-to-markdown conversion), but it's time I finally got this done.

In theory, I'll start blogging again as well, but... we'll see.

Google TV and Native Libraries

The Google TV runs a fairly unusual flavor of Android (at least the 2nd-gen ARM-based devices). I have a Sony Internet Player (not the Blu-Ray version), so what I'm about to write applies to that device, but maybe not any other, though it stands to reason that the other ARM-based GTVs are the same.

Phone-and-tablet Android doesn't look much like a Linux desktop or server system. It uses the Linux kernel, to be sure, but a lot of the userspace libraries are custom. It even does not use Glibc, but a C library that Google wrote called Bionic. It's fairly stripped down and lightweight, and while it implements most things you might need out of a standard libc, it does not pretend to be POSIX compliant.

From some simple investigation, I've learned that the Sony GTV is running a EGlibc 2.12.2, and probably a mostly-unmodified version of it. Someone with an @google.com email address stated that the reason for this was that they couldn't get Chrome running against the Honeycomb version of Bionic.

Due to this, a Native Development Kit (NDK) is not yet available for the GTV. So the question remains: can we hack one together that works? The answer is... sorta.

With this knowledge in hand, I built a relatively standard arm-linux-gnueabi toolchain using crosstool-ng. Then I 'adb pull'-ed the contents of /system/lib from my GTV and merged them with the new toolchain's sysroot, copied some headers out of a stock NDK, and ended up with a sysroot that approximates what you'd find in platforms/ in a stock NDK, just without Bionic, and with EGlibc.

I didn't get to modifying the NDK's build system (it would need to be changed to find the new toolchain), so I built my native library manually, and got a simple "hello world" type app with a native lib. (It just calls a native method that returns a string, and displays the string on a label.)

One annoying thing is that the ABI string in the Sony GTV is set to "none", so you have to unpack the APK, rename lib/armeabi-v7a/ to lib/none/, and repack and resign it. All of this means that this would be strictly hobbyist for now: no chance that you could distribute something in the Play Store. Not only does Google have to release an officially-working NDK, but they need to decide on an ABI string, and get Sony (etc.) to push updates out to their customers that update build.prop on the devices with the new ABI string.

There's also the possibility that Google doesn't want to create and officially support that much native drift between phone-and-tablet Android and GTV Android, and will wait until manufacturers are running a more-stock Android 4.x on GTV (that uses the 4.x version of Bionic) before releasing an NDK that works... in which case we're at the mercy of Sony for updates, unless XDA or CyanogenMod wants to take a crack at it. My money's on this scenario, unfortunately.

One of the main things people have been screaming for is a version of XBMC that runs on GTV. I have been able to get it to build using my hacked-together toolchain, but not actually to run. I ran into problems with runtime linking: the built binaries depend on a shared libstdc++ and libgcc_s, neither of which appear to be included on the GTV's filesystem. I tried including them in the APK, but, weirdly, when the GTV unpacks the native libs from the APK at install time, it discards those two libraries. Static linking of those two may not be possible since XBMC's APK includes a bunch of native libs. A possible solution would be to build all of libxbmc.so's dependencies as static libs, and then just make one big static library.

But I haven't had time to work on this over the past couple weeks...

Techie TODO

In no particular order.

  • Start blogging again.

  • Suck less at Javascript, even if it's a shitty language.

  • Learn jQuery, even if it's just a library to make a shitty language less shitty.

  • Learn Rails properly.

  • Get back into open source dev.

  • Find a project/idea I can potentially monetize, and build and launch it.

  • Throw out my website entirely and start from scratch.

  • Stop running MacOSX all the time on my laptop and get back to using Linux as my primary desktop OS.

How To Save Artwork from Weavesilk.com

I just discovered weavesilk.com, which I think is pretty cool. However, it looks like they don't give you a way to save your generated artwork. If you're running Google Chrome (or, as I am, Chromium), there's a trick you can use to save what you've created. This can probably be done with Firefox using Firebug, and maybe in some other ways, but here's how I do it with Chromium.

  1. Create your artwork by dragging around.

  2. Right-click somewhere on the page and select "Inspect Element."

  3. In the new browser pane that comes up, click to the "Console" tab and enter the following:

    canvas = document.getElementById('render')
    img = document.createElement('img')
    img.src = canvas.toDataURL()

  4. The browser will probably freeze for a few seconds (or more than a few), and your CPU usage will shoot up. Be patient.

  5. Click to the "Resources" tab in the developer pane, and look in the list for something that starts with "data:image/png". Click it, and you should see your artwork to the right, on a transparent checkerboard background.

  6. Right-click the image and select "Save Image As."

The image will save with a transparent background, but you can open it up in an image editor and add a solid background color if you like.

Gentoo Linux on an 11" MacBook Air (October 2010)

I just posted a page detailing my experience installing Gentoo on one of the new MacBook Air models (in my case the MacBookAir3,1 with 1.6GHz CPU, 128GB SSD, and 4GB RAM). Hopefully it'll be useful for others.

Amazon MP3 Downloader on 64bit Gentoo Linux

Update 2010/12/04: A commenter recommended clamz instead. I've installed it but not yet tried it, but it's certainly easier than installing another OS in a chroot.

(This is going to be a bit of a narrative. If you're impatient, scroll to the "How-To" section at the bottom of the post.)

Today I decided to download an MP3 album from Amazon. I actually wanted all the songs on the particular album, and noted that you save a couple bucks by downloading the whole album vs. downloading each individual song. So click through, and find that it requires the Amazon Download Manager thingo.

Lame, I think. I click the download link, and it actually gives me some buttons to choose from that have to do with Linux. Huh. Nice work. However, I assume it's closed-source proprietary crap. But hey, why not give it a try.

My choices are two .deb files, one for Ubuntu Jaunty, and one for Debian 5, or two .rpm files, one for Fedora 11, and one for OpenSuse somethingorother.

So I grab the Ubuntu one. I'm on Gentoo, so I "emerge dpkg", and then run "dpkg -x amazonmp3.deb ." in an empty directory. I look in usr/bin that it created, and find a binary. But it's a 32bit binary.

Crap.

I run 'ldd' on it, and of course it needs gtk and a bunch of other stuff that I don't have 32bit libraries for. Like boost.

So I think, ok, I can install a 32bit chroot. So I download the stage3 Gentoo i686 tarball and unpack it in /opt/gentoo32. I also "emerge schroot" in my regular system, and set that up. I recently found schroot while using Ubuntu at work. It's awesome. Eventually the stage3 tarball finishes up, so I schroot into my new 32bit environment and "emerge libboost". After it's finished, I note a problem. Amazon's binary is expecting some weird version of boost that has "gcc42" in the filename. Also, I just installed boost 1.35, and it wants 1.34. Out of desperation, I try to make symlinks to the correct file names, assuming it probably won't work. I was right: it doesn't work. Balls.

Then I think... well, why not install a chroot of 32bit Ubuntu Jaunty? I "emerge debootstrap" and pray... yep, it's in portage, excellent. I install it, schroot into it, and apt-get a bunch of the libboost packages, and... holy crap, it works.

How-To

Here's a step-by-step. This is for Gentoo, but it should work equally well on any system where you can install debootstrap and chroot. The following instructions assume you've installed them already.

As root on the "main" system:

# mkdir -p /opt/ubuntu-jaunty-32
# debootstrap --arch i386 jaunty /opt/ubuntu-jaunty-32 http://archive.ubuntu.com/ubuntu/
# cat >/etc/schroot/chroot.d/jaunty32.conf
[ubuntu-jaunty-32]
type=directory
description=Ubuntu Jaunty (32-bit)
location=/opt/ubuntu-jaunty-32
priority=3
users=$USER
groups=$USER,root
root-users=root,$USER
root-groups=root,wheel
personality=linux32
run-setup-scripts=true
run-exec-scripts=true
aliases=jaunty
[hit ctrl+d]
# cat >/etc/schroot/mount-defaults
/proc/procnonerw,bind 00
/proc/bus/usb/proc/bus/usbnonerw,bind00
/sys/sysnone    rw,bind00
/dev/devnonerw,bind00
/dev/pts/dev/ptsnonerw,bind00
/dev/shm/dev/shmnonerw,bind00
/home/homenonerw,bind00
/tmp/tmpnonerw,bind00
/var/run/dbus/var/run/dbusnonerw,bind00
/usr/portage/usr/portagenonerw,bind00
[hit ctrl+d]
# schroot -c jaunty
(32bit)# groupadd -r staff
(32bit)# apt-get update
(32bit)# apt-get install sudo curl libglademm-2.4-1c2a xdg-utils libboost-date-time1.34.1 libboost-filesystem1.34.1 libboost-iostreams1.34.1 libboost-regex1.34.1 libboost-signals1.34.1 libboost-thread1.34.1
(32bit)# dpkg -i $DOWNLOAD_DIR/amazonmp3.deb

Note that I didn't just type all this verbatim... this was just my memory of what I did. So if something's missing, please leave a note in the comments and I'll update this.

Next you can try running "amazonmp3" to test it. If that works, you can go back out to your "real" system (just type "exit" in that shell), and do this:

# mkdir -p /usr/local/bin
# cat >/usr/local/bin/amazonmp3
#!/bin/bash
schroot -c jaunty -p /usr/bin/amazonmp3 -- "$@"
[hit ctrl+d]
# chmod +x amazonmp3

This creates a script in your "real" system that will chain to the 32bit amazonmp3 binary in your Jaunty chroot. You can set up your browser of choice to automatically launch this script when you download .amz files. At this point you can try running "amazonmp3" from your "real" system (outside the chroot) and see if that works.

There are also a few other things: 1. If you are running a system that uses GDM to log in, you may need to add /var/run/gdm to the bind mounts in the mount-defaults file or else apps started in your chroot won't be able to connect to your X server.

  1. If you're using non-default gtk2 theme engines on your "real" desktop", you'll need to install them in the chroot (via apt-get) as well. Well, ok, you don't have to, but if you don't, the Amazon app will look uglier than it should.

  2. Remember to always pass the "-p" option to schroot. If you don't, the environment in the chroot will get reset, which means you'll lose your DISPLAY env var, and you won't be able to connect to the X server without manually setting it.

  3. When I first ran the apt-get command in the chroot, I got some weird errors at the end of the process about some packages not being configured because another package (gtk, I think) that it depended on hadn't been configured yet. Just running the same apt-get command a couple times fixed it, strangely.

  4. Make sure your "real" system has /usr/local/bin in the PATH.

Anyhow, that's it. Works like a charm.

Code Comments

I'm a bit of a minimalist when it comes to commenting my code. This is probably in some ways a bad thing; code that is completely obvious to me in its function may be difficult to understand for others, and I'm often not so great at realizing this on the first pass.

So that leads me to the purpose of code comments:

The purpose of commenting your code is to inform readers of that code what a section of nontrivial or non-obvious code does.

At least, this is my definition. Opinions differ, I'm sure. I might also add to that a clarification: "readers" in this case may include yourself. Code you wrote may even be incomprehensible to you if a decent amount of time has passed.

From this definition you can also infer something else, that I believe it's unnecessary to comment obvious code. In fact, I'd argue that it's harmful to comment obvious code, because you're making it harder to follow, and you're adding a barrier in front of the reader being easily able to distinguish between trivial and nontrivial code at a glance. You also increase the length of the code fragment, which may make it more difficult to read and understand in its entirety (if you can't fit the entire fragment on one screen, you'll have to scroll back and forth to see the entire thing).

However, too often -- very often, it turns out -- I see things like the following:

/* take a reference */
g_object_ref(object);
/* free string */
g_free(str);

And one of my favorites:

/* set the label text to "Time Left:" */
gtk_label_set_text(GTK_LABEL(label), "Time Left:");

(Yes, I actually have seen something very similar to that, though I don't remember what the label text was.)

How do these comments actually add anything useful to the file? Every time I see one of these, a little part of me dies inside.

Now, the last one is just silly. Even someone who has never developed using the gtk+ UI toolkit can figure out what that line of code does without the comment. If you can't, then a code comment there probably isn't going to be enough to help you overall in any case.

The middle one is equally silly, though it's understandable that someone might not know that g_free() is the glib equivalent of free(). However, consider your audience: is an extra line of code for a comment really useful here?

The first one is not quite so easy for me to dismiss. It presupposes a few bits of knowledge:

  1. Understanding of what reference-counted memory management is.
  2. Familiarity with the "ref/unref" pair, as opposed to only being exposed to something like the OpenStep "retain/release" (or even the COM/XPCOM "AddRef/Release") terminology.
  3. At least passing knowledge of what a GObject is.

Now, for code that makes heavy use of reference counting, I think presupposing #1 is not unreasonable. In this case, it doesn't matter: the comment as presented will not help you if you don't know what reference counting is.

Points #2 and #3 depend on your goals and potential audience. If you think that a decent number of readers may not be familiar with the "ref/unref" terminology, "take a reference" is probably enough to generate an "oh, duh!" moment in the reader's head. As for #3, unless you intend your code to be able to act as a sort of GObject tutorial, that is, something that people aspiring to learn GObject programming might want to read, I think the comment there does not serve people unfamiliar with GObject. Regardless, most GObject-using code will probably be pretty confusing to someone who doesn't know GObject, so whether or not you should comment g_object_ref() is going to be the least of your worries.

Now, I'm not going to claim that my code commenting is perfect... far from it. I could certainly stand to sprinkle comments a bit more liberally throughout my code. I tend to only comment public API (and then just a description of what the function does, not how it does it), and code fragments that are really nontrivial1 and potentially hard to understand.

But there has to be a happy medium somewhere. While too-infrequent commenting can certainly make code harder to understand, I'd argue that too-frequent commenting is worse. It's sorta like "the boy who cried wolf" in the sense that comments draw my eyes to them as a way of saying, "pay attention! This bit here is important!" (or tricky, or whatever). Overuse of comments just makes me start skipping over all of them, useful or otherwise.


  1. It's worth noting here that this point further reduces my volume of comments. I generally prefer clear code over neat hacks, even if the neat hack represents a reduction in lines of code or a moderate increase in performance. If I write a section of code and then look at it again and see that it looks too complex, I'll usually try to immediately rewrite it to be simpler. 

« prev 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 next »