[macroexpand.com/~bm3719]

February 27, 2013 - Apologia Pro Vita Sua

The saddest day of your life isn't when you decide to sell out. The saddest day of your life is when you decide to sell out and nobody wants to buy.
- Norman Spinrad

About 6 years ago I decided that I wanted to be permanently free from having to be employed. I met that goal a while back and am currently just finishing up my targeted buffer amount. So, I'll be calling it a career soon. While many others have accomplished this, it's a pretty rare thing to do these days if you don't have a pension or some other way to socialize your living costs, particularly at my age. Here's the theory and practice I developed to make this happen.

Some Definitions

I define "financial independence" as the ability to not ever have to have a job or otherwise labor for income in order to provide for the means to pay for projected expenses over your maximally plausible remaining lifespan. If this is a reasonably lengthy period of time, this necessarily will have to include some healthy buffer amount to account for the unforeseen expenses that are sure to arise at some point in all those years.

"Employment" hereafter refers just to the W-2 kind. I would probably consider self-employment of the variety that is largely indistinguishable from this in the same category though, like if you owned and operated your own food truck.

For me, "retirement" means ending having a job with no intention of returning to one. This is admittedly a sloppy definition, since it doesn't apply to those who have to work in some non-job context. Making my definition even more complicated is that I wouldn't necessarily exclude certain arrangements that may actually fall under my above definition "employment", as there are still contracts between parties where some service is delivered that I may do for other reasons (i.e. there's some jobs I'd accept for a very short period, just for fun). So, a more accurate definition to retirement that applies in my case would probably be something like: The permanent non-acceptance of employment contracts in exchange for compensation that is collected simply to pay for goods/services considered necessary to maintain my desired standard of living. Since that's already covered, there's a definite revaluing of the utility of any offered compensation. More accurately put, money still has value, but its value has become independent of my baseline of physical comfort, thereby decreasing its marginal utility to the point where time and the ability to direct my own efforts start to outweigh it. Acting on that revaluation is then considered "retirement".

To calculate "net worth", I take a rather conservative "mark to market" approach. This means that a financial asset, like a 401k, is only valued at the amount of which I'd actually get were I to liquidate it today instead of its face value. I also exclude most physical assets like a car and other possessions. The reason for this is that I try to only own items that I actually use such that if I sold one of them, I'd just have to replace it anyway. This goes against conventional wisdom that encourages you to include things like your home as part of your net worth. I think part of it could plausibly be included, but that would just be the difference between your home and what you actually intend to downgrade to sometime in the near future. Without that intent, it's really not wealth you have available to influence any calculations affecting your life and might as well not exist for those purposes.

Measuring Success

I created a completely arbitrary ranking of net worth levels to track my progress. These and my own timeline through them are as follows:

  • Level -1 (Negative net worth): It's impossible to retire at this level unless one decides to ditch life and go live under a bridge or at a homeless shelter, both situations that will likely eventually result in insanity, premature death, and/or waking up to someone urinating on your face. I squandered quite a bit of my adult life languishing here in ignorance.
  • Level 0 ($0 net worth): Same as above, but without bill collectors harassing you. Reached this on January 2008.
  • Level 1 (The six months expenses level): Once here, a job loss isn't as catastrophic, since there's a reasonable amount of time available to find a new one before ending up in the gutter. Of course, even at level -1, having this amount set aside is still a good idea, but I'm only counting the debt-free version of it here. For me, this meant having about $12k in 2008 dollars. Reached this on March 2008.
  • Level 2 (The disaster/life-reinvention buffer level): This is a psychologically comforting point to reach. Once here, I was pretty secure in life, as I had enough years of non-work funded that I could have completely reinvent my career if needed and was generally immune to most of the common financial disasters. It also opens up several options like taking years off just for the fsck of it. For me, this translated into having a decade of non-work funded at city life expense levels. Reached this on October 2010.
  • Level 3 (Theoretical financial independence): At this level, it becomes mathematically feasible to never work again, but requires very minimal living, paired with an extremely careful investment strategy to preserve wealth. It also requires a lot of luck for nothing to go wrong. This was a point where (number of years of life left) * (annual cost of living) = (net worth). Effectively, this is meaningless, but it's a nice milestone. Reached this on November 2011.
  • Level 4 (Real financial independence): This is the same as above but with a +40% buffer, which by my more detailed risk analysis and projections, was what I am comfortable detaching myself from the world of jobs with. This was also my original goal, since it fit in nicely with the number of remaining years of employment I felt I could stomach. However, this latter projection was based upon me presuming that I had reached the pay ceiling for software developers that weren't also entrepreneurs (and was actually rather lucky for already being an outlier above it). I later figured out a way to further optimize my employment time, allowing me to raise the buffer bar further and also cut the projected end date. At this point, I could safely stop caring whether I was employed or not. Reached this on February 2012.
  • Level 5 (Super-secure financial independence): This supports my current lifestyle for the rest of my life and provides a healthy +100% buffer from level 3. I am allocating a small portion of that buffer to slightly improve the quality of life too. If I stuck around for it, I would hit this by this time next year, but the current plan isn't to wait for it.

I track net worth on a monthly basis using a simple org-mode TBLFM and a Gnuplot script. I also created some supporting org-mode files for optimizing budgets and projecting new ones. This is really all you need, since the math behind it is simple and you only need a single way to visualize progress. You could do the same thing in a spreadsheet or on various personal finance sites too.

Applied theory

So, how do you go from the typical debt-ridden bottom-feeder you are now to financial independence? I can only tell you what I did. Apart from the fraction of it made on the market, I'll say that I actually did it the hard way. Freeing yourself from employment is definitely the least easy to do as an employee, as on average you have the largest number of factors working against you. I always tried to extract some wisdom when in the presence of someone independently wealthy, and they've all either done it as business owners or by exploiting cronyism in the government sector (which is still hard work). I've never personally met anyone who has been able to walk away in under 10 years, just by doing a day job, though I'm sure they exist.

Employment has several rather insidious aspects that lock you into dependence. Getting around those makes me think a prerequisite to doing it the employee way is to bootstrap some concepts that probably seem counter-intuitive or at least outside the norm to focus on. These include things like having a visceral understanding of what it means to spend a dollar, avoiding debt like the plague, and never over-extending yourself by counting your paychecks before they're deposited. Some things you can't do much about, like paying higher taxes, having vast swaths of time lost, being surrounded by employment lifers, and not exercising independent thought.

Most humans, despite possibly enjoying some aspects of their job, do so primarily to acquire the purchasing power they otherwise wouldn't have. That power is exercised and expended in acquisition of goods and services. Part of this expenditure is for physical survival and the remainder is optional upgrades, with a fuzzy boundary between the two. Most would agree that not much effort is needed to survive, so almost everyone with a job is laboring their entire lives for those upgrades.

However, there's a way out, and you're looking at it right now. Thanks almost entirely to computers, the majority of pleasures that are not life-essential are now nearly free. For the price of an internet connection, $500 in computer hardware, and a small amount of electricity to use it, a man has access to the majority of the accumulated knowledge of the species. Boredom isn't possible in the presence of several hundred exabytes of information, assuming you can't be bored by learning. Even better, there's an infinite number of things you could create or at least design on a computer.

Thus, both input and output are effectively limitless and near-free. The biggest benefit of this is vastly reducing the amount of capital accumulation needed compared to any other point in history.

Counter-arguments I've heard to my view of liberation via computers and the lessened need for extended work are many, and here's a list of some common ones (often even given by fellow programmers) with my common replies:

  • "But I want to travel and explore the world!"

    Unfortunately for you, the world has already been thoroughly explored (unless you're talking about space, parts of the ocean floor, or underground). Fortunately for you, instead of spending all that time and energy physically traveling to the famous, ancient rock pile and pointing your eyeballs at it for a short period of time, you can look at pictures of it as long as you want thanks to the internet. Chances are the pictures will even be of far higher quality than your single perspective from some designated viewing area, and you don't even have to get your testicles manhandled at the airport to do it. Physical travel is an inefficient method of accumulating experience anyway, as there is far more photographed than you can ever view in person. Besides, I've already been to many places on the surface of this planet, and the main feature of any of those places is they're all infested with filthy humans and places to spend money. So if you want to experience the primary trait of any tourist attraction, just go to your local mall.

  • "You'll be bored."

    I translate this to "I'd be bored". I already spend the a sizable part of time at work mildly bored (especially in meetings), but my personal empirical evidence proves that the same isn't true when I'm not working or on vacation. I do observe most old retirees having lives filled with activities optimized to make time pass as painlessly as possible until death, but I largely attribute this to their degenerate neural nets being hardwired by a lifetime squandered in servitude. This is another good reason to bail early before damage is incurred to the point where your only option is outsourcing entertainment then consuming it.

  • "You won't be part of anything big."

    This is probably more common here in New Babylon, but I've seen a lot of identity reinforcement via employer or title in the private sector too. I guess if I had to be a janitor, I'd very slightly rather plunger President Cheney's gold-plated toilet than one at a truck stop in El Paso. But, I'd rather own my own sanitation service than either of those.

Like traveling, there's also other consumption-enabling arguments, such as owning stuff or breeding more humans. If any of these things are that important to you, you can still do them, you'll just have to sacrifice some of your time that would otherwise be free from work in order to finance it. There is a limit to the market power the vast majority will ever control as an employee though. As long as your sights are low enough, you can probably exchange enough years to accomplish some of them. I've made a few comparatively minor exchanges along these lines too, otherwise I'd have already written this post long ago.

Anyway, I'm still working on my exit strategy and identifying risks. One big unknown is how much damage there's been from being an obedient vassal for so long. It's totally feasible that I'll suck at complete independence and require years of remedial work. I also have a back-up plan of leaving the door open to return to employment for another short period if things aren't going so well, but that's really a last resort. My operating hypothesis is the various skills needed to function solo are just like any other skill that can be mastered -- it just requires enough neuroplasticity and deliberation. I have plenty of ideas of what to do with the increased freedom (including startups, various programming projects, and many other things I'll probably write about later). But, immediately following early retirement, the first order of business is de-workifying the brain.


July 21, 2011 - Durch Nacht und Blut zur Licht

After a while, you realize that killing people is just part of the job.
- Coworker

Heading to Afghanistan for a year starting next month.


March 11, 2011 - Dien Blut Ist Wasser

Miner II deactivates as it finds its asteroid a ravaged husk of the glorious boulder it once was.
- Eve Online

Every couple of months I see some article about how even Joe Nobody can retire a millionaire. It's usually something about how saving a few hundred dollars a month will result in you retiring rich, all thanks to the "magic" of compound interest. There's usually a nice, simple chart or table provided to prove it too. The problem is that this is a lie. This becomes obvious quite fast as soon as you actually try it or even just think about it some.

First, these usually show returns of 8-10%. Some lucky or well-informed people get returns like these, but for every one of those, another guy loses his shirt. The real average rate of return is slightly higher than the guaranteed return of US Treasuries, which historically is around 3.85% (depending on where you start counting from). I'll use 5% in the calculations here.

A typical compound interest example scenario might involve you setting aside 10% of a median income (currently about $45k/yr) for about 50 years. After paying all your taxes and other fees, you'll probably find yourself with about $30k left over, so let's say you set aside $3k/yr, saving a total of $150k. Here's some Gauche Scheme code I wrote that will do the calculation for us.1

;; Figure out how much money you will have given:
;; years: number of years
;; intr: interest rate in decimal
;; n: initial savings
;; m: savings per year
(define (compound years intr n m)
  ; Just the interest from a given amount for one year.
  (define (interest rate amt)
    (* rate amt))
  ; Total of the starting amt, the money from interest, and the money saved
  ; that year.
  (define (year-total initial-amt rate saved-year-amt)
    (+ initial-amt (interest rate initial-amt) saved-year-amt))
  ; Recurse through the number of years.
  (cond ((= years 0) n)
        (else (year-total (compound (- years 1) intr n m) intr m))))

Running it gives us:

gosh> (compound 50 .05 3000 3000)
662446.1865024817

662 thousand dollars! But before you decide which yacht club to join, we're forgetting that there might be some inflation in 50 years. Let's normalize everything in today dollars. Supposedly, inflation is about 4%/yr on average (again, depending on where you start counting from and which measure of it you believe -- we'll use this since it's the most commonly quoted).2

;; i: average inflation rate
(define (compound-inflate years intr n m i)
  ; Calculate year modifier.  Used for interest or inflation.
  (define (year-modifier rate amt)
    (* rate amt))
  ; Total of the starting amt, the money from interest, and the money saved
  ; that year, less inflation.
  (define (year-total initial-amt rate saved-year-amt inflation-rate)
    (+ initial-amt
       (year-modifier rate initial-amt)
       saved-year-amt
       (- 0 (year-modifier inflation-rate initial-amt))))
  ; Recurse through the number of years.
  (cond ((= years 0) n)
        (else (year-total (compound-inflate (- years 1) intr n m i)
                          intr m i))))

gosh> (compound-inflate 50 .05 3000 3000 .04)
198323.44201869617

Ouch. Now all that work has only made you less than an extra $50k in 2011 dollars. Of course, you'll still actually have a lot more nominal dollars, but they'll only buy the same amount of actual stuff that $200k today would.

Then again, $50k of free money isn't so bad. That's 50,000 frozen bean burritos! However, we're forgetting that your free money is actually income, and of course The Greedy Hand will want its share rendered unto it. Let's assume the best case scenario here, where all of it is long term capital gains. Since you make the median income, that puts us in the 25% income tax bracket which means we'll have to allow 15% of your interest be democratically redistributed -- for the common good, you understand.

;; t: capital gains tax rate
(define (compound-inflate-tax years intr n m i t)
  ; Calculate year modifier.  Used for interest, inflation, or tax.
  (define (year-modifier rate amt)
    (* rate amt))
  ; Total of the starting amt, the money from interest, and the money saved
  ; that year, less inflation and taxes.
  (define (year-total initial-amt rate saved-year-amt inflation tax)
    (+ initial-amt
       (year-modifier rate initial-amt)
       saved-year-amt
       (- 0 (year-modifier inflation initial-amt))
       (- 0 (year-modifier tax (year-modifier rate initial-amt)))))
  ; Recurse through the number of years.
  (cond ((= years 0) n)
        (else (+ (year-total (compound-inflate-tax (- years 1)
                                                   intr n m i t)
                             intr m i t)))))

gosh> (compound-inflate-tax 50 .05 3000 3000 .04 .15)
162964.96345515392

Oh, now your $50k turned into $13k. Your effective interest rate was about 0.25%. Well, it's still money you wouldn't have had anyway, and it only cost you your entire life.

Since you're starting now (and missed out on the social security and pension parties), it even working out this good depends on the US economy getting back on track at least enough for you to get and keep a middle class job, not having any emergencies that will require looting your savings, taxes and inflation not going up (the capital gains tax here is already slated to go to 20% in 2013), not having to pay brokerage or fund management fees on any investing, and countless other implausibly optimistic outcomes.

So, fellow domesticated animals, saving is obviously for suckers. You should still do it though, because this rigged game is one you can't opt out of (minus suicide). It's better than being the one paying the interest to someone else, because that's what the real average is. If life worked out as "good" for you as this, you'd be an exceptional success story. Just expect your reward to be heaving away your life's blood for every last dollar and looking forward to a retirement of low income housing and dinners of dried cat food.3

1 Grab the code here if you want to plug in your own numbers.
2 Historically, even by the CPI-U, this is a highly rosy average. For example, according to the BLS the US dollar inflated 639.5% from 1960 - 2010. Source: inflationdata.com.
3 Later (maybe next time) I'll post a summary of my plan for getting around this problem.


December 28, 2010 - Porta-Toilet

You are in a sunny glade in the forest. There is a unicorn with a key around its neck. There is a golden gate to the north. There are exits to the north and east.
- Zork II

The Porta-Toilet is an idea that occurred to me today that could save a good bit of money on sewage and water bills. To build it, construct a box frame of sitting height out of pipes. On top, affix a wooden or plastic board. Then cut out a toilet seat-shaped ovular hole in it. If wood, treat it with a sealant to prevent water damage. Add a back rest for extra comfort if enough spare parts are handy. Ensure the bottom is at least about 2.5' wide (the base can taper out if necessary).

Front view:

        -   o=======o <-- board with poop hole
        |   /       \
     2' |  /         \ <-- 2" metal pipe (4 legs)
        | /           \
        - o-----------o  <-- pipe connectors or weld spots
         |-------------|
               2.5'
      

The side view looks the same, except there's no tapering out of the legs in that direction.

To use, get a shovel and dig a trench about 2' wide, at least 2' deep, and as long as desired. A single trench consolidates the digging required and is far easier than digging a lot of individual holes. Put the toilet over the trench at one of the ends, drop your pantaloons, and start excreting feces. Leave the removed dirt piled nearby along with the shovel so some can be tossed over piles of fresh plop (to keep flies off it and reduce the smell). Hose the toilet down occasionally to remove any splattered excrement.

After that part of the trench gets filled to 1' of the edge, bury that part completely and move the toilet further down the trench. Keep notes on where the trenches were dug so that no new trenches will be dug there for several years (maybe put a painted rock at each end). Bushes or other low plants could also be planted there to provide cover for using the next trench. Obviously this will need to be used in an area with enough vegetation to provide some privacy. If that's not possible, a portable shower enclosure can be bought for about $30 that would serve this purpose or one can be easily constructed using pipes in the same manner as the toilet. If you construct one yourself, build it just below eye level so you can keep a lookout for lurking coprophiliacs while defecating.

While there's no reason this can't be used in the rain, it would be unpleasant to use in the winter. Rural Americans as late as the 1950s would use outhouses all year long, but most of us have gotten used to having our testicles protected from the elements. The average toilet costs 13 cents/flush with 5 flushes/day for one individual. So, even if you use this for 9 months out of the year (never flushing the indoor toilet that entire time), you could easily save $7200 in today dollars over the next 40 years.

If you are feeding yourself with a garden, you can recycle those molecules back into the system by digging your feces up years later and using it as fertilizer. Human feces used for this purpose is called "night soil". Directly parking bricks onto your garden isn't advisable, as the concentration of heavy metals is too high. With urine, it needs to be watered down (directly peeing on plants will harm them). After years underground though, it will be ready for plant consumption if spread thinly about. Furthermore, now that you've dug up all that free fertilizer, you'll notice you have another empty trench, ready for another load of ripe ass-paste.


December 9, 2010 - Cassandra's Fate

Ein großes Feuer wird vom Himmel fallen mit einem Gestank von Schwefel. Schrecklich wird die Erde brennen und große Furcht wird die Menschen packen.
- Estampie

Society almost surely isn't going to collapse in our lifetimes. Even the sanest amongst us, however, realizes that there's still a non-zero chance that it or something effectively similar could happen. Even if the chance of it occurring is 1%, that's still greater than the chances of various things that you probably already pay thousands of dollars in insurance for, like house fires. There's also constant examples of localized collapses of society, or you may one day want to buy a house in Detroit. So, it just makes mathematical sense to prepare for this too. Thinking about this for a couple hours at some point in your life and factoring it into the items you already have to own is the only way, as you can't buy societal collapse insurance. The intarj3wbs is full of advice along these lines (mostly written by idiots and k00ks), but this is an absolute minimalist approach to the topic. Note that I haven't actually read much survivalist advice, so I'm arriving at these conclusions mostly in a vacuum. To reduce scope, I'll assume we're preparing for a typical survival-type scenario in the US, that the Earth's atmosphere and environment remain in their present condition, and that it doesn't involve gray goo, robots, asteroids, the undead, aliens, or the return of The Old Ones.

Your primary goal in this situation is to satisfy the base level of the Mazlow hierarchy. Next, you'll want to defend your property and the delicious meat cells attached to your skeleton. After that, you'll want to harden your normal amenities setup to be functional regardless of disruptions. None of this is at all difficult, as you'll see here, and you can pretty much live almost as nice and fulfilling of a life as a software engineer as you do now (perhaps moreso, once the planet depopulates some).

In each category here, I'll sum up the stuff you need. These are things on top of what everyone already has to stay alive in normal times.

Food and Water

This is what most survivalism focuses on, and rightly so, as you won't last long without some of either of these. However, they get the execution completely wrong.

Water isn't too much of a problem as you can easily construct a rain collector (or just find a roof with a rain gutter) and store water in any of the zillions of plastic containers covering the planet. This means you don't need consumable items like filters and purification tablets. Water isn't a problem and no pre-collapse preparations are necessary.

Food, on the other hand, isn't as simple. If society collapses, there will be no wild animals to hunt, as they will all be killed off within a month. There will, however, be plenty of famished humans. It is mathematically impossible for all of these humans to continue living if industrialized agriculture and distribution networks cease functioning. The weak will, of course, die first, so the first thing you need to do when it's obvious that a collapse is permanent is to identify a defenseless, resource-rich target and relieve them of their possessions. The sooner you do that, the better.

You can only store so much food in your basement, but if you combine the food from your neighbors' basements, you can survive a very long time indeed. How much you need is exactly the amount necessary to support you until The Cleansing is finished. After natural selection has run its course, you'll be able to plant a garden and feed yourself indefinitely. But, you have to live long enough first. Don't feel bad about prematurely terminating your neighbor's main thread; an obese, football-watching lawnmower-collector like him wasn't going to last long anyway. Since you should be eating canned foods mainly already (since they're so cheap) the only preparation you'll need here is to kill off any remaining empathy memes and get ready to see a murderer in the mirror for the rest of your life.

Stuff needed:

  • 10-20 packs of non-hybrid seeds of various vegetables ($30).
  • Shovel for gardening (also good for digging poop holes and burying corpses) ($15).

Shelter

Finding shelter isn't a problem, and you can safely skip all the useless knowledge about building them out of branches and leaves. There are already too many buildings for everyone now, and with humans murdering each other like savage beasts and the tracts of vacant commercial real estate, you'll have your pick of a new home if your current one is inadequate.

Of course, a box to live in isn't quite enough. You'll need a way to heat the enclosed atmosphere during the winter, and if you don't have a something like it already, you can easily build a wood stove out of a 55-gallon drum and a few pipes. Then you can just burn random trash you find lying about.

Stuff needed:

  • Hand axe for chopping furniture and other stuff to burn ($20).

Weapons

Expect roving gangs of thieves and murderers to plague the land for years after any total collapse. We have enough historical evidence to show that first will come the criminally insane, their primitive urges now unrestrained. During this period, it's best to just enter fortification mode and only engage in defensive combat. Once most of this dies down, the primary threat will be those desperate individuals who didn't read this post. They'll just want your food, and will prefer to steal it without conflict if possible. This is why there's no point in trying to grow your own food until this population has decreased sufficiently. A garden full of juicy carrots will just be a magnet for them and require extensive armed security, to the point that it'd be a net loss.

With the primary threat being humans, you'll need firearms. There are dozens of uses for firearms post-collapse, and unless you're into collecting them, you'll want the minimal number of guns that accomplish as many critical uses as possible.

A lot of this is just personal preference, and any gun is better than no gun. If you already have one, use that, but if not, you might want to consider these points:

  • Readily available calibers: A gun without ammo is just an expensive club, so you might want them chambered in rounds that are cheap and plentiful. Using the same rounds as the US military might also make sense.
  • Offensive use: You won't last long if you only attack other humans at close range, so you'll want something that can drop an adult man at least a 150 yards out. At this distance, you can snipe a guy carrying a grocery bag with almost no danger to yourself.
  • Defensive use: Some humans aren't completely stupid, and may lure you into a compromising situation where you'll need to engage in CQC. You don't want to unsling a scoped, bolt-action rifle in such a scenario.
  • Utility use: Years later, there may eventually be enough animals around to hunt for food, and you may want something that can dispatch rabbits, squirrels, turtles, and other small game.
  • Mechanical simplicity: Firearms with buttons all over the place, complicated gas pistons, and a lot of finely-tuned springs will surely fail after many years, and you probably won't have parts lying around to fix them.

If I could only have one gun, I would choose the TC Contender G2 single shot pistol, by far the ultimate in firearm versatility. The best feature is its ability to interchange barrels in an extremely wide variety of calibers. Personally, I would at least get a .22LR barrel for utility use and a scoped .223 Remington barrel for long range offensive use. I would maybe add a .410 barrel for CQC and birds (unfortunately, you can't get a larger gauge). Obviously, it's less than ideal for all these purposes, but it gets a lot of jobs done well enough. Being a handgun, you can carry it on your person (and you'll want to be armed 24/7, but that's true now too).

If you had money to waste, you could certainly make a case for other firearms, like a battle rifle for medium ranged combat (great for maintaining a decent kill-zone radius around your property), a double or single-action revolver (for a more mechanically simple CQC handgun), a combat shotgun, or a scoped rifle. If you possess social skills, consider making a "do not murder" list of people that you trust who are equally prepared as you. You then mutually agree to form a party in such an event and assign appropriate combat roles. For example, the heavier guy with the most HP can wield a close range weapon, while your frail self can be the team's designated marksman.

You'll also want some kind of edged weapon, but don't fall for all the marketing gimmicks most knife companies try to sell you on. You already have some kitchen knives, so those are probably good enough for cutting anything. The only thing you'd want to add is some kind of folding knife, since you can't really carry a kitchen knife in your pocket. Really though, I don't consider a knife much of a weapon, except for dispatching grannies and the handicapped. Getting into knife fights is a good way to reduce your life expectancy significantly. Once you drop someone at long range, then maybe you can pull out your knife and get to work on the corpse.

Stuff needed:

  • TC Contender G2 frame ($350), 12" .22LR barrel ($250), 14" .223 Remington barrel ($250), scope ($100). A used Contender can be had for half this price.
  • 1000 rounds .22LR ($40), 150 rounds .223 Remington ($30).
  • Folding knife ($20).

Electronic Devices

There's little point in just perpetuating a pointless existence, so you'll need to make sure you can continue to experience the most essential technology, and even continue the progress of it, particularly software engineering and computer science. To do this, you'll obviously need the ability to run a computer in absence of an electric grid, at least long enough to type in and run programs.

This is actually quite easy, provided you use a low power computing platform like a netbook or an mITX system with an Atom, CULV, or similar CPU. Try to buy/build systems that are fanless and with SSDs. Like computers from the 80s with no moving parts that are still around today, they'll last your entire life if you don't abuse them. Make sure you have the kernel and userland source for your operating system and applications, since you won't have access to the FreeBSD FTP sites.

A cheap netbook can run on under 10W of power during normal use, and this means you can easily power one with a single, small solar panel, still having plenty of power left over for light, a packet radio modem, or other uses. You'll want some batteries to store power, and you can just help yourself to a lifetime supply of those from abandoned vehicles.

As far as other gadgets are concerned, you do need a flashlight, some rechargeable batteries, and wire cutters (multi-tools usually have this built in). Most likely you already have these. You will also want some basic electrical skills, so go read a tutorial on it or just buy a book and lazy load it when the time comes (you'll have plenty of free time).

Stuff needed:

  • ~50W solar panel ($100)

Other Stuff

You should make sure you have lighters, medical supplies, ropes, tarps, and tape in your house. Most people already do, and you'll be able to liberate plenty more from the hapless clods you slay.

And that's it. You don't need tents, maps, compasses, gas masks, signal flares/mirrors, machetes, windmills, sleeping bags, or any of the other stuff filling endless store shelves. While most of this stuff isn't completely useless, their utility is less than the cost of ownership, particularly given the extremely low chance of needing them. The people telling you to spend thousands of dollars on a mountain of crap typically are the same ones trying to sell them or the consumers that have themselves fallen for the marketing.

Bring the Pain

Assuming you get your firearm used, you can acquire all the recommended items here for less than $1000, and these are all things that are useful in normal life anyway. You might as well setup the solar panel now too, as after a few years, its cost will be recovered and thereafter generate free power.

By now, you're thinking that it's a shame that a societal collapse is so unlikely. Losing a few conveniences like toilet paper and running water would be a small price for having all the hours of your day and your life's fate in your own hands, assuming you were competent or fortunate enough not to fall victim to the initial slaughter. Considering the miserable lives of indentured servitude that most Americans have to look forward to, I would take my chances too.


May 22, 2010 - Ultima Ratio Regum

"When pygmies cast such long shadows, it must be very late in the day."
- Gian-Carlo Rota

Interviewing programmers sucks. I think I hate it more than the candidates being grilled do. Of course, my reason is different; I hate it because it brings me face to face with so many morons.

At the new workplace, the pool of applicants tends to be a little better than my previous sampling, however. I have actually met a few that were quite impressive. This, combined with higher standards, has allowed me to increase the average difficulty level of questions. Since coming up with really good questions isn't easy, I've been collecting them over the years and recently compiled them in an single document for my coworkers (and now you) to read.

See the list here. I added some JavaScript to hide the answers so you can quiz yourself and check them later to see how you did. If these all seem super easy to you, send me an email (security-clearable US citizens only, pl0x). There's still a few openings on an interesting research project, plus I get a nice pile of cash for recommending people.


May 18, 2010 - Das Schloß am Meer

"Just because we Lisp programmers are better than everyone else is no excuse for us to be arrogant"
- Ron Garrett

Two years ago, I wrote a survey of which programming languages I was interested in. Here's an update to that.

Main Programming Language Focus

  • Haskell: Haskell pWnz0rz j00r m0mz0rz. Apart from occasional use, I've been taking a break from all things purely functional and category/type theoretic in favor of the Lisp world, at least for now. It is my end goal to be writing Haskell almost exclusively, however, at which point I intend to supplement it with Agda (both the theorem prover and dependently-typed functional language).
  • Common Lisp: I currently spend most of my recreational programming time writing CL in SBCL. The reason is that those lambdas are far more relevant to the computer science and algorithms that I actually use on a daily basis. I view Lisp as a base language from which the other mainstream languages contain only a subset of features from (with only a few exceptions, like parts of Haskell). Thus, Lisp is the ultimate practice language for real world algorithms, as well as just being fun to write in.
  • Scheme: n00bs always ask me what the best beginner's programming language is, and I always say Scheme, due to it having a syntax tree you can memorize the entirety of in a couple days and the fact that algorithms in it aren't encumbered by mountains of syntactic frills. Then they go off and buy a C++ book and years later still can't program. I'm only using Scheme (with the Gauche interpreter) for SICP and EOPL. I got distracted by other things and suspended work on SICP. It's back near the top of my list now, but I know that a lot of people finish it using CL, so I might start over with that.
  • Scala: Now that my job is back in the JVM technology stack, I'm ditching F# and replacing it with Scala. Both have an ML-derivative syntax and that same awkward boundary-straddling between the OO and functional paradigms. While I do think F# is a slightly better designed language overall, being .Net-only makes it useless for me. Many of the guys at my current job are also Scala fans, so having to find isolated corners away from drooling OOPtards isn't as much of an issue.
  • Clojure: Another Lisp-variant and JVM language. While this is a possible nexus between work and languages I'm partial to, I'll at most only use this in isolated areas that I'm working on alone. Another problem lately has been the stability of the environment. Getting SLIME working with swank-clojure was a massive pain and still has a few annoying REPL bugs for me. Judging from blog posts by other Lisp programmers out there, I'm not the only one. This says nothing of the language itself though, which is great -- like, I appreciate a lot of the changes that address some of CL's historical baggage.
  • OCaml: Using OCaml only for working through Benjamin Pierce's type theory books, TAPL and ATITAPL.
  • Prolog: I still plan on at least using this to work through The Art of Prolog, but it's a rather low priority task, so I haven't gotten around to it yet.
Maintenance Efforts Only
  • Java: I had to resurrect my Java knowledge due to work. Java has obviously fallen behind C# lately in language features. In practice, this gap is addressed by new capabilities provided by fugly 3rd party frameworks. "Knowing" Java isn't enough to be an enterprise Java developer. You'll need to wallow in a puke fountain of frameworks like Hibernate, Struts, JPA, EJB, Tapestry, JSF, JMS/EMS, Sproing, GayBoss, and Assfish. The non-extensibility of the Java language means writing code to use these is a nightmare of annotations and XML tag-soup. Declaring everything in 5 places and deciphering stack traces 5 frameworks deep to figure out which string literal you mistyped will make you hate life itself. There's a few ways around some of this, but I'm no Java expert, nor do I intend to ever be, so I'll let others speak authoritatively on that.
  • C: C interview questions are rather rare these days, removing my previous excuse for maintaining it. Still though, a lot of older CS texts are in C. Most importantly, my OS and a lot of system software is written in it, and it's often necessary to modify that (especially given how often critical ports break on FreeBSD lately). Plus, I actually sort of like writing in C, but only in very small doses.
  • JavaScript: I subscribe to the Douglas Crockford philosophy of JavaScript, where you isolate a subset of functional-esque features from an otherwise craptastic language. Combine this with fixing the development tools problem of JavaScript with flymake, JSLint, Rhino, and MozRepl, and you've got a fairly clean, small language that you can actually write some interesting code in.
  • SQL: One of the ways I keep from falling asleep when writing SQL is to think about its set theoretic foundation. You can even first write your queries in relational algebraic notation, then translate and add the semantic fluff for sorting and grouping.
  • Emacs Lisp: With my exit from the MS development world, I'm now able to write 100% of my code at work in Emacs. Though there's been some recent work towards more automated configuration (like ELPA), keeping Emacs highly customized and running optimally still requires plenty of e-lisp coding. There's no point in mastering it though; if you're doing anything serious, just (require 'cl).
  • LaTeX: Maybe I should leave this one off like other semi-languages, but LaTeX macros make typesetting programming almost fun. If I never have to write another MS Word document again in my life, I can die a happy Donald Knuth fanboi.
Language Memory to Return to the Heap
  • C#, F#, T-SQL, and all things .Net: Not having a Windows development job makes these useless. If I want to torture myself in framework hell and technology that churns faster than any human can keep up with (but to little real result), there's no shortage of options in Java-land.
  • Python: I'm not entirely sure I want to forget Python yet. It's mainly here because I've ignored it almost completely for the last 2 years and with all this other stuff, spare language bandwidth is pretty minimal. I can see the use of having a dynamically-typed, multi-paradigm interpreted language though. Another option here is to replace it with the annoyingly-named Groovy, a Ruby-inspired JVM language, since it's occasionally used at my current job. Apart from that one immediate benefit, Python is still a more practical choice in the long run and all my other commentary on it last time still holds.
  • C++: While I am a fan of the generic programming that templates provide and a few other features of C++, the main reason I'm giving up on it is simply the amount of brain space taken up by memorizing the zillions of memory-management gotchas that compilers don't provide warnings for, the time wasted debugging errors that aren't even possible in other modern languages, and the general feature bloat of the language itself. As Ken Thomspon said in Coders At Work, C++ is "just a garbage heap of ideas that are mutually exclusive." If I was getting paid to maintain these things, I would. I've already been wasting several weeks every year trying to perpetuate a mediocre skill level (by enterprise-grade standards, that is), and this amount will never be enough to compete with those guys with decades of C++ knowledge arcana, so I'm sure I can think of better things to do with that time.


March 26, 2010 - Nacht fiel über Gotenhafen

As I had planned for several months now, I resigned my current job two weeks ago. I'd originally planned on just taking at least the rest of the year off, but I did interview at a couple places anyway and ended up accepting an offer that's an improvement in pretty much every area. As a result of this transition, I've spent a good deal of time since January contemplating how to optimally position myself in the economy and tech sector, both short- and long-term. Here's some of my observations so far.

Since this includes a lot of criticism, before doing so, I'll first mention that my (still current) job is a pretty good one. It's definitely exactly the kind of thing I was aiming for back in college, and there are potential circumstances in the future where I may want something similar again. I fully realize that compared to most people inhabiting this vale of tears and Earthly sorrow, I live a life of mostly-fulfilled dreams and decadent luxury.

Ex Labore Nihil

I've now been working for almost 8 of your Earth years. While it's true that most humans work some 50 years, I have no intention of dedicating the majority of my life to giving other humans the chance to get rich. This isn't to say I have anything against anyone getting rich. In fact, I'd rather there be fewer obstacles to mobilizing new ideas. But unless I'm getting a real cut,1 I'd rather participate in someone else's dream as minimally as possible.

As most Americans are learning these days, even regular, honest work doesn't really pay. I've run the numbers for my own situation, and they're pretty demotivating. For example, my original plan of resigning four months into the year was almost entirely for tax reasons. Say you have a salary of $120k/year. Work a third of the year, and you'll get to keep about $35k. If you wanted to double the amount of real take-home pay this year, you'd have to work almost the entire rest of the year. In other words, you'd have to work 3 times as hard to make twice the money. This is at the middle class income level, but various similar disincentives apply at all levels. I'm not the only person to notice this. Many others realize that if they're going to be punished for working, they're not going to do it. One option I'm considering to counter this later in life is doing shorter term contracts, strategically straddling the cut-off between tax years to minimize income in any particular year.

My original plan was to front-load as much of my employee time as possible, working for some 10 years at most and then doing whatever I wanted the rest of my life. This makes sense until you factor in inflation. Consider the fact that 30 years ago, the equivalent of a $100k/yr job today would be $33k/yr then. If you had front-loaded your employment 30 years ago, you'd have been working 3 times as hard for every dollar you spend today, assuming you hadn't lost it via some group-think investment vehicle in one of the many recessions since then. As long as the printing presses are running full speed, just-in-time financing of your life makes the most economic sense. I do still plan to front-load most of my work though, but hedge against inflation with commodities, metals, and a few passive income investments in foreign markets.

Math.ceil(pay);

Anyone who knows anything about programming knows that a great programmer is worth many times more than an average one. One can easily imagine a room of 30 lackluster programmers being outdone by a single guru programmer. In fact, the room of 30 programmers has all kinds of downsides, such as constant bug-treadmilling and construction of monolithic monstrosities. But, the disparity between talent and lack thereof is even more severe than this in the world of software, as a truly talented and motivated engineer will invent things that our room of n00bs could never envision, even if given infinite time and resources.

Now, I don't consider myself a guru of this magnitude, but with the help of org-mode, I'm hopefully headed in that direction. I do consider myself at least above average by any objective measure in the shallow talent pool immediately surrounding me. Most skilled developers I've met intentionally downgrade their output by a percentage roughly equivalent to what they feel their compensation is reimbursing them for. I've done this too of course, and while it doesn't really bother me that much as a slower pace does prevent burnout and I fill any spare bandwidth with side projects, it's a shame that no employee-context exists where I can output at maximum aptitude and be reasonably sure to be compensated accordingly.

Let's say you were a typical talented developer roughly of could-work-at-Google quality. You're no savant, but you could at least match the output of the 5 junior-level developers you work with. If those other guys are paid $60k/yr, you might feel justified in walking into your manager's office and politely requesting a new salary around $300k/yr. As you walk out of his office a few minutes later wiping his wad of saliva off your face with your company logo tie, you'll realize that you've discovered the salary ceiling for software engineers.

While I could make a long list of the causes of this ceiling, part of it is simply because it takes an even more talented programmer to recognize and order programming talent. The rare manager that is capable of this and recognizes this problem won't be able to make a case bean counters can understand. This is why when interviewing for jobs, you should also interview them and look for signs that talent and creativity are recognized and rewarded. On the positive side, at least our ceiling is far higher than most other thought-intensive jobs in the sciences or academia. Challenging mental activity is also its own reward, and most of us that aren't blessed with disabilities have to work at some point in our lives, so better it be with our brains.

ro nanmu ka'e binra

As mentioned in an earlier post, I've now got a good mental measure of the job market competition (at least here in the DC Metro area). Not just among the unemployed, but even among those with jobs, the zeitgeist of underlying fear is palpable. I've seen behavioral changes in select employed persons that can only be explained if you assume a large debt burden and resulting fear of job loss -- enough to turn a grown man into a spineless yes-man. Given current economic woes, many of them are worried justifiably considering their lack of abilities beyond bare minimum. I hear the competition on the job market out there is pretty stiff, but can't vouch for that firsthand, as I only interviewed at two places, one being through a recommendation. However, I'm fairly confident that it's still true that anyone who's demonstrably amazing would still get scooped up pretty quick. For the rank-and-file left mouse button operators out there, I can imagine an involuntary job search now to be a potential economic death sentence.

Even if I felt I was a know-nothing paycheck sponge, I'd still not be overly concerned. I've always viewed the state of employment as a temporary condition anyway, and non-work as the norm. This is probably a healthy perspective for anyone, even when it's not true, since it prevents taking the number on your current paycheck for granted.

Incidentally, while most of this is negative, employment probably is a net negative for most of us. Manual labor destroys healthy bodies, sedentary office work morphs us into blobs, and all of it truncates our finite existence. Though I certainly owe a lot of my practical software development skills to work and could probably make a long list of other benefits, I don't see many smiling faces around any office I've worked at, nor in any of the oncoming traffic while commuting. So, even if it was overall positive, any objective critique of work would have to include criticism.

Imagining Sisyphus Happy

All this said, I'm quite looking forward to my new job. Better technologies, more math/compsci, a higher average INT level, almost no managerial overhead (a rare thing indeed in the defense sector), better office furnishings, and many other perks I won't bother listing. Today's my last day working on CODIS, and there's things I'll miss: DNA forensics, my laptop and workstation, and even some things in the MS dev stack (like the System.Linq namespace).

My current job was my first real foray into a large, corporate software development environment, which has its own unique set of pros and cons. I was part of an initially small team of developers who built some great software from nothing. As I now know is often the case in a particular class of government contracts, the client (the FBI in this case) will inevitably want to protect their investment, and the playbook government agencies use for that is a lumbering beast of counter-productive process management called CMMI. Suffocating as this can be on its own, in this situation, a phenomenon I first read in jwz's Netscape employment post-mortem simultaneously occurs without fail:

And there's another factor involved, which is that you can divide our industry into two kinds of people: those who want to go work for a company to make it successful, and those who want to go work for a successful company. Netscape's early success and rapid growth caused us to stop getting the former and start getting the latter.2

The environment changed such that myself as an asset was about to soon be under-utilized. But, there's no bitterness here. A mis-allocation evolved and was corrected. The Red Army goose-stepped into Gotenhafen, but I've joined the exodus, and thankfully not aboard the Wilhelm Gustloff.

1There are ways to cash in big as an employee, like with stock options at a startup. This isn't a sure thing of course, and most people not named Gabe Newell end up just as broke as normal employees but with more gray hair and possibly an equal amount of neck jello. However, opportunities in this area have largely dried up in the last decade, and now many startups I've heard of recently expect you to work 60 hour weeks for the same scraps you would make at a normal, non-disappearing job. As much as I like the idea of doing something entrepreneurial, this is a sucker's deal: All the extra risk and much more work for guaranteed no return. You'd be better off getting a normal SE job and converting a fraction of your paycheck into lottery tickets.
2Read here. Netscape is a valuable lesson every Real Programmer should learn. This is a fate that awaits almost every successful software project, and the signs are always there. Don't be the last guy operating the bilge pump on a sinking ship. Leaving early turns your role in such a project into a success story, instead of an inevitable, depressing tale of lost former glory.


January 25, 2010 - Tractatus Logico-Philosophicus

"Where of one cannot speak, one must pass over in silence."
- Ludwig Wittgenstein

Bertrand Russell (to whom we're all indebted for the Principia Mathematica) remarked that Ludwig Wittgenstein's Tractatus Logico-Philosophicus was a "work of genius" and modern philosophers often call it the most important philosophical work of the 20th century.

If given the benefit of the doubt, at best, Wittgenstein's intent was that by forcing a logical positivist reader to decipher his declarations therein, they might themselves realize his position on language - a kind of demonstratio ad absurdum. I'm not sure I believe this though, and Wittgenstein's own actions seem to prove this isn't the case. Since his life is a mismanaged mess of contradictory behavior, difficult to derive many contextual clues from, it's probably best just to take the text as a closed system. After all, what kind of masterpiece would it be if it required foreknowledge of an author's propensity for trolling?

While I agree that natural language is insufficient at describing anything in an exact manner, the solution to that is formal (and possibly certain constructed) languages, not more gibberish. Nonetheless, the Tractatus is historically important for a couple reasons, in particular Proposition 7 (quoted above) and the notion that use of language which does not communicate fact is nonsense. There's a few other valuable concepts within, but these are traceable to the Principia.

But those few worthwhile parts are adrift in an ocean of sewage; its foremost problem being that it's a collection of naked assertions and not a single argument. Many of these are easily demonstratively false by an increasingly disinterested amateur like myself casually reading it. Here's just one example:

3.032 It is as impossible to represent in language anything that 'contradicts logic' as it is in geometry to represent by its coordinates a figure that contradicts the laws of space, or to give the coordinates of a point that does not exist.

The Greek philosopher Epimenides, in 4th century BCE, demonstrates a contradiction to this in the form of the liar paradox, expressible in any natural language, of which a form would be "this statement is false." 3.032 is even an internal contradiction, since it admits that it's possible to describe a contradiction in the language of geometry, and what could the "laws of space" be if not based upon logic? Wittgenstein apparently agrees with me on this (see: 2.0121 and 2.013).

This level of sloppiness is endemic in the text (and if I took modern philosophy seriously, I'd give it a solid fisking), but that's just the beginning. Other problems are its writing style, awkward use of common words with unique meanings (e.g. "picture"), many internal contradictions (e.g. 2.141 vs. 2.203), and (possibly intentional) obscurantism. In short, I disagree with the majority of its contents (either by degree or in entirety) and consider its style a few steps short of k00kskr33d.

While I can forgive Russell and other contemporaries for being without my benefit of hindsight, I'm left only to conclude that the fact this work remains popular is probably more a result of academic pseudo-intellectualism than anything else. Language had by then been considered the final vestigial structure of philosophy, but computer science's progress in formal language theory has probably stripped it of most of these duties, except maybe semiotics and the parts of linguistics that natural language processing isn't interested in.


December 15, 2009 - Interviewing Programmers

So, I've interviewed many dozens of candidates for programming positions over the past few years, and now have new wisdom to share. These words would come as a surprise to the former me-who-hadn't-ever-interviewed-anyone. After all, proto-interviewer me had read all of the famous blog posts on how to interview programmers -- all while nodding knowingly and no doubt reciting, "Yep, smart and gets things done, that's the secret," followed shortly by listing a few epic questions that will surely separate the wheat from the drool.

Actually, the majority of these famous interviewing rants are quite good, but they didn't really tell me the reality of being on the other side of the table. That reality is: Most people that call themselves programmers can't program. Just that fact was a pretty frightening concept to wrap one's young, naïve head around. I've seen grown men, with supposedly 20+ years of experience as a corporate programmer (3 or 4 times more than myself, by the way), stare me in the face and tell me they're an expert C++, Java, C# (or whatever) programmer, then get stumped trying to write a function to do something painfully simple (like reverse a string). I still haven't come to terms with this, actually.

Furthermore, most of the ones that can program are just implementers. By that, I mean these sorta-programmers look at programming the same way a steam shovel operator looks at his trade. They're operators of heavy machinery, just the implementers' is typically some IDE like Visual Studio or Eclipse. Ask what the big red button actually does behind the scenes, and you'll find the pool is quite shallow. They only know how to push it.

Based on my experience, I've modelled the software developer candidate gene pool into these buckets. In reality, it's more an n-dimensional continuum, of course, but there's definitely some major trends which are hard not to notice.

  • The Empty Head: A phone screening process can weed out most of these, but one or two will always slip through. These people don't know anything and don't want to know anything. They usually sit passively, answer all questions minimally, if at all. Extracting anything like actual information out of them usually involves you giving the information to them first so they can just repeat it. Once you realize you have one of these, just get them out the door as soon as possible, unless you have a chair that needs warming.
  • The Crib Sheet: This taxon is the same as The Empty Head, but has been to enough interviews to notice that some of the same questions keep coming up. They'll then go online and Google "C# interview questions", and memorize the answers to these, confident they won't be embarrassed the next time someone asks them a stock question like "What's an abstract class?" You'll know you have one of these when they insta-answer these questions, yet shrug when asked something equally easy that doesn't show up on those lists. I always ask a few of these stock questions as control questions. Everyone gets them, and you'll then have a baseline to detect when they're actually being challenged. However, none of these answers should go towards actually giving a candidate the thumbs up.
  • The Bullet Point: These types can eventually get programming done sometimes, but there had better be a pre-packaged solution built into one of the libraries available, because there's not an original thought in their heads. Microsoft and Sun's developer ecologies really breed these non-thinkers for various reasons I won't go into here. I consider these types "software assemblers" instead of "software developers," since the only original code you'll get out of them is some glue between code written by people who actually are talented. Even if you work in a place where all you do is make boring business apps along these lines, do you really want someone sinking 100s of hours into tasks that you could solve in a few minutes?
  • The Day Jobber: Rarely, you'll encounter someone that seems to have the necessary skills, but isn't anything to get excited about. You'll sometimes find a complete understanding of the requisite SE baseline, but a vacuum any further below. This guy will do his job, keep his head down, and leave at exactly 5PM sharp every day. If you work in a drab cube farm for a corporation that considers its developers "resources," this is probably what you should aim for because you're not going to do much better. I honestly can't blame these guys, as they're just taking the path of least resistance. Most of them have been around long enough to know that if they stick their necks out and show some initiative, they'll at best get ignored and at worst get perma-branded as a malcontent.
  • The Thinker: This, in my opinion, is what any software developer should be, even the junior-level ones. Real software development is a thought-intensive process involving abstracting problems and creating systems that model them in a formal language. I have no advice on how to interview these types, since I've yet to encounter one in this capacity. The only thing I do try to do is create intelligent questions that leave open the room for someone to surprise me in this way or keep prodding them until I've exhausted their knowledge on a depth-first line of questioning. If I have to have a job, I want to work around fellow thinkers. Being the smartest guy in the room is boring, as the information transfer is always one-way.

I think there's a few causes specific to my situation that makes the sample of local fauna I've encountered so dismal. At least, I hope this is the case. Perhaps I'll have a different perspective if I continue this practice elsewhere, but for now, here's a few unordered observations that hopefully complement the established best practices. This isn't a "How to Conduct the Ultimate Interview" post like most rants on this subject are, though I reserve the right to write one of those later.

Liar-Detection

A disturbing percentage of job candidates have no qualms about lying right to your face. I've caught people lying about just about everything imaginable: colleges attended, work history, and most commonly, stuff they claim to know. The latter is the easiest to spot. For example, if you're interviewing for an MS developer position, expect people to come in claiming to be UNIX gurus. I'm sure they get away with this most of the time, but it's usually the case that I know enough about it to call them out. If I see suspicious stuff on their résumé that I don't know, I'll spend an hour researching it and come up with a couple super-simple questions about it.

Here's a few recent examples:

One guy claimed to be an Emacs expert. I replied, "It just so happens that I use Emacs every day, even here at this job. What do you prefer, XEmacs or GNU Emacs?" "Uhhh... I can't remember which one I use." "Maybe you could tell me a few common editing commands at least?" "Um... I used it a long time ago." "Oh, I thought you said you were an expert."

Another guy claimed to be a Lisp programmer, proudly boasting, "I use LISP [he then wrote down the word 'LISP' in all caps on his notebook and showed me] for AI programming." I let him talk about it for awhile, making several inaccurate statements, and eventually replied, "Well, it just so happens that I'm a Lisp programmer too. What Lisp implementation do you prefer?" I gazed into a classic deer-in-the-headlights stare and heard, "Um, it was some free one, I can't remember." "OK, but maybe you could at least tell me what a REPL is? You can't get far in Lisp without knowing that." "I only played around with it for a day or so." "Oh, I thought you said you were a Lisp AI programmer."

The reality is that something like this happens almost every other interview. It may seem a bit cruel to call people out like that, but you're not really doing your job if you don't, nor is it fair to the guys who actually do know these things. Some people put stuff like that just as résumé-padding, so before spanking them I'll always first ask if they consider this item one of their skills, and what level of expertise they possess in it. I'll never bring up topics completely irrelevant to the job, but if they start talking about it or claim to be an expert, then it's fair game.

Ignoring "Qualifications"

Another group that surprised me were people with Masters degrees in computer science. I guess this shouldn't be too shocking, since I was surrounded by n00bs who just copied all their work in gradschool, but people with MS degrees fare no better than those without. In fact, they've actually done worse in my sampling. I have my suspicions on why this is, but I won't go into them here. They even do poorly on the more computer science-related stuff, like runtime analysis, type systems, or recursion.

Trying to factor in where someone went to school is a slippery slope anyway. You have to consider the quality disparity between various foreign universities (and between domestic ones), how long ago it was, whether to ask for a GPA, etc. All this tells you nothing in the end compared to just giving them a pen and asking them to write a couple lines of code.

Other supposed qualifications to ignore are continuing education classes and certifications. Maybe you could make a case for certs in the IT technician field, but most developers know they are worthless. I guess some people may actually prefer to learn that way, but how do you tell those from the ones that just wanted the résumé padding? Plus, the shelf-life on those is pretty short. Ideally, a good developer will be an effective self-learner, as if he had to rely on someone else telling him what to study every time he needed to learn something, he'd be pretty much a tard no matter how many classes he took.

Basically, it's best to just ignore everything under the education section of a résumé. I would even go so far as to include ignoring whether they even have a degree at all, but in my case, the non-degree holders are pre-screened out.

Ignoring "Experience"

HR drones and recruiters like to quantify skills in a particular language or technology by way of listing the number of years someone has used it. Anyone with a clue knows this is retarded. In fact, ignore everything recruiters say. When one emails you with "You're gonna just LOVE this guy. He's amazing and won't be on the market long," just tell him to shut his dumb wang-holster. Maybe the guy is amazing, but I'm sure someone who doesn't know the difference between one acronym and the next can't tell.

Along these lines, you should probably ignore or at least severely discount the number of years in the industry developers have on their résumés. I admit being surprised the first time I encountered a "programmer" with 25 years of experience who couldn't write even the simplest code, but it happens so often that I quickly learned to assume nothing based on résumé length. That does leave an unsolved mystery about what the fsck these n00bs were doing all that time. Did they once know how to program but just forgot, did they spend all that time doing paperwork, or are they just lying about their job history? All I know is they can't program now.

Leaving Time for the Cuddle Party

Maybe I'm still an idealist, but I always give even the most floundering imbecile a chance at the end to talk about whatever they want to. A good way to prompt them on this is to just ask what technology-related stuff they're interested in. For all I know, maybe they suck at everything else but are a data mining genius, and I wouldn't otherwise know because I never asked about it.

Answering this question, most will say something stupid like "Um, my main interest is Biztalk." This, of course, is another lie, and a shame that they'll choose to do that when given an open floor. I've never really heard anything particularly interesting here. Some of the Day Jobbers might be into making websites or some light side-project like that. I know I'd want this kind of a chance, so I still think it's a good idea. If you went to an interview and all they did was ask a set list of questions with no side-talk, that'd probably be a good sign you're interviewing for the position of Manhours Bucket.

A former coworker of mine also suggested asking the candidate to explain something they know that you don't, his reasoning being, "if I have to spend over an hour with some guy, I want to get something out of it." Conceptually, it would also be a good chance to see how good they are at explaining ideas to an uninformed party. In practice, I've had problems finding something to ask, as most people just list the same boring stuff. When I do, the explanation is often riddled with inaccuracies (since I always go back and check what they say afterwards), so I've given up on that idea.


July 21, 2009 - Une Mur Dorée

"The move from a text-based interface to a graphical interface takes us back before the invention of the alphabet to the time of ideograms. The move to a speech-based interface takes us even before the invention of writing."
- David Madore

So Much Communication, So Little Said

Decades past, technologists dreamed fancifully of a world electronically connected via computer networks and the progress that was sure to engender. Surely, instant communication between all people everywhere would herald unimaginable intellectual revolutions in every human endeavour. Or, so we all thought. Overlooked was that everyone actually having anything of substance to communicate with interested parties was already doing so (though admittedly, sometimes at a slower pace). Mathematicians, scientists, engineers, and even businessmen didn't work in vacuums, isolated from the ideas of their peers. All of the technology was in place for near real-time remote collaboration, it was only the moderately-prohibitive expense of such technology that kept the throughput of it at low levels. Naturally, observers saw the great things being done with such technology and sought to expand its accessibility, yet we can now conclusively declare that lowering this barrier of entry as far as we have has only resulted the opposite effect.

We've long since passed the point where adding additional inter-connectivity adds more noise than it does useful information. Consider a disconnected country like, say, some craphole in Sub-Suxharan Blackfrica, where the majority of the population doesn't have access to the internet. Should we further lower the costs of connectivity to the point where everyone there can participate, we might gain a few people contributing marginally-useful information (if we're lucky). In return, we'll have to endure the addition of hundreds of thousands of idiots, illiterates, perverts, net.k00ks, trolls, spammers, and scammers. The noise this latter group generates doesn't just advance us no closer to our original goal, it actually detracts from it. The descent of some once productively-communicating forum on the internet into uselessness via being flooded with malformed, non-topical, incorrect, and/or ignorant communication is so common that I hardly need to cite examples. We're all the poorer when stupid people operate keyboards.

So, what are we tortured few who actually want to engage in meaningful exchanges to do? One of the few good things about a fully connected world is that we have a functioning ecology of mediums competing for participants, so we have plenty of real world data to judge what works and doesn't. Herein, I'll address two complementary methods - both already currently happening right now, but which came about simply for natural selection reasons. Examining the successful factors here and intentionally incorporating and amplifying them into future mediums will ensure some more realistic subset of our original goals can be achieved. Lastly, I'll relate these to some more large-scale structural musings in attempt to salvage our original ambitions.

Walled Gardens

Most existing communication technology that remains useful incorporates some inherent or intentional barriers to participation. Of these, by far the most effective is the technological barrier. Having to manually configure some mildly complicated piece of software, internalize a few typed commands, or understand foreign network structure keeps the vast majority of idiots out of irc, mailing lists, and version control systems. This is often coupled with less effective barriers like account creation, human moderation, captchas, and karma systems. These add-ons help some, but tards still make accounts, moderation is usually carried out by losers, captchas are a mindless timesink overhead, and karma systems breed karma whores.

I contend that the technological barrier to entry is by far the most effective because it does something no other existing barrier does: it tests the potential participant's mental ability. Anyone who can't parse a few HOWTOs isn't going to be generating any meaningful communication after all. Why stop there though? Consider the following system of my design that makes this concept its foundation:

We can establish identity via some form of cross-medium identity service like OpenID or an addon service to it that associates identities with a measurement of the probability that an individual will contribute content and not noise. Let's say this is just a simple IQ test. Now, while no one's forced to humiliate themselves with a low IQ score attached to their online persona, if you want write access in that type theory forum where the world's greatest type theorists all hang out, you'll have to meet their minimum IQ requirement. Maybe they recognize that there remain smart people out there who may nonetheless be too ignorant on this particular subject, and duly also require a domain-specific knowledge test as well, while listing some reference literature for the capable neophyte to get started.

Now we only need some lightweight backup system like human moderators for those rare events when a tard does manage to slip in or a formerly acceptable member converts to Eckankar. Concurrently, other problems requiring the introduction of additional meta-complexity, like intentionally making our medium technically obscure to scare off n00bs, are largely unnecessary since a high baseline qualification has already been established - one nearly impossible for the incompetent to circumvent. Apart from identity theft, the only way around such an obstacle is to actually become competent.

Our goals are (in order of importance): Keeping idiots out, letting smart people in, and minimal intrusion on smart people with protocol overhead. While I'm under no illusions it should be the final word on the matter, this system accomplishes all of these.

Honeypots

No system of restrictions are completely airtight, and we'll get less work done if constantly besieged. One solution to the problem is so effortless it requires no more than illustration by this simple thought experiment:

Imagine yourself a typical attention-starved nobody who wants a rooftop to bleat meaningless drivel from. Before you are 2 communities: The first is populated by a dozen mathematicians soberly discussing recent developments in homological algebra, has a spartan text-based interface with its only feature being the ability to attach TeX-formatted mathematical equations, and requires a minimum IQ of 130 to participate. The other contains millions of like-minded participants and allows the creation of an altar glorifying the self, complete with textfields to list products and media you consume, all manner of shiny and colorful features, and most importantly, a sense of belonging. It presents no barriers of entry apart from the ability to remember a password.

This side of the problem is generally solving itself, but it certainly can't hurt to make popular intarwebs software even more time-consuming, have more real-time connectivity to the point that participants can report on trivialities on the scale of restroom visits, and have increased access to images of reproductive organs. By providing more point-and-drool CMS frameworks for pseudo-developers to service these needs, we won't have to actually do any of this tedious labor ourselves.

The Final Solution

This carrot/stick approach, while granting us sanctuaries to work unmolested, won't save us out in real life from the tyranny of the vulgus many, who with their buffet-forks and crème brûlée torches, periodically amass at the sealed gates to angrily demand salvation from their own ineptitude. This happens now, after all, and at the moment of truth, the true culprit for our suffering is revealed - and it is ourselves.

Subsidize drooling long enough, and you'll one day wake up waist deep in it. The status quo inevitable from not a meritocracy, but one where equality is enforced on the basis of having a pulse, necessarily favors that group which has the largest population disparity advantage. Hoi polloi will always outnumber the real men who actually build this world, and finite resources are therefore democratically redirected into their frothing, insatiable maws. Meritocracy is observably the order of the natural world, but is currently being held back in human affairs by various memeplexes, which even pollute many of the brains of we few holding all the cards. Observe the existing state of affairs where the primal urges of the peasants are collected by the equally dim-witted of higher social, but not mental, status (i.e. your typical talent-toilet MBA). We with ability are then given requirements and toil away on products which we would never ourselves consume. Every participant in this process is expendable except the creators, who maybe with some help from me, will notice that by creating, they also enable.

I'll elaborate on the specifics of the parasitic memeplexes at work here at some later date, but since this post is about actionable ideas, I propose we use the aforementioned honeypot concept to disempower first the main breeding body of commoners, then our equally-simple handlers. Our hands are already dirty serving their whims, so why not temporarily continue doing so in exchange for their more permanent purchasing power? Once sidelined financially, social disenfranchisement will naturally follow. This would freely happen of its own accord should egalitarian subsidization backed by force not be the norm. In fact, as mentioned in the previous post, it's already happening here in the US right now despite futile countermeasures, as wealth redistributes itself from unproductive Americans to harder-working Asians. Nevertheless, sans more fundamental (e.g. ability-based, not geography-based) dividing lines, plebeian hubris will never fail to eventually rise once again wherever competence congregates.

Liberated from wasteful fancies and having converted our overlords into the commodities they should be, we could then start consuming and reinvesting the products of our own labor in ways we, not Walmart customers, so desire. On the pragmatic side, this will ironically probably end up benefiting even the commoners, as faster computers and more efficient cheese factories help everyone. Being only focused on such an infinitesimal slice of technology myself, I can't begin to conjecture what wonders such a reordering of management might bring, but I can definitely say we won't get any technological singularities creating more payroll management systems or building squishier icons for cell phone UIs.


June 29, 2009 - Cognito, Ergo Sux

"So, whom do we eat first?" - "Me! I am delicious!"
- Dmitry Orlov

On the Economic (and Possibly Overall) Fate of the United States

Modern economists pretty much fail at their main job of understanding and describing markets, particularly on the macro scale. As Upton Sinclair said, "It is difficult to get a man to understand something when his job depends on not understanding it." With macroeconomists mainly existing today to mouthpiece Keynesianism and monetarism largely for political reasons, one might wonder why anyone listens to people that are consistently as wrong as they are. Because, wrong they are, and quite often. If only an economist would predict that the majority of his contemporaries' predictions would be wrong every time a forecasting frenzy began, we might finally have a successful one.

Economics, despite being a social "science", was actually reasonably successful at making sense of markets long ago. This is primarily for two reasons. The top one is that the products of economic thinking were largely free from people paying to hear certain results. By contrast, all competing fields of economic thought, like Austrian Economics, are now sidelined since most don't prescribe meddling by governments or central banks. Thus, debates are simply reduced to something like "by what percentage should we dilute existing wealth this year?" which is more of a Hobson's choice than a debate. The second main reason is that with the aforementioned interference, even if we had a model that could accurately predict the effects of a particular intervention, it would be meaningless in context of all the other interventions in effect, not to mention the chaotic volatility introduced by the fact that at any unknown point, arbitrary new rules or parameters can be introduced at whim. With human behavior, even in aggregate, already difficult to predict with any precision, this makes things infinitely worse for prospective speculators. Even ignoring this, the fact that there are no economists striking it rich as investors or traders is a telling sign, as any significant, consistent edge in some small niche of the financial markets would be all it'd take to get very wealthy, very fast.

That said, I caveat my remarks by pointing out that in such an economy, no one can scry divinations with any serious level of confidence - not professional economists and not amateur number-watchers like myself. On the other hand, maybe the numbers we're watching are just so massive and the trendlines so steep, that they exceed the volatility introduced by the previously mentioned agents - which are equivalent to line noise at the level of abstraction necessary to keep said trendlines in scope. If this were the case, we should all be interested in which direction they're pointing. Our collective fate may be sealed, but maybe there's something individuals can do. I offer these admittedly vague predictions with all of the lack of confidence that you'll never get from a professional economist.

Realpolistats

The state of the US economy is far more dire than the average American thinks. If you take government-released indicators seriously, your perceptions of economic health are greatly distorted towards the positive, and while popular sentiment is an inarguably important factor in macroeconomic health, irrational positivism with no basis in reality is very much a net negative thing and becomes more so as the time scale increases. For instance, irrational positivism in popular notions of personal wealth have recently led the average American into a depth of debt bondage the likes of which are historically unprecedented. Centuries ago, indentured servants here signed away 3-7 years of labor, but afterwards had a fair chance of making their fortunes in a new country free of kings and tyrants. Today, we indenture ourselves for 30 years or more in exchange for mass-produced drywall boxes or degrees in gender studies.

Practically all official economic indicators are fudged via various hedonic regression models. A prime example here is GDP, one of the most important signs of national economic health. This number, currently around $14.3T, is unfortunately meaningless in its current state due to several intentional contortions, the largest of which occurred when GDP was changed to include consumption. Of course, Americans love nothing more than consuming, and while it probably once provided a nice boost to the GDP for some immediate payoff (typically, equations to factor indicators are "rebalanced" by incoming presidential administrations, mostly for bragging rights during reelection campaigns), it's now an intractable, essential component. Consumption is now a stupefying 70% of GDP. Of course, consumption has no business being in this formula. Anyone with half a clue wouldn't add the amount of money he spends to any measure of his productivity. There's other distortions on GDP, but if we just factor out consumption, we're left with $4.29T for our 2008 GDP, which sounds much closer to reality when you consider that the federal government got about $2.4T in tax revenue that year. This rough, "back of napkin"-quality calculation result fits in with an earlier post that cited taxes being roughly a 60% drain on productive capacity. Anyhow, if you're paying attention, this renormalized GDP should be depressing. It shouldn't surprise you though. Look around at your fellow citizens and try to spot them doing anything productive. You're far more likely to spot them waddling their obese bodies into shopping malls and buffets. And when they do go to work, it's usually in some equally non-productive activity in the service sector.

Other indicators fare no better - inflation, unemployment (try comparing our current U3 unemployment to the previously used U6 unemployment), and the like. I won't bother enumerating all of them. Yet, even with reasonably bright quants in government employ who do nothing but work on these formulas all day, they still paint a dismal picture. The real numbers, however, point to impending doom.

The factors leading to this bleak outlook are so numerous, I would have to write a lengthy book to collect them all. Some of main contributors I'll mention are:

  • Destruction of productive economic sectors: Destruction of our manufacturing base would have been fine, if we replaced it with something equally or more productive. The remnants of those sectors along with new sectors such as the software industry only make up a small percentage of what was once millions of people, getting up every day and making stuff. Now we have fragile service sector jobs in retail, finance, real estate, and massage therapy, which have been the first to go in a crash. Why this is especially important is that in order to pay off debt, we need to create some kind of wealth, and that means producing something people, preferably in other countries since that's where all the capital is, want to buy.
  • The country's shift from creditor to debtor nation: In previous serious economic setbacks, like the First Great Depression and previous serious recessions in the 70s and 80s, even if it was managed incompetently (and by any measure, they were, just not with as many zeros as this time), we were always reasonably sure to come out of it eventually since the world owed the US money. Now it's the other way around, by the order of several times the entire annual tax revenue. If government shut down every function except tax collection, it would still take some 10 years to pay off and service our existing debt. Of course, we're not only not doing that, we're doing the opposite by increasing it at an increasing rate.
  • Inflation of the money supply: The Federal Reserve was ostensibly created in 1913 with one of its main goals being to control inflation. Except, inflation wasn't a problem until then. Since 1913, the US dollar has lost some 97% of its value, even going by the heavily-doctored CPI. These other factors listed here combine to a massive increase in currency dilution with the Fed buying up a majority of the multi-trillions of otherwise unsellable US treasuries that are being issued starting a few months before this writing. This is euphemistically called "quantitative easing", the monetizing of national debt. Anyone with money in a bank or a wage that won't go up to match the dilution (and wages have long since lost pace with inflation) will find their money worth far less as this continues.
  • Increase in size of government: Since WWII, the government has consistently grown in size, but only recently has it truly exploded: +40% in the last 8 years, and plans are in place for the expansion to increase much faster in the coming years. The last number I saw on the percentage of American jobs that were in government was 30% a couple years ago, and it's definitely a lot higher now. Maybe that would be tolerable if it was efficient, but the government can't even run the post office at a profit, despite trying for over 200 years.
  • Increase in socialism: The government controls vast swaths of the economy, and that which it doesn't directly control, it regulates. By any definition of socialism, this is an increase of it. I seem to remember the end of a 40 year Cold War that we vanguards of capitalism fought against the socialist hordes. I guess we lost.
  • Old people: The fact that the zombie population is booming now couldn't have come at a worse time. Even under the current entitlement system (which is now up for expansion again), we have some $55T of unfunded liabilities to pay for. This is an impossible number of course, and certainly healthcare service will suffer and likely require rationing as a result, but under no imaginable circumstance is this scheme workable. Even if everything else was going great in the US, the millions of old people created during the post-WWII procreation binge all demanding monthly handout checks, requiring hundreds of thousands of dollars in life-extension attempts, playing bingo, and generally smelling up the place would have been a massive drain, not to mention the millions of potentially productive people of working age whose lives are squandered tending to their bedpans.

While I might speculate on the price of pork belly futures next month, I can honestly say I have no clue what they'll be. But, the numbers that control the United States' long-term fate here are just too monstrous to be even remotely optimistic about. If things were even half as bad, I still might advise checking apartment prices in Singapore. Together, all these factors set up a perfect storm of a national debt spiral and economic collapse that is all but inevitable.

The Decline and Fall

I'm not going to make any specific predictions, because the actual character of any economic collapse depends on too many unknown parameters. Who knows, maybe the government will eventually institute price controls on commodities, establish a "wealth tax" (a form of property tax on security holdings), or any number of other increasingly desperate and draconian measures during its descent into the abyss. A lot of specific predictions like that are being made right now, but there's no factual basis behind the majority of them. A more rational approach I've never heard would be to view any potential collapse as a standard distribution curve, which I won't bother creating a graphic for. With probability as the Y axis and some measure of severity being the X axis, on the low severity end, we might have a country that more closely resembles European socialism and is suffering from some form of stagflation stretching out forever into the foreseeable future. On the other end, the country completely defaults on the national debt, most likely via hyperinflation, and all manner of internal social disorder results. I doubt it'd ever get as bad as states seceding from the union, but the volatility is so high at that end, that anything's possible. These are both low probability outcomes. Far more likely is some middle ground, with a mixture of massive inflation, defaults on government securities starting with municipal bonds and proceeding up from there, an end to US military hegemony, and the destruction of the majority of remaining private wealth.

Wherever the United States economy ends up on this curve, it's not going to be good for anyone living here. If you're poor, you'll struggle to make ends meet even more, and if you're rich, you'll be a prime target for any number of new taxes and capital confiscation (for example, the US Treasury Dept. claims it has the power to confiscate gold, and has even done so in 1933). However, there's no reason you have to go down with the ship in this day and age. If you've been smart enough to emulate your life after mine, you'll have no reason why you can't just pack up your few meager physical possessions and move somewhere less unappetizing. It'll be pretty obvious where things are heading before it gets really bad - a good sign will be when permabear sentiment becomes firmly entrenched in the majority of people that care about their lives enough to pay attention to such things (like, say, if foreigners stop buying US Treasury notes, which all but ensures hyperinflation).

Despite my complete lack of optimism, I'm still taking a wait and see approach since the negative effects we've experienced so far haven't yet surpassed the point where it's apparent from a simple cost-benefit analysis that I'd fare better elsewhere, given the overhead of emigration. Besides, unlike our newspeak-spewing leaders, I openly admit that I could very well be wrong. If by some salvation I'm overlooking, maybe I can get by staying here and hedging against inflation or even profiting with commodity holdings. One thing the US government is good at is keeping a Ponzi scheme going, so maybe they'll be able to delay our reckoning for many years. For all its faults, the US is a much better place to live than most of the rest of the world, after all. Most other countries are too crowded, smell like fish or human effluent, or are overrun by religious kooks.


April 22, 2009 - Harmonices Mvndi

"Python was the subset of Lisp that was understandable by C++ programmers."
- John Stephen Jacob Anderson

Emacs is one of those rare examples of a true wonder created by man. Those large piles of rocks, phallic monuments, and other physical creations typically considered wonders seem mundane and prosaic by comparison to the realized ultimate in human-computer interaction. Install Emacs, and prostrate yourself in mortal humility before its extensible glory. Keep your .emacs file pure as a sacrament to its sanctifying, life-giving enlightenment.

Anyway, Emacs is great. I could extol upon its many, many virtues all day, but the best way to understand why it's so amazing is to just spend the next 6 months or so of your life using it everyday. Entire books have been written on this subject, and even they are no replacement for just using (or, living within) Emacs. So, while the rest of this post may sound like evangelism, it's really just Emacs-related, positive self-affirmation.

My personal Emacs story isn't very interesting: I started using XEmacs back in 1999, since it was far superior to GNU Emacs at the time. I used it for a few months, but then got a job where everyone used vi, which I already knew well enough for years. So, I switched over to that as a result, hardwiring my motor control functions to its command set. Shortly thereafter, I discovered vim, and had basically been using it, and roughly the same .vimrc file, for the next 6 years. Long into this process, I realized I was missing out on some amazing stuff for programmers, like integrated REPLs, and finally cut my losses and perma-switched to GNU Emacs about a year ago.

As often happens with introductions to a transcendent paradigm (like, a long-time PHP programmer learning a real programming language), Emacs opened up a world of extensible computer interaction I never realized was accessible (at least, not anywhere near the level it is). There's really just no replacement for being able to program features/behavior into your environment on the fly in a Lisp-dialect. More importantly, unlike the more static vi/vim, Emacs really isn't (just) an editor, but a framework to do with as you please.

I don't yet use Emacs for everything, like some people do. Some of these excluded tasks and why are as follows:

  • File management: I do sorta use Emacs for this, by running a zsh shell in a buffer, but if you have a sensible directory hierarchy that's easy to remember, there's no need to create a new directory content buffer for each navigation operation. M-x dired is useful, however, for macroing and batch operations that would otherwise require one to dirty their hands with a lesser shell scripting language.
  • System Administration: Sysadmin tasks are for IT monkeys, but since I don't own one, a .conf file tweaking task occasionally comes up. But, root should only use /bin/vi under /bin/sh.
  • Anything graphics related: Since any task involving graphics is probably a waste of time, this doesn't come up much.
  • ncurses games: Emacs does provide plenty of games, but some external games, like most rougelikes, don't render properly in shell buffers.1

Apart from the file management, these tasks are an insignificant portion of my life, and I reserve the right to use Emacs for any of them in the future.

Emacs is the ultimate IDE for any language worth actually writing code in. Emacs is the ultimate publishing tool (I'm composing this text in Emacs, of course), personal planner, NNTP/HTTP/SMTP client, and tool for any productive activity imaginable. I wake up the morning and reattach GNU screen to my emacs -nw session. I attach to the session at work and use Emacs all day. I then come home at night and use Emacs all evening. When I go to sleep, I often dream about Emacs, SLIME, and org-mode and how amazing they are. I fully intend to be doing this for the rest of my life. In fact, `Emacs' is synonymous with `life'.

1 UPDATE: It turns out you can run just about any ncurses app in M-x ansi-term or multi-term. Never doubt the One True Editor.


March 10, 2009 - Ea Tempestate Plebs

"You're looking rather prosperous, sir."
- Lawrence Minard

Humans around me often say stuff like "I don't care about money." They might as well be saying "I don't care about my life," since this attitude will typically result in a lifetime of working for exactly the thing they claim not to care about. If you don't care about money, then why are you wearing that paper hat and name tag? There are people on this planet who can make this statement without consequence. You aren't one of them. You are nobody.

The external world that exists outside your skull isn't going to solve your money problem for you (and you have one, whether you acknowledge it or not). In fact, it's filled with entities that want to do the exact opposite of this. If you're lucky, you'll find someone that wants to trade you some money for time slices from your finite life. My economic goal in life is to sell as few of these slices as possible, for as much as possible. With the majority of the people in this country caught with their designer khakis down by this economic crisis, here's some almost-timely advice along these lines.

Debt Bondage

The only thing worse than being broke is being a debt slave. You were born into this world with nothing. If you now have a negative net worth, what does that say about the total value of your activities on Earth thusfar? Debt slaves often have decades of work ahead of them just to be a nobody.

I would just commit suicide if I were as deep in the hole as the average American, but for those who like long shots, the first step to getting out of the hole is to stop digging. This means stop buying plastic molded into various shapes and then marked up 3000%. Consumer goods depreciate by up to 100% as soon as your remove them from their packaging. Some purchases actually have a return on investment even worse than -100% due to upkeep costs. For example, the food you buy then consume turns into feces. Unless you're into coprophilia, owning feces is undesirable, and you have to pay a sewage bill to dispose of them. Obviously, you need to buy some things in order to continue living. Do so minimally, and consider these what they are: necessary expenses.

Living on (Almost) Nothing

Once you've achieved a $0 net worth, you've still got the rest of your life to pay for. While you do have the small luxury of paying for these costs later, at some point you'll have to earn or steal the money to pay for next year's food. I like to measure wealth, not in dollars, but in time. How wealthy you are is how long you can live without doing stuff you don't want to do. Someone with no obligations may survive on almost nothing, while a guy with child payments who insists on living in an expensive house will require considerably more money for the same amount of time. Once you have enough to pay your expenses the rest of your life, you can start measuring the quality of that time in dollars. Apart from the few lucky (or possibly deluded) people that do exactly what they want to do for their day job (and I don't mean just the main task, like programming, but all the extra crap that comes along with it), one way this is achieved is by spending less.

It's possible to live on almost nothing. While I could easily write an entire book on this subject, here's a few ways to do so, most of which I've personally used:

  1. Buffets: Pay for one meal at a buffet, dining hall, or some other place where you ladle your own gruel. Load up several trays with packable items like fruit and cookies and casually slide them into your backpack when no one is looking. You can do the same with prepared food if you sneak in some sandwich bags. I've walked out of buffets with an entire week of provisions this way.
  2. Catered Events: Keep an eye open for events like local business meet-and-greets, large family reunions, company picnics, religious gatherings, funeral receptions, etc. Make sure the event is large enough that you can inconspicuously stand in the corner stuffing your face for 20 minutes or so. You can combine this with the previous tactic for even more savings. This may sound risky, but if you use some common sense picking your targets, you'll never get caught. I've personally done this at least a dozen times and never even had to come up with a story (though I had one ready).
  3. Fast Food Restaurants: Here you can help yourself to napkins, ketchup packets, plastic forks, cups, and various other amenities. You might be able to find spare toilet paper in the bathroom too. A backpack full of toilet paper rolls is as good as $5 in your pocket.
  4. Mom's Basement: Live at home as long as economically sensible. Continuously do a cost-benefit analysis of the situation though. Like, maybe you could make more money overall by moving to a new city, even with paying rent. Also, if your mom is a hysterical, nagging old crone, factor your sanity into the equation too. Keep in mind that you won't impress many whores with these living arrangements, but that leads me to...
  5. Celibacy: Nothing costs men money, and hence their life, more so than their manparts. Financial woe awaits he who is not smarter than his. You're not special just because some dumb whore likes you. Look around sometime. See all those ugly and stupid married people? They were amazed to find someone actually interested in them too. It can and does happen to anyone. In fact, if you don't actively try not to, it is almost inevitable to happen to you sometime in your life. It can help to get as ugly as possible without damaging your health or to nurture some strange fetish so perverse and impractical that it would scare away even the most desperate shebeast, but a lifetime is a long time to dodge this bullet unless you acknowledge the problem and are committed to avoiding it.

While there are countless other ways to save money, this section would be remiss without mentioning the largest expense in almost every American's life: taxes. Common wisdom holds that you work a third of the year to pay tax, but the reality is far worse - direct federal income tax of up to 35% (plus another 15% paid by your employer that you never see), plus state and local tax, various entitlements like unemployment and social security programs you can't opt out of, sales tax on the other end, an uncountable number of small taxes like phone and gas tax, property tax on stuff you already paid for and "own", and a steady 3-4% of inflation with taxes on interest/capital gains making saving effectively pointless. You can easily make a $100k salary and only actually get about $40k of real value out of it, most of which has to go to rising costs for basic needs and costs associated with the "privilege" of having a day job. And if that weren't bad enough, the value of all items is distorted due to the fact that all those taxes are paid yet again at every step of the process to produce the things you buy. This is another reason I suggest not bothering to buy stuff or only participating in the economy enough to free yourself from it. There are ways to legally pay less taxes, but this really deserves a post of its own to address fully.

While stealing can save a lot of money too, I don't recommend it, unless you're already an epic level rogue. It only takes getting caught once to wipe out a lifetime of small gains.

Gold Farming

Though it is possible to achieve the stated goals here via frugality alone, a far more efficient strategy would be to combine it with increased earnings. I don't consider myself as much an authority on this subject as prior ones (I was a debt slave myself until a couple years ago), but I'll offer what insights I can.

A job is the main way most people earn money and it's also the worst way to do it. Unless you're paid an enormous salary, money slowly trickles in while you trade away massive amounts of time. Look back on a year of full time labor, and you'll wonder where all that time went. There's also a lot of overhead involved, like the several hours a day you spend getting ready for and recovering from work, money spent on non-offensive clothing, and intangibles like warping your potentially creative mind into that of a worker drone. Nevertheless, a job is a necessity for most of us, so try to get one that at least gives you a 1:2 ratio on years worked to years of non-work funded. If nothing else, you don't want to end 10 years of employment with nothing to show for it besides some depreciated baubles. You should also try to get a job that has mental benefits outside of your immediate position, like learning all you can about a specific industry so the option to go into business in it yourself is available later.

Apart from employment, the other main options are going into business for yourself or investing. Most adventures into this realm end in disaster for the average man for two main reasons: 1.) they simply lack the mental faculties to make it on their own, and 2.) they've been so well-conditioned to groupthink from a lifetime of school and employment, they are no longer capable of offering anything of value or making their own decisions. If you don't fall into these categories, venturing out on your own is no more risky than employment, which has its own costs and risks.

Business creation and investing are far more efficient uses of your time, if done properly. For example, a skilled day trader can easily make thousands of dollars with a few hours of work. An unskilled one could just as easily lose years of manual labor in the same amount of time. The distinguishing factor here is mental ability. It's my opinion that a smart person will always have the ability to make enough to live, even in the employment realm, but doing so the hard way is a waste of his time. I prefer day trading, and even though I don't yet consider myself a completely skilled trader, I no longer even bother stealing ketchup packets at Burger King. The ease of creating wealth when you've got a functioning, unconditioned brain puts money into a new perspective, so much so that you may be insulted when you look at your paycheck. The sad irony is that everything that supposedly prepares you for adult life, from early schooling to higher education, is exactly what kills your ability to effectively break the fate of lifelong indentured servitude.


September 12, 2008 - Noli Turbare Circulos Meos

"The average man, who does not know what to do with his life, wants another one which will last forever."
- Anatole France

With most of my free time being sucked up lately, I've not been able to compose a post with anything resembling a point. While this is still the case, I will post a random mashing of various unrelated topics, instead of being forever silent.

L1J-En

I always wanted a decent private server emulator for the MMO Lineage 1, and checking in on the progress made recently, I was pretty disappointed at the complete lack of anything resembling competence on the "efforts" made in the non-Asian world. So, I started this project to fill that void. After a few months, it's already the most bug-free and feature-complete server emulator for this game available, thanks largely to being able to locate other competent developers.

The downside: since it was impractical to completely rewrite this project from scratch, it's saddled with a bunch of lame technologies (e.g. Java, MySQL) and a bunch of even lamer design. If life wasn't so finite, I'd redo all of this, but just getting most everything working properly is really all the polish I'm willing to expend on this moist lump of excrement. Another main downside to starting this project is that it's a huge timesink where I learn practically nothing. Seeing hours go by with my GHCi cursor blinking expectantly yet neglected brings a sad, lonely tear to my sight orb. By far the biggest negative of putting any time into this is that like any multiplayer game, it brings you face to face with the naked stupidity of the unwashed masses and I worry that staring plebeian vacuity in its drooling, gaping maw is like staring into the abyss, which also stares into you.

Ward of the State

So, I thought I'd be a good peasant and go get a driver's license and some valid plates/tags/etc. The nearest DMV (which I had to waste my time looking up the location of on Google, not to mention drive there) was a pretty dismal sight - from its bland, suburbanite-gulag exterior; to the equally bland, defeated faces of the commoners queued up within. I've experienced the wonder that is homogenous unity, and it smells like Mexican armpits. Meanwhile, an armed security guard stands ready to remind the proles which member of the citizen-state relationship maintains the monopoly on the use of physical force. The statist drone at the information counter informed me what a fool I was to think I could just walk in there without proof I existed. Apparently, getting permission to press pedals and turn a wheel requires documentation that I was born as well as some that I have secured shelter. I returned a couple days later with these quests completed and was assigned a queue number. The government then reminded me that my time isn't worth anything by making me wait for over an hour before I finally gave up and went back to work (ironically, also for the government). The final chapter occurred the next Saturday, where I actually wasted yet another trip and had to expose my hands/face to sunlight yet again just to find out that the Labor Day holiday apparently was a 3 day event for government employees (the Department of Labor probably got the whole week off).

So, I guess I'll just continue driving illegally. At least this spares me the final coup de grôpe of having to actually pay for the privilege of successful completion of this process.

In other news, the Central Committee reports another record harvest!

SICP

I'm finally getting around to working through SICP, which is almost universally recommended educational reading by PL theorists, and something of a rite of passage (though one you're typically supposed to do in the beginning of your CS career). I tried out several Scheme interpreters, like MIT/GNU Scheme and mzScheme, but settled on SCM integrated with Emacs, of which I haven't noticed any shortcomings, at least for this purpose. I'll post my solutions to the problems in the book as I solve them here.

One thing that always annoyed me about the "wizard book" and the MIT video lectures version of the associated course, is the intro. In it, there's a pointless analogy made between computer programming and mysticism. Thankfully, the k00kspew only lasts a few paragraphs, then the rest of the book is quality computer science.

This book is really a distilled outline of everything you should have learned during a Bachelor of Computer Science program. If you have a CS degree and find this book full of foreign concepts you should probably resent your university for being an expensive degree-mill and/or yourself for being a spoon-fed moron. In my case, I never once heard the terms "tail-recursion" or "closure" in an actual lecture, even in gradschool (the books had this stuff, but you had to be motivated enough to read up on it yourself). Naturally, my alma mater recently turned into yet another n00b-factory Javaschool, where kids can spend 4 years debating whether Manager should be a subclass of Employee. I guess this is adequate for a life of rotting away in the corporate salt mines though.


March 29, 2008 - Exegi Monumentum Aere Perennius

"The ancient reckoning held that the Five Skrelkampi (and their Truebine) would return when the great Trond-feast could be held anew and the Belnap reunited."
- Progress Quest

With very few exceptions, I'm thoroughly bored playing most of the games purchased in the last few years, even after filtering them through my internal crap detector. After you've spanked your 10 millionth dire badger, the charm is lost and you just become apathetic about the fate of Abeir-Toril. I still like a few turn-based strategy games and the occasional sim or single-player RPG, but modern day progress outside of graphical fluff and MMO nannyism is shamefully stagnant. A shame and a loss, because I'd gladly hand over my $5 for a truly innovative game. Unfortunately for me, gaming consumers are a swarm of mouth-breathing fun-whores with primitive urges (like companionship, ego reinforcement, and what Ted Kaczynski called "the power process") that need satisfied, so no one is going to make one.

The epic scope needed to faithfully take PC games to the next level is beyond the occasional after-hours effort of a single human, and since working with other people is not an option for reasons too extensive to enumerate here, I accept the fact that this kind of game will probably never exist (since I won't be writing it). That doesn't mean one shouldn't see how far they can get though.

My perpetually vaporware attempt at a gaming opus magnum is something I've been thinking about for the past 8 years. Despite this amount of time, I recently realized everything prior to about a year ago isn't of high enough quality to preserve. I admit, my thoughts were corrupted by the limited imaginations around me. Like Aleistard Crowley's deathbed lamentations upon his wasted life of foolish triflerism, I confess my former peccability. At least it didn't take me a lifetime of depravity to figure out. In an effort to actually materialize something tangible at some point, and to help you members of the general public create games better than the soulless poop fountains currently being produced, I hereby disseminate some of my current thoughts on the matter.

Game Semantics

Like programming languages, a mathematical formalism of the logical semantics of games can provide a system within which one can construct and validate theories within a game model. As an applied semantics, game semantics are analogous to domain specific languages in formal language theory. When founded upon formal calculi, we can provide a domain-theoretic system upon which model correctness (formal program verification) in relation to a specification is possible.

As a simplified example, consider turn-based, 2-player, fixed-size universe games (such as chess or connect-n). We can apply type classes to the category of games (defined in Lamarche [1]), or even objects. Where O and P are the sets of moves available to the opponent and player, we can define a grammar similar to this one lifted from game DSL Eriskay [2] (note that I dropped the sub-game "tagging", as I fail to see its relevance), where z ∈ Z (set of integers).

o ∈ O ::= q(z) | andL(o) | andR(o) | impL(p) | impR(o)
p ∈ P ::= a(z) | andL(p) | andR(p) | impL(o) | impR(p)

For each move o or p, q(z) is a question and a(z) an answer (here, z is a label), and the rest is just the constructs needed to define the move itself, the definitions of which are beyond the scope of semantics (this is just an example). Assuming we've defined our grammar, we'd then want to know something about how to formalize isomorphisms between the types we define.

De Lataillade [3] describes System F game semantic models represented as collections of trees. Here, trees are used to describe the modulo reduction rules of a system (or parts of it) much in the way lexers use trees. Laurent [4] proposed an approach within game semantics for characterizing isomorphisms in the λ-calculus between categories of trees. Pragmatically, this tells us about properties of our semantics by looking only at the model.

A related thought I had was to abstract isomorphisms outward to include non-semantic models. After all, we can use graph theory concepts apart from trees (directed graphs, bigraphs, etc.) to model any imaginable structural relation between types. Generic graph isomorphisms are merely bijections however, so more research is needed before I can determine whether there exists (or can be created) any useful applications of the more structure-determinate graph homomorphisms (such as graph coloring).

1. Lamarche, F.; Sequentiality, games and linear logic. Manuscript 1992.
2. Longley, J., Wolverson, N.; Eriskay: a programming language based on game semantics; 2008.
3. de Lataillade, Joachim; Second Order Type Isomorphisms Through Game Semantics; arXiv:0705.4226v1 [cs.LO].
4. Laurent, O.; Classical isomorphisms of types. Mathematical Structures in Computer Science, 15(5):9691004, October 2005.
See Also: Abramsky, S.; Semantics of Interaction; Pitts, A., Dybjer, P. (eds), Semantics and Logics of Computation, Proceedings of the Newton Institute, Cambridge University Press 1997.


March 17, 2008 - Comme Appelé du Néant

"All that poets sing and grief hath known, of hopes laid waste, knells in that word 'alone.'"
- Edward George Bulwer-Lytton, The New Timon Part II

Here are my current status/goals regarding specific programming languages. This post is mostly just a reminder to myself, so I can look back in a few years and see what changed.

Main Programming Language Focus

  • Haskell: Haskell pwnz0rs your m0mz0rs.
  • Common Lisp (SBCL): I feel like a heretic, but I've finally given in and switched to Emacs for development in certain languages. Emacs+SLIME is really the only way to write Lisp, and I've only been punishing myself by resisting RMS's warm embrace. I still hate commies though.
  • F#: I like F# increasingly less the more I use it, not for the language itself, but its awkward relationship with the Common Type System. Every time I write F#, I just wish I was writing Haskell. Then again, whenever I write C#, I wish I was writing F#.
  • MIT/GNU Scheme: Needed for SICP, HTDP, EOPL, and a few other classic CS texts.
  • Clean/Cat: These are the only other purely functional languages I find interesting on this level, mostly because they retain functional purity by a large collection of alternate methods.
  • SWI-Prolog: There are better logical programming languages, like Mercury, but only being peripherally interested in logical calculi, Prolog will do for now.
Maintenance Efforts Only
  • C#/C++/SQL: Continued survival requires food. Food requires money.
  • C: Money requires answering interview questions.
  • Python: I found a lot of the common Python enthusiasm to be rather baseless from a PLT perspective. Lisp luminary Paul Graham, for example, whose books I'm a big fan of, penned many a praising essay about Python, so I figured there had to be something to it. Well, there isn't. It's just yet another "do stuff" language, lacking any theoretical foundations, and worst of all, includes a bunch of arbitrary, Ruby-esque parlor tricks (like yield). That said, it's not useless enough to intentionally forget, since there are plenty of nice libraries out there for it, and implementing them has relatively low overhead. As for Paul Graham, I could only assume that years of tea-sipping at Y-Combinator had made him soft and squishy, which was confirmed when Lisp-dialect Arc was released.
Language Memory to Return to the Heap
  • Delphi: Believe it or not, you can make a lot of money programming Delphi. Post a résumé with Delphi experience on a jobsite and expect relentless spamming by recruiters and software companies that borders on desperate. What these HR cretins (and recruiters in general) don't realize is that any tard who knows how to program in a couple languages can pick up Delphi in a week. Delphi doesn't completely suck manparts like VB though; it's just not very interesting. Delphi is like your dad, driving the station wagon to the hardware store for more lawn care products. Meanwhile, VB is like your Uncle Gary, who has some candy for you in the back of his windowless utility van.
  • Java: Sure, Java isn't that far off from C# and if you wanted a Solaris development job, it'd probably be in Java. Without getting into a full course rant, I'll just say the main reasons Java sucks are: craptacuslow development software, historical baggage, copious boilerplate, and the drool-factory Java programmers themselves. C# developers at least know they aren't channeling the divine flatulence of Anders Hejlsberg with every try-catch block. Java programmers fall into two, usually overlapping, categories: those that got caught up in the OOP-evangelism that started in the mid-90s, and those that can't program in any other language. Java is popular over in India, where 10 Java programmers huddle around a single Dell Optiplex, focusing their collective cluelessness into the functional equivalent of redirecting feces into a named pipe.
  • Ruby: Same complaints here as Python, with the additions that: Ruby is many factors slower (with Python's performance being pathetic as is), Rails is for fags, and the paltry selection of libs outside of web frameworks. I only wasted a couple weeks with Ruby, so it should be an easy purge.
  • Perl: There's little point in explaining why I'd want to forget Perl, as it's obvious to anyone not a Larry Wall (who for all the Wall family's religious (the literal kind, not the computer-related kind) zealotry, can't even keep sadgirl/poet Geneva Wall from un-wed teen pregnancy) fanboi.


February 28, 2008 - Hostis Hvmani Generis

"Society will shun you. You will shun society."
- Leon Bambrick, The Truth About Lisp

I've started using Haskell for all my everyday computer usage. It's exponentially more productive than writing and debugging programs in C. I'm also writing some F# on the side, and often catch myself typing in one syntax instead of the other. After a lengthy foray into another language, it's usually a good idea to give yourself some practice problems to load the syntax back into your brain's RAM. Here are a couple quick Haskell problems I came up with today along with their solutions. The answers come immediately after the problems, so don't look at them before attempting your own solution. These are typical problems that you probably encounter on a daily basis, and probably waste a lot of time writing lengthy solutions to them in an imperative language.

By the way, that satisfying feeling of intellectual superiority over the mouse-molesting masses you'll have after solving all of life's problems, even the normal, everyday tasks, in such a mathematically pure way is completely normal. Now imagine feeling that way all the time yet still having to face the outside world, and you'll have a small glimpse into my tortured existence.

Problem 1. Create a comma-delimited string of n Fibonacci numbers.

-- pattern matching version of fibonacci
fib :: Integer -> Integer
fib n | n < 2     = n
      | otherwise = fib(n - 1) + fib(n - 2)

-- create a list of n fibonacci numbers
fibList :: Integer -> [Integer]
fibList n | n < 1 = []
          | otherwise = fibList(n - 1) ++ [fib(n - 1)]

-- a better version of the above
fibList2 :: Integer -> [Integer]
fibList2 n = map fib [0..(n - 1)]

-- append commas to all but the last elem in a list of strings
commaDelim :: [String] -> [String]
commaDelim []       = []
commaDelim (s : []) = [s]
commaDelim (s : a)  = (s ++ ",") : commaDelim a

-- tie it all together
makeList :: Integer -> String
makeList n = (concat . commaDelim . (map show) . fibList2) n

As often occurs when writing Haskell, you'll be in the middle of writing some function and suddenly recall a construct that will do the job for you in a single line. This occured here when I was writing fibList.

*Main> makeList 18
"0,1,1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,1597"

This rather uninspired Fibonacci definition bogs down around n = 35 or so. Try writing a faster version of fib for extra points (ultimate solution here).

Problem 2. Create a standalone application that asks the user for numbers until a flag is read. Output the product of those numbers and the binomial coeffecient of the numbers paired off by input order.

module Main
    where

import IO
import GHC.Float

main = do
  hSetBuffering stdin LineBuffering
  nums <- getNums
  putStrLn("The product is " ++ show (foldl (*) 1 nums))
  mapM_ (putStrLn . binFormat . pairCreate) nums

getNums = do
  putStr "Enter a number (0 to finish): "
  num <- (fmap read) getLine
  if num == 0
    then return []
    else do
      rest <- getNums
      return (num : rest)

fac :: Integer -> Integer
fac n | n < 2     = n
      | otherwise = n * (fac (n -1))

--binomial coeffecient
binCoef :: Integer -> Integer -> Float
binCoef n m = fromInteger(fac n) / fromInteger((fac m) * (fac (n - m)))

binFormat :: (Integer, Integer) -> String
binFormat (x, y) = "Bin(" ++ show x ++ "," ++ show y
                   ++ ") is " ++ show (binCoef x y)

pairCreate :: [Integer] -> [(Integer, Integer)]
pairCreate []             = []
pairCreate (w : [])       = []
pairCreate (w1 : w2 : ws) = (w1, w2) : pairCreate ws

Why would you ever want to do this? I have no idea, but it's a good example of requirements that have no inherent logical structure to them. When you're at work, do your clients/customers come up and say, "Larry, go ahead and take 3 years pondering a formal system to model our domain of interest in a dependently typed theorem prover"? Mine usually don't. With a little beard-stroking, you can turn random problems into almost-elegant code though.

Of course, parsing user input requires an IO Monad, which is why read must be fmapped to getLine for inferred type matching. Likewise, the functional composition above requires a Monad-aware version of map.

*Main> main
Enter a number (0 to finish): 3
Enter a number (0 to finish): 4
Enter a number (0 to finish): 12
Enter a number (0 to finish): 3
Enter a number (0 to finish): 22
Enter a number (0 to finish): 3
Enter a number (0 to finish): 0
The product is 28512
Bin(3,4) is -0.25
Bin(12,3) is 220.0
Bin(22,3) is 1540.0


December 27, 2007 - Præmonitus, Præmunitus

"Ἑλληνιστὶ πρὸς τοὺς παρόντας ἐκβοήσας, 'Ἀνερρίφθω κύβος,' διεβίβαζε τὸν στρατόν"
- Πλούταρχος

Do other humans go out of their way to speak extremely slowly and use simple words with few syllables in your presence? Does the idea of parking your large, bovine mass in front of a televised sporting event and repeatedly dipping your greasy fingers into a bag of chips interest you? Does your mouth absent-mindedly droop open to one side? If so, you are probably stupid. However, you can take some solace in the fact that you are certainly not alone as most people are just as stupid as you, or even more so. In fact, stupidity is actually an asset in some sense, as the world is really designed with you in mind. This, sadly enough, includes the computer science and mathematics curricula at most universities.

I suspect that most learned computer scientists would be just as successful, if not moreso, as autodidacts, provided they at least have some initial guidance as to what base theories to investigate. Without that early direction, you just end up being an untrained "street programmer", as I've occasionally heard it called. In other words, just knowing specific languages or technologies isn't enough. In fact, you should intentionally ignore wasting your time on the latest SE acronym. Having mastered the underlying theory, any particulars can be learned the week before you start the job where they are needed. CompSci programs are really headed in the opposite direction from this (i.e. the "Javaschool" scourge). You should still get a CS degree, if you can, but in-between learning how to be a salivating design pattern whore, learn some real CS by taking my free advice. You don't want to end up writing some drab web-based database front-end or yet-another-accounting-system, do you?

Consider this: the vast majority of the US economy is made up of the vaguely-named "service sector". The previously mentioned mundane software jobs are an important part of this, and where most software developers work. This work might be challenging for stupids, but if you follow my advice, you'll want one of the cutting-edge compsci jobs. Where are those? In the only industries the US really excels at: entertainment, academia, and defense.

By entertainment, I mainly mean games, but there are other good inroads into the sector. Unfortunately, video gaming, like academia, is currently suffering from a serious dumbing-down. If you work in the industry, you probably won't have a chance to be very creative. How creative can you get when tasked with designing the latest incarnation of some retarded console sports game? However, getting the best job in the video game industry is easy. Simply quit whatever job you currently have, apply for welfare, and stay home writing only the video games you want to.

These days, half of everyone graduates from college, something that was reserved for only the smartest of people a few centuries ago. Are half of humans today as smart as the intellectual elite of yester-year? I think not. The blank, vacant stares of students during the last (and only) time I ever taught a class were precisely the types of idiots that really belong out in a field doing the manual labor that peasants like them should be doing. Putting a peasant in a CS class is like putting a monkey in a suit. Nonetheless, the most prestigious theoretical computer scientists often work in academia, and becoming a non-teaching post-doc is a fine career choice in both CS and math.

For those that want to have a more immediate effect on the world, the defense sector is the obvious choice. If you don't mind looking at Dell logos all day, you can help blow things up all over the planet, and more importantly, work on some of the most interesting projects around with plenty of opportunities to flex your CS abilities. Of course, this depends, since you could just as easily get a job writing an inventory management system and still be in the defense industry. But, unlike actually being in the military (where you'd just be a button-pushing end-user), you can simply apply for only the jobs you want. My only warning as a defense contractor is to not work your way too far up the career ladder, since you'll then waste most of your time in endless liaison meetings with imbecilic government employees, military personnel, and extraterrestrial ambassadors, preventing you from getting any serious compsci done.

You now know what your end goals should be. Next time, I'll tell you exactly how to get from here to there; turning the idle sloth that you currently are into a well-honed algorithm generator.


December 13, 2007 - Le Dernier Cri

"When asked why he spent so many hours in the lab, he noted that the alternatives were to go home, where he would do the same things that millions of others were doing, or to work in his lab, where he could discover things that no other human had ever discovered."
- Douglas E. Comer

As someone who reads massive amounts of inane drivel on web forums, Usenet, and "blogs", I can't help but notice that members of the general public will often brag shamelessly (far more so than they would in real life) about just about anything, but especially computing habits, software installed, and hardware owned. Every day, I inevitably view some guy besieging some post-accepting medium with rabid enthusiasm about how he only runs Opera, owns some Apple product, installed some Linux distro, hooked his computer up to his television, or something else equally mundane and yawn-inducing. Apart from the sad fact that in their miserable lives, such mindless banality is considered an achievement, what is also occuring here is the pursuit of novelty: the attempt to distinguish one's self from the rest of the herd of product-consuming clones by consuming products slightly different.

Novelty is relative. At some point, being different stops being cool. You can only be outside the norm in so many ways before you're no longer a trendsetter, but a weirdo. Declaring this obvious fact is not intended to be critical of being abnormal. I wish I lived on a planet where the inhabitants were both unique and smart enough such that everyone was weird by current norms. However, I'm also thoroughly unimpressed every time some braggadocio boasts aloud about the novelty of his home network that, having put all of a few hours of effort into it, he is now sure is suitably unique. This post is to inform you cl00bies that you are a long, long way off.

Running old hardware or software, in and of itself, is not uber. A lazy or poor person could just as easily be stuck with a 386sx16 running DOS5.0/Win3.1. In fact, many boring factories and warehouses are to this day. That setup would make you about as uber as an accountant or cashier from 1993. Careful, thoughtful selection of which obsolete products you use is an important statement, as is what you intentionally ignore. More importantly, there's nothing elite about just being an end-user. A real computer freakshow writes code and does so because it was what he was born to do. You don't buy uberness on eBay, you have to live it. Here's some example archetypes of truly uber hax0rs:

  • The Imperator: This guy runs NetBSD 1.3-stable on a customized Apollo workstation, and not only just uses the command line, but does so remotely via a greenscreen WYSE terminal wired into his single-room apartment's closet. There he writes F77, Modula-2, and m68k ASM while wearing women's underwear and a velvet cape. The extent of his social life consists of a small hole drilled into the wall, where he can spy on his neighbor's children.
  • The Retired BOFH: This aging male administrates several vintage mainframes in his basement, which of course he never leaves. His man-cave is furnished with various Burroughs mainframes, Sperry UNIVACs, VAXen, and at least one PDP-8. The Retired BOFH shuns screen editors, and won't code with anything more modern than the TECO line editor over teletype, which he uses to write tape transfer algorithms in obsolete variants of ALGOL and PL/I.
  • The Unlambda: Possibly the next stage in human evolution, what this hairless, naked man lacks in obscure hardware, he makes up for in CompSci ability. Not only does he program in only Haskell Prime, but speaks it in real life too. His brain calculates every action to optimize runtime complexity and solves all problems recursively. For example, he mainly survives on pickles, since the jars are useful for storing urine, which is in turn useful for storing pickles. If you somehow managed to break his gigaquad-key disk encryption, you'd find his pr0n folder contains an indexed catalog of suggestive-looking fractals.

Of course, you don't see these men acting like blustering windbags on public forii. They are too busy doing all the uberlicious stuff you're too lame to even know about. When your supposedly elite lifestyle can compete with these fine gentlemen, I might be mildly impressed.


December 4, 2007 - Ars Pontifex

This fanfic is a short story taking place in the X-Series universe.

Ars Pontifex
------------

"Uh, yeah. Two meatsteak cahoona loaves. To go." Yampa B. Parker was already annoyed for having to wait in line so long. "And make it quick, you mongrel insectoids."

"Gssthhh... ssssir want anyytttthing drinkth witthhh?" awkwardly mandibled the brightly-uniformed Paranid pupa.

"Hmmm..." Yampa quickly eyeballed the overhead menu. "Yeah, a large cahoona shake." The Paranid turned to a coworker and made a verbose sequence of clicking and slurping sounds. A thin mucus started to drip out of a series of small orifices on the cashier's face at which the other Paranid dabbed about with a tongue-like part of his proboscis. Yampa found himself rather annoyed by this inefficient and shamelessly nauseating method of communication.

Meatsteak grease seemed to coat every exposed surface in the Funbeef's Beefhut kiosk, especially the counter and queue railing. It even seemed to permeate the air. Yampa figured that boiling beef fat created airborne grease particles, which would eventually stick to any surface, including the employees. The young Paranids here didn't seem to mind. In fact, pupae typically gestated in a mucus-lined, chitin sheath. "Probably some enterprising Teladi got the idea he could make a few credits encouraging them to hatch early and work for him," Yampa thought to himself. "An Argon would never come up with that."

Stepping over to the pick-up counter, Yampa gazed up though the shipyard's food court skylight in time to see dawn breaking on Argon Prime. From 285 miles above in orbit, humanity's homeworld never failed to inspire transcendent awe in even the most jaded Argon. Yampa felt a sudden jolt of poeticism overwhelm him, and the cacophony of slurping noises emanating from the Beefhut kitchen seemed to fade away. While trying to think of a 7 syllable line that ended with something rhyming with "exosphere", his order came up.

"T'th'kloplithyliyth trvtl'th tjkilk'thnysth thl'p!!!"

"Aaargh! Do I LOOK like a giant, leaking cockroach, you mindless slimetard!?!?" Yampa briefly considered punching this Paranid in the face and running, but then remembered he had swiped his credstick when paying.

"Gttrrrstth... Doesss ttthhe ssssir want beefsssauce?" hissed the alien nearly unintelligibly with that typical emotionless, unreadable face all Paranid had.

"YES. I. WANT. BEEFSAUCE." Yampa heaved a deep sigh of disgust. He could feel the angry frown his mouth was making, but didn't make any effort to conceal it.

The Paranid slid open the door to the saucepit behind the counter, leaned over, and dipped his proboscis within. He then made a loud sucking noise as his oral cavity filled with liquefied Argu beef. Excess mucus stored within other facial orifices began oozing forth as he was doing this, most likely from the internal pressure building within the head section of his exoskeleton. After a time, the sucking and slurping ceased and the Paranid retracted his head from the saucepit. Dripping beefsauce all the way, he then extended himself mid-counter, pushed Yampa's meatsteak cahoona loaves together, and with a sound similar to blowing one's nose, sprayed the sauce all over them. He then wrapped the loaves in a rimes cloth and put the large cahoona shake next to them.

Yampa looked at his purchase on the counter. "Well, at least you Paranids do one thing right... and just in time for lunch!"


December 3, 2007 - Less Artsy, More Fartsy

"In science one tries to tell people, in such a way as to be understood by everyone, something that no one ever knew before. But in poetry, it's the exact opposite."
- Paul Dirac

I've found myself unable to stop thinking about lexers/parsers lately, which are an important part of language and compiler theory. One of my favorite classes in gradschool was Formal Languages and Automata, which was a pretty good introduction that included this topic. I could never seem to fit Compiler Design into my undergrad curriculum due to scheduling conflicts and always felt I was missing something as a result. However, I'm thinking the theory course should come first, so a lot of it would have lacked perspective anyway. Designing compilers (even the small, fun kind) can be tedium, but one can certainly extract the best part, which is designing (context-free) grammars. Creating a lexer is a fun way to check your formal grammar, since the lexer, properly implemented, is functionally equivalent.

Though there's a lot to say about formal grammars, the most important thing to understand when creating a lexer is to target a particular grammar type, which vary in things like lexeme context-sensitivity. Texts like abstract poems and Myspace comments aren't constrained by any grammar rules whatsoever, so they exist on one end of the context spectrum (i.e. unrestricted). It would be exceedingly difficult to create an algorithm to parse such input meaningfully beyond simple tokenization (a Turing machine will encounter a `decision problem' here, similar to the halting problem). On the opposite end are completely `regular' languages, like regexes. The deterministic/non-deterministic finite automata that generate regexes are typically quite simple by comparison. Most programming languages fall under the category of context-free grammars. Lexical analyzers for context-free grammars are pushdown automata, which as their name suggests are implemented by a stack datastructure.

A typical, enjoyable intro to actual hands-on lexing for a beginner like you is to create your own scanner in, say, ANSI C, which you can use the common lex/flex + yacc combination to convert your EBNF specification into a pushdown (or some other kind of) finite automata. You can then write input files and perform some interesting pattern matching experiments to do things like creating your own macro language.


November 13, 2007 - Destroyer of Worlds

See entry "January 16, 2007 - Kingdom's End" for Chapter 1 of this Amiga fanfic.

KNOWLEDGE ENABLE
----------------

Chapter 2: Destroyer of Worlds

R-Aecantogoen MLD floated effortlessly in an ambient, fluidic continuum. For the last few days, he had been dedicated to the phagocytosis of a particularly tasty particle of biomatter that had drifted into the underside of his biofilm colony. Though he hadn't put much thought into the matter, the protein receptors on his cell membrane knew a perfect meal when they encountered one, and once fully engulfed, it would provide all the nutrients needed for mitosis and give his progeny a good head start at doing the same.

Life itself was another subject matter R-Aecantogoen MLD hadn't analyzed in any great detail. His countless amoeboid siblings and several species of fungi, archaebacteria, and other symbiotic microorganisms had extended their planar realm to the bounds of the known universe (which turned out to be roughly elliptical). Apart from this, existential curiosity was unsurprisingly beyond him - and even the entire colony as a whole, as there were no organisms within it dedicated to such trivial matters. Thus, the ancient cycle of life, death, and rebirth continued unabated, without wants, disappointments, or regrets.

Had he the ability to sense light, an omen of what was to come would he have had, for like a dark cloud foreboding an impending storm, the flickering fluorescent spectrum that had forever illuminated his world from above was fast being eclipsed. With a violent, cosmic crash that shook the entire world and everything within to its core, it vanished completely. Upon this hapless universe, a Nameless Horror ravaged mindlessly and without reason. R-Aecantogoen MLD flailed his tiny flagellum impotently as the obscene, explosive scourge tore his insignificant body from his dying family and liquefied him against a ceramic wall.

Oblivious to this microscopic holocaust, Timothy Rue's face contorted in mortal pain. His eyes were shut tight, cheeks flushed red, and his lips upturned in a rabid snarl. His tormented expression relaxed for a brief moment while he took a deep breath of noxious public restroom fumes and beared down once more, mentally bracing himself for the inevitable agony.

Yet again the bowels of hell opened. Tim's body spasmed chaotically as an unimaginably vile odor began to reach his olfactory sensors. As Tim's mind swam on the brink of unconsciousness, he screamed blasphemous curses upon God, The Architect, Taco Bell, and the Amiga Corporation. His face turned up to the peeling plaster ceiling between him and the night's sky. "all i evar wanted was too help teh user realise teh nine act0in c0nst3nts!!# WHY DANM U WHYYY???!"

Just then, a blinding light filled the restroom and Tim's stall door was flung open by an invisible force. Tim shielded his eyes with his hands and slowly peered out between his fingers, his heart racing. As his eyes slowly adjusted to the brilliant light, a silhouette emerged before him. "teh face of g0d..." Tim whispered in awe, his mouth agape.

"Close enough!" boomed none other than Paul Norman of Cosmi and Aztech Challenge fame. Paul stepped forward and gazed down upon a pantsless Timothy Rue with an expression grimly serious.


October 29, 2007 - Sokath, His Eyes Uncovered

[boyscared] @type fmap fmap
[lambdabot] forall a b (f :: * -> *) (f1 :: * -> *). (Functor f, Functor f1) => f1 (a -> b) -> f1 (f a -> f b)
[boyscared] @type fmap fmap fmap fmap fmap fmap fmap fmap fmap fmap fmap fmap fmap fmap fmap fmap fmap fmap fmap fmap fmap
[lambdabot] forall (f :: * -> *) (f1 :: * -> *) (f2 :: * -> *) a b (f3 :: * -> *). (Functor f, Functor f1, Functor f2, Functor f3) => f (f1 (f2 (a -> b))) -> f (f1 (f2 (f3 a -> f3 b)))
[ivanm] now that's just mean
- #haskell

Cartesian Closed Categories

While studying typed and untyped lambda calculi, Joachim Lambek, originator of Lambek grammars, realized that the sort of category that you can do lambda calculus in are only Cartesian closed categories. In this sense, category theory could possibly grow to subsume lambda calculus at some point, through their applications tends to diverge outside of language theory.

A category is `Cartesian' if it has finite products (a product involving a finite number of terms which, being finite, are always non-converging); binary products and a terminal object. Category closure indicates that for each object C, functor C α has a right adjoint. An adjoint functor in here is the Hom functor, Hom(Γ).

The fact that the Hom functor is introduced by category closure leads to a relationship to set categories. In fact, a category of finite sets is Cartesian. The terminal object is the one-element set, and the product the usual Cartesian one. Hom(Ψ, Ω ) is the finite set of functions from finite sets Ψ and Ω . How this relates to adjoints is simply the morphism that a function A -> Hom(B, Γ) is the same as a function A * B -> Γ.

Natural Transforms in Haskell

Yoneda's Lemma uses the Hom functor to derive a natural transform morphism like so:

Hom(h,-) : Hom(A,-) -> Hom(A',-)

In Haskell, the map function is useful to our discussion here. Examining its type declaration in GHCi gives us:

Prelude> :t map
map :: (a -> b) -> [a] -> [b]

The most accurate explanation of this syntax is from the Haskell manual, which describes map as "return[ing] a list constructed by applying a function (the first argument) to all items in a list passed as the second argument." In simpler terms, map transforms a function a -> b into a function between lists [a] -> [b], where a list creates types (from the type a you get the type [a] of lists of a) but also functions (from a function a -> b, you get a function [a] -> [b]), in a way compatible with function composition. fmap is similar:

Prelude> :t fmap
fmap :: (Functor f) => (a -> b) -> f a -> f b

Basically, for any type (T a), apply functor type (a -> b) to every element a in T.

The Curry-Howard Isomorphism

I'll talk more about the C-H isomorphism some time in the future, but for now the most interesting practical application of it is that you can write types as propositions and programs as proofs (or model theories).

So, let's declare an axiom:

t1 :: forall a b. ((a -> a) -> b -> b)
          -> (a -> (Maybe a))
          -> b
          -> (Maybe b)

We can now programmatically generate theorems based on this type. In this example, I'm using FTshell1.

Using the FixModel, we get:

forall T1,T2 in TYPES. forall R1 in REL(T1,T2), R1 strict and continuous.
  forall T3,T4 in TYPES. forall R2 in REL(T3,T4), R2 strict and continuous.
    forall f1 :: (T1 -> T1) -> T3 -> T3.
      forall g1 :: (T2 -> T2) -> T4 -> T4.
        (forall f3 :: T1 -> T1.
           forall g3 :: T2 -> T2.
             (forall (x4, y4) in R1.
                (f3 x4, g3 y4) in R1)
             ==> forall (x3, y3) in R2.
                   (f1 f3 x3, g1 g3 y3) in R2)
        ==> forall f2 :: T1 -> (Maybe T1).
              forall g2 :: T2 -> (Maybe T2).
                (forall (x2, y2) in R1.
                   (f2 x2, g2 y2) in lift-pointed_{Maybe}(R1))
                ==> forall (x1, y1) in R2.
                      (t1_{T1}_{T3} f1 f2 x1, t1_{T2}_{T4} g1 g2 y1) in
                      lift-pointed_{Maybe}(R2)

The occurring lifted relations can be written as:

lift-pointed_{Maybe}(R1)
= {(_|_, _|_)}
u {(Nothing , Nothing )}
u {(Just x1, Just y1) | (x1, y1) in R1}

lift-pointed_{Maybe}(R2)
= {(_|_, _|_)}
u {(Nothing , Nothing )}
u {(Just x1, Just y1) | (x1, y1) in R2}

Reducing all permissible relation variables to functions yields:

forall T1,T2 in TYPES. forall h1 :: T1 -> T2, h1 strict.
  forall T3,T4 in TYPES. forall h2 :: T3 -> T4, h2 strict.
    forall f1 :: (T1 -> T1) -> T3 -> T3.
      forall g1 :: (T2 -> T2) -> T4 -> T4.
        (forall f3 :: T1 -> T1.
           forall g3 :: T2 -> T2.
             (forall x4 :: T1.
                h1 (f3 x4) = g3 (h1 x4))
             ==> forall x3 :: T3.
                   h2 (f1 f3 x3) = g1 g3 (h2 x3))
        ==> forall f2 :: T1 -> (Maybe T1).
              forall g2 :: T2 -> (Maybe T2).
                (forall x2 :: T1.
                   (f2 x2, g2 (h1 x2)) in lift-pointed_{Maybe}(h1))
                ==> forall x1 :: T3.
                      (t1_{T1}_{T3} f1 f2 x1, t1_{T2}_{T4} g1 g2 (h2 x1))
                      in lift-pointed_{Maybe}(h2)

The occurring lifted relations can be written as:

lift-pointed_{Maybe}(h1)
= {(_|_, _|_)}
u {(Nothing , Nothing )}
u {(Just x1, Just y1) | h1 x1 = y1}

lift-pointed_{Maybe}(h2)
= {(_|_, _|_)}
u {(Nothing , Nothing )}
u {(Just x1, Just y1) | h2 x1 = y1}

Curry-Howard-Lambek

What this has to do with Cartesian closed categories is a three-way isomorphism between types, propositions, and Cartesian closed category objects. More on this later.

1 PL Wadler [1989], "Theorems for free!," in Fourth International Conference on Functional Programming and Computer Architecture, London, MacQueen, ed., Addison Wesley. http://citeseer.ist.psu.edu/wadler89theorems.html


September 17, 2007 - Finis Coronat Opus

I've accepted a job offer as a senior software engineer at a government contractor in the DC Metro area designing/implementing the FBI's latest DNA analysis system. This was the end result of a 3 week job search, which was almost a full-time effort itself. An observation I made during this is that while entry-level positions tend to almost all have at least short technical interviews these days, for mid/senior level positions, everyone seems to be following the Google and MS gamebook: typically 1-2 hr phone technical screenings followed by up to a half day of technical grilling in person. This is in addition to the standard interviewing. Here's a few of the questions I was asked during various technical interviews:

Question: Find the nth (or some specific number) lexicographic permutation of the digits 0, 1, 2, 3, 4, 5, 6, 7, 8, and 9.

Answer: This isn't that tough if you have some time to think about it. Usually, something similar to this is asked to see if you understand recursion. You might not have been exposed to the Exeter algorithm (I hadn't), but it's the most obvious way to approach it and you can probably figure it out in an implementation similar to my solution for the generic case:

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

const int ARR[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};

void printarr(int * a) {
  int i; // C99 mode
  for (i = 0; i < sizeof(a)/sizeof(int); i++) {
    printf("%d", a[i]);
  }
}

void permute(int * a, int p, int k) {
  if (p == k) {
    printarr(a);
  } else {
    int tmp;
    int i;
    for (i = 0; i < sizeof(a)/sizeof(int) - p; i++) {
      tmp = a[i];
      a[i] = a[p];
      a[p] = tmp;
      permute(a, p + 1, k);
      a[p] = a[i];
      a[i] = tmp;
    }
  }
}

int main(int argc, char ** argv) {
  printf("Permutations: \n");
  permute(ARR, 0, atoi(argv[1]));
  return(0);
}

Question: What is BCNF?

Answer: This is an unfair question to non-DBAs, in my opinion. I never met anyone that had all the normalization forms memorized who hadn't just walked out of a final exam. I answered that I didn't recall offhand, but generally understood that NFs are progressively strict and would be happy to go into why you might want to choose higher or lower NFs. But if you happen to be a robot, you can respond with:

A relation schema R is in BCNF with respect to a set F of functional dependencies if for all functional dependencies in F+ of the form a->b, where a and b is a subset of R, at least one of the following holds: 1. a->b is a trivial functional dependency (b is a subset of a), 2. a is a superkey for schema R.

Question: In C#, how do you directly call this native function exported from a C++ DLL?

__declspec(dllexport) int __stdcall f_pK56(BYTE ** m)

Answer: Expect a question similar to this if you're applying for a position in a job where there is incremental migration of a legacy system. Answering it requires knowledge of the COM Interop, DllImport, and the syntax involved.

using System.Runtime.InteropServices;
...
[DllImport("_4x09ij.dll", EntryPoint="f_pK56", ExactSpelling=false,
  CallingConvention=CallingConvention.Cdecl)]
private static extern int f_pK56(byte[,] m);
        

If interviewing for a mid-to-senior level position, there will also be plenty of language-specific feature questions like "are static indexers possible in x" or "what is the syntax of a lexical closure (or anonymous function) in x", where x is a language used there. Really obscure questions of these types are easy to miss, even if you write in that language every day.

Another thing I noticed is that nobody in the software engineering industry really cares how many years you spent in college, as long as it's above 4. They ask about it when you're just out, but that's probably because there is nothing else to talk about. For example, I left grad school 3 credits short of my MS, and I figured I'd at least be asked why, but the subject of education never once came up.


September 4, 2007 - Dulce et Decorum Est

"A hollow voice says "plugh"."
- Colossal Cave Adventure

A new side-project of mine is to refresh my language skills in the main imperative languages (some of which I've thoroughly neglected) by writing a series of smaller games until I get bored.

The first is Commercial Angler, now complete. This was written in C#, using .Net and GDI. The source code is also available if anyone would like look at or compile it. One thing I was too lazy to do properly was use the lock monitors instead of the deprecated ThreadStates - something I may revisit at a later time.


June 23, 2007 - A Principled Approach to Language Theory

"Her name is lambda and she dances on the sand."
- John Meacham

Any good computer scientist or software engineer needs to periodically emerge from the dark cave of whatever problem he is currently working on and appraise the progress made in other sub-fields. Part of any thorough audit would certainly include languages. Throughout the history of programming languages, ideas have consistently floated down from the ivory towers into the real world and this is no less true today. If nothing else, as an engineer gets fluent in a language, he undoubtedly will notice deficiencies in it, and start to write his own extensions to it if possible, or just continually feel constrained if not. When this happens, it's a good time to conduct such an ecological survey of modern language theory.

The State of the Union

The industrial-grade language community is now firmly rooted in the OOP/OOD paradigm. A good illustration of this is that Java has recently surpassed COBOL as the most used language in the world. The exception to this rule is the stored procedure world of relational databases, but we typically see an object-oriented data access layer on top of the transactional interface of n-tier applications. Overall, this transition has certainly been good for the world at large, and any first year CompSci student will gladly recite all the reasons that large-scale procedural applications are unmanageable.

On the other hand, if object-oriented programming lived up to its promises, why are large applications still just as bug-prone as ever, if not more so? It could just be a matter of sloppy work, and that's certainly a large part of it. However, a computer doesn't care what programming language or structural archetype its programs are written in. Programming paradigms exist only to facilitate the management of complex algorithms by humans, who, with their low quantity of bio-RAM, are only capable of conceptualizing small segments at a time. So, the logical question is: why is OOP incapable of full-compartmentalization of program logic despite encapsulation, varyingly-strict inheritance rules, polymorphism, and all the other evangelized features, and why don't mathematicians have this problem?

The main reason I'll address is that procedural execution of OO code is still limited in the scope of which a program can be modularized. A good analogy to this point is a comparison of a system of applications that all modify the same data. The individual algorithms within those applications are isolated from the others, but they still depend on the state of their input (the global dataset) for their results. Furthermore, as in most complex systems that employ this model, there are times when messages1 need to be passed from one application to another, which create a vast web of states2. By scaling this example from applications, to threads perhaps, then down to objects, we can clearly see why large systems tend to have collections of bugs that appear seemingly at random and that are impossible to foresee. The only counter we have to this emergent misbehavior is to put our systems through massive amounts of QA and testing, then trace through the execution stack and see where the state of the program-space conflicts with the logic. This process is then repeated until we (or the marketing droids) conclude the system is at an acceptable level of instability.

Big Muscles. Big, Sweaty, Soapy Muscles.

Now imagine that every time you needed to debug a method, you only had to consider the input parameters and local variables. What if in addition to this all your methods were only a few lines of code long on average and only had static variables and could never create static side effects. The only thing you had to worry about was the return value. In fact, we could equate such a method with a function (the mathematical definition of a function, that is, not `function' in the context of imperative language syntax). What we have here is a recipe for a property of languages called referential transparency.

Discuss OO shortcomings with your average software engineer, and he'll tell you that's just the way computer programs are, and always have been. Explain to him concepts above and he will likely scoff and propel a wad of saliva onto your face, saying that such a language would be impossible to get any real work done in. The reason is that he's locked into the narrow perspective of thinking in terms of his current favorite imperative language, and you've just suggested removing all of its main selling points. Were this the case, such scorn would be well deserved. However, since we're creating a language definition based on lambda calculus, we can combine these integrity restrictions with higher order functions, lexical closures, currying, and lazy evaluation. What we get in the end is a language that allows us to "transcend object-oriented programming"3 - a fully functional programming language, equivalent to a mathematically defined method for solving a problem.

The Road Not Taken

I'll probably discuss the theoretical foundations for these functional transforms in the future, but for now, a comparatively-easy issue can be resolved here: can functional programming one day replace object-oriented programming as the dominant paradigm? If you pass this question around the functional programming community, you will likely get conflicting answers. My thoughts on this are that functional programming shouldn't be defiled with functionally impure methodology. But, if it isn't, then your average Linux cluebie with his "PHP for Dummies" book will never be able to make the mental leap. While mildly unfortunate, it's better than the alternative. Moreover, I'm pessimistic that most programmers at large can make that leap, and point to the massive quantity of programmers who don't even understand proper OOP design as proof. For this and other reasons not mentioned here, I would suggest a divergence of industry programming into two camps, one for those who understand functional programming concepts and one for everyone else. We already have this meritocracy to some extent with commoner-level languages like VB and PHP4, as well as the built-in flexibility in popular languages like C++ and Java to generate poorly structured code.

Besides, the fundamental functional programming concepts are actually far older than the OO design philosophy. I blame its continuing unpopularity on the top-down, constructionist thinking of the more worldly engineers amongst us. These are the types that will write 500 lines of procedural loops to avoid writing a 10 line recursive function. These people may be programmers, but they aren't computer scientists.


1 Historically, the alternative to this is in-channel messaging, where procedural messages are passed in-line with the data. Obviously this creates even worse problems, due to message corruption.
2 Most OSes provide a kernel-level message server for these purposes. Userland applications typically also have access to network protocols, such as various TCP/IP protocols, or standards/APIs that reside on top of them for network applications or provide only local inter-process communication. Examples of these include CORBA, DCE/RPC, and SIG* for *nix process-scheduler messaging.
3 This phrase was (to my knowledge) first used by Paul Graham in the book, ANSI Common Lisp.
4 While it's true that both of these languages have improved a great deal in recent revisions, for various current and historical reasons too numerous to list in a footnote, no self-respecting computer scientist would volunteer to work in such a plebeian milieu. Lacking any responsible influence, their focus has been to maximize popularity. Thus, like a discarded gob of wet feces attracting flies, n00bs conglomerate about them in mindless, mob-like orgies of clueless depravity.


June 17, 2007 - Mobile Functional Programming

"Greenspun's Tenth Rule of Programming: any sufficiently complicated C or Fortran program contains an ad hoc, informally-specified, bug-ridden, slow implementation of half of Common Lisp."
- Phil Greenspun

UPDATE (December 5, 2009): This post is horribly out of date and I consider it highly non-optimal by my current standards. See this page for my latest setup procedure.

Installing a *nix variant on a laptop has always been a pain, unless you're into the latest fad Linux distro. The first thing you might do when in the market is analyze your computer science requirements. For me, it was being able to write Lisp and Haskell code with as few distractions as possible. I settled on a Thinkpad T21 800Mhz 256MB RAM and FreeBSD 6.2. This journal entry will be my Google-indexed public service to T21 BSDers, since none currently exists, though the majority will be applicable most anywhere.

System Setup

First, download the minimal install ISO of FreeBSD 6.2 and install the minimal base system as normal. This whole process only takes about 3 minutes, since you're only installing a few MBs of system binaries and the kernel. You will also want to install the cvsup port as a binary package either from disk or afterwards on your own.

Running in console mode at 80x24 is kind of annoying, especially since you'll next be editing a lot of config files and compiling ports before X11 is up. So append this to rc.conf (you can query vidcontrol -i mode to list available console modes):

font8x8="cp866-8x8"
allscreens_flags="80x60"

Some of the iso0*-8x8 console fonts are okay too.

Now, you'll want to download and install the ports collection, so grab the ports cvsup template from /usr/share/examples/cvsup/ports-supfile and copy it to ~, chmod u+w it, and pull it up in vi. Here, you can add a random cvsup server from the FreeBSD mirrors list. Now run:

# cvsup -L 2 /root/ports-supfile

This will grab the full ports tree. At this point, you're probably asking yourself why you don't install the ports collection from disc, along with X11 and many other apps. The reason is that you'll want the latest version of ghc, and that requires X.org 7.2. Upgrading from X.org 6.x to 7.2 is much more of a pain than just installing 7.2, and you'll still have to compile 7.2 anyway.1

Once this is done, you should install portupgrade from /usr/ports/ports-mgmt and run it:

# /usr/local/sbin/pkgdb -F # check the package registry database
# /usr/local/sbin/portupgrade -ra # update all ports

X11R7

Here you may want to install portaudit or grab the system source and customize your kernel and userland, but if your priority is to get coding as soon as possible, you can just go ahead and make install bash and X.org 7.2 now. You can then follow the normal X setup procedure here, running X -configure. However, this will generate an xorg.conf file that causes your X sessions to hang when you exit them. If you Google this problem, you'll find a lot of people with it, but no solution. After some unpleasant config-monkeying, I figured it out though. Go ahead and generate your xorg.conf, and then open it in vi and make the section changes made in my xorg.conf.

twm

Now you'll want to customize twm into a usable state. Copy over the example .twmrc into your $HOME and edit it to your liking. I've also created a nice .twmrc theme anyone may feel free to use. This includes a "fulldesktop" shell script menu option that will auto-populate the twm workspace with 3 rxvt terminals:

rxvt -g 143x30+0+0 -bg \#323232 -fg \#5FBF77 -fn "-misc-fixed-medium-r-normal-*-*-120-*-*-*-*-*-*" -sr -sl 5000 -ls &
rxvt -g 80x31+0+424 -bg \#323232 -fg \#5FBF77 -fn "-misc-fixed-medium-r-normal-*-*-100-*-*-*-*-*-*" -sr -sl 5000 -ls &
rxvt -g 85x31+504+424 -bg \#323232 -fg \#5FBF77 -fn "-misc-fixed-medium-r-normal-*-*-100-*-*-*-*-*-*" +sb -sl 5000 -ls -e "top" &

The upper rxvt has a slightly larger font (I write most of my code here). The bottom left is used for compiling and viewing manpages/API docs. The bottom right auto-execs top and is used to keep an eye on system info.

Here's a screenshot2:

[twm screenshot]
[1024x768, 43KB]

The Shackles of Imperative Programming

Now you're free to install your Lisp3 and Haskell programming environments. This is a matter of personal taste, but I prefer clisp and ghc, and source editing in vim.

The next step to full functional paradigm immersion is to install xmonad (a tiling window manager). Lispers might appreciate StumpWM, which is written in Lisp. Darcs is the preferred Haskellers' version control system. Another promising project is hashell, which is not quite ready for full time use yet.


1 Another option is to install the ports tree and then cvsup the updates to it, which may save a few minutes of downloading.
2 Don't try this at home warning: In practice, you shouldn't chsh root to a shell like bash, tcsh, or zsh and you definitely shouldn't run X as root.
3 Lisp is arguably a marginally-hybrid functional programming language without complete functional purity/referential transparency, due to its mutable variables, lack of monadic-style isolation of side-effects, and inclusion of iteration operators. A caveat to this statement is that it is implementation-dependant whether iterators (e.g. `dotimes') establish new bindings to variables on each iteration or once at the entry point, then perform assignments on iterations.


April 3, 2007 - Amateur Astronomy Primer

Before you is a picturesque view of the Romulan neutral zone. Along Starfleet Outpost Sector Z-6, the Enterprise D is patrolling the Federation side amid reports of lost contact with several listening posts near the border. While inspecting a suspicious debris field, two Romulan D'deridex-class Warbirds decloak and, without warning, unleash a salvo of disrupter blasts on the Enterprise. The Enterprise initiates evasive maneuvers and counters with a spread of torpedoes. Suddenly, a Borg cube warps in and catches one of the Warbirds in its tractor beam. While its crew is being assimilated, the humans and remaining Romulans temporarily put aside their differences and unite against a common enemy. This show has just gotten started as you yell in from the back porch for your Mom to bring your sweater and some more pretzels.

Welcome to the exciting world of amateur astronomy! If you've ever looked up at the night sky in wonder, been fascinated by celestial phenomena, or just like cataloging and collecting numerical data, then perhaps amateur astronomy is a hobby for you. An amateur astonomy hobby can be educational, entertaining, and as casual or as serious as you please. Who knows, you may even make discoveries or otherwise advance humanity's understanding of the universe!

Getting Started

As an initiate junior astronomer trainee, you'll obviously be eager to jump right in to your new hobby. However, a little preparation can go a long way to maximizing your recreational astronomy experience.

Like any hobby, astronomy has its tools and you should be familiar with their terminology, maintenance, and safe operation. Though not particularly dangerous compared to some hobbies, there are some risks that every amateur astronomer needs to be aware of. For example, while staring directly into the sun with your naked eyeballs can be mildly painful, looking at it with light-concentrating optics without the proper filters can cause permanent retinal damage in addition to intense pain. If staring continues, your eye's lens and cornea will permanently deform, your photo-sensitive optic nerves will die, and the retinal fluid in your eye will heat up. Eventually, your eyeball will explode, leaving a rather gruesome and disfiguring optic cavity exposed to the elements for the rest of your life.

A checklist of the items you will need:

  • One or more eyeballs - These useful organs are capable of detecting light which the brain receives as neuroelectrical impulses and translates into meaningful images.
  • Corrective lenses (optional) - See your local optometrist to determine whether your eyeballs need these to experience the wonders of the universe in all their glory.
  • Chair - You'll likely be outside, possibly in unfurnished areas.
  • Optical/radio telescope or astronomy binoculars - The principle tool of the astronomer.
  • Climate-appropriate attire - Clothing will help your body retain warmth, prevent the soles of your feet from being damaged, and provide some protection against insects or other creatures you might encounter. Wearing at least some minimal clothing is also required by law in most jurisdictions when in public places.
  • Computer or notebook - You'll need some way to record your findings. Note: If you use a notebook, you'll also need some kind of writing implement, such as a pencil, pen, or crayon.
  • Survival gear (optional) - While survival gear is probably unnecessary in your back yard, on a remote mountaintop you may need significant provisions such as rations, temporary shelter, weapons, and bear repellant. Use your best judgment here, but be sure to plan for the worst.

Once you've collected these items, you're ready to get started. Now the only thing missing is a location to setup operations. For those of you living in urban and most suburban areas, there is probably too much light pollution for you to effectively implement any serious astro-gawking. While it may be tempting to destroy nearby light sources with rifles or other projectile weapons, you'll probably be at that all night, and by the next night, half of those light bulbs you shot out will have been replaced anyway. Your best option is to travel to unpopulated areas or areas only inhabited by primitive, pre-industrial tribes. One of the best ways to discover optimal locations in your area is by trading information with other amateur astronomers.

Joining a Club

For the socially-inclined, joining an astronomy club is a great way to pick up trade secrets from your fellow astronomy buffs as well as provide plenty of targets for bragging about your recent discoveries. Most locales in the United States have amateur astronomy clubs which you can probably track down online or by posting on various forums or newsgroups. Clubs are typically happy to recruit new members, so don't be too shy to send them an email professing your love of astronomy and introducing yourself.

Try not to fabricate too many details about yourself during your electronic correspondence with the astronomy club you wish to join. Remember, you'll hopefully be meeting them in real life at some point, where they will discover your true body type, gender, and so forth anyway. When the fateful day arrives, be sure to dress nice (but, don't overdo it - casual attire is fine), have a positive attitude, and take a shower beforehand so as not to omit any offensive odors.

Should your new friends accept you into their astronomical collective, you will now be able to attend meetings, events, astronomy-related political rallies, and telescope parties. Vary your participation based on your personal interest, and remember not to let peer pressure get the best of you. Some social groups like fraternities and secret societies have been known to have humiliating, illegal, and sometimes homosexual initiation rituals, and astronomy clubs are often no different. So, don't be afraid to refuse to do anything that exceeds your comfort level. Amateur astronomy can be just as enjoyable alone, after all.

Start Astronomizing!

You have made all the necessary preparations, located a suitable base of operations, and have your equipment deployed. With bated breath you activate your radio telescope, boot up your UltraSparc 3 Mobile Workstation, and load up your astronomy and mathematics software.

First, input your geographic lambda coordinates into your planetarium software, and make sure your GMT offset is correct. Then, use your eyeballs to scan the night's sky to orient your perspective with its display. In this example, I've entered my coordinates (39° 56' 5.33" N 39.934813° N, 77° 39' 22.87" W -77.656352° W).

[Star Chart]

Now, let's say you've decided to study the M44 Praesepe Open cluster, so look up its astrometric details by its Messier or Herschel object ID (M44/NGC2632):

M44: NGC 2632, GC 1681, h 517, deCh 11, Ha II.1, Ptolemy 449, Ulegh Begh 446, Tycho 576, Hevelius 291, Flamsteed 1213, Bode 20; Mel 88, Cr 189
Right Ascension 08 : 40.1 (h:m)
Declination +19 : 59 (deg:m)
Distance 0.577 (kly)
Visual Brightness 3.7 (mag)
Apparent Dimension 95.0 (arc min)

Had you not already known, you could find out if it was a GLOBL, CL+NB, BRTNB (bright emissions or reflection nebula), or other IAU classifications. Its distance has obviously already long since been determined at 0.577 KLy (which is 177 Pc), but as a useful exercise, let's say you want to confirm this with your own calculations. Input the zenith, azimuth, and declination into your radio telescope's motor controlling software's angle encoder and redirect output to a delimited output file.

Since M44 is a cluster, before calculating its luminosity, plot a Hertzsprung-Russell diagram (H-R diagram) with the data you collected, as shown here. You will now see the relationships between the cluster's absolute magnitude, luminosity, classification, and effective temperature.

[Hertzsprung-Russell diagram]

Thus, (since we know the true luminosities of the main sequence stars from the H-R diagram) we can now calculate the cluster distance using the standard luminosity-distance formula. This method for obtaining the cluster distance is often called "main sequence fitting," as it fits the main sequence on the cluster diagram to the standard main sequence.

[luminosity-distance]

Here, substitute apparent brightness (B), luminosity (L), and solve for dL by applying the inverse square law of brightness (B = L/(4πd2)). If all went well, your calculations will correspond with the official record.

Congratulations! You now have the necessary background to become an amateur astronomer. Obviously, this primer couldn't cover everything, and only provides a small glimpse of the wonders that await you, but you now have the knowledge and confidence to continue your research on your own.


March 8, 2007 - Meditate on the empty list (), and its dual nature nil.

"Computer Science is no more about computers than astronomy is about telescopes."
- EW Dijkstra

I thought having a decent laptop would be more fun than it really is. It's great for dual-boxing at whatever computer you're sitting at though.

But... Ick. I feel like a n00b using Linux on it. I hadn't touched a Linux graphical session in like 5 years, and hadn't used one at home since switching to FreeBSD around 1999. I had no idea how n00bed out the majority of distros have become these days. And don't even get a nigga started about KDE. Distros, like the kernel, are a complete anathema to the Unix philosophy. Before, it was just Emacs like this, but now n00blets can get a whole system full of bloated garbaaj.

I guess I'm just sick of being surrounded by cl00bies everywhere I look anyway. The reason software and OSes suck so much is because they're written by and for n00btards. It'd be fine if they just kept to their own little worlds. Like I could care less if everyone else's system was filled with India-ware IM clients and flash pr0n banners, as long as mine was just the way I wanted. But, the ecology is too interdependent. Applications depend on libs and services, which depend on kernels and protocols, which depend on hardware, which is designed and optimized by applications, all of which is designed by feature-whore marketing fags. These components are more tightly integrated then even this in reality.

I could endlessly write voluminous diatribes about all the stupid and thoughtless design decisions in every category. I would imagine most non-technical people would find how personally I take chronic, system-integration of n00bness to be to be a bit overboard, but that's because they're usually the exact types of people responsible for this, haplessly clicking their way to a gheyer world.

If only I could travel back in time to a few key historical moments with a loaded gun. Were up to me, we'd all be using Lisp machines or at least RISC PCs running microkernels, and all apps would have CLIs and separable frontends. That would just be the beginning though. Basically, the end result would be that it wouldn't take 512MB of RAM and a 2GHz CPU to check your addressbook. And, the world would be a better place.

Though multi-faceted, the main problem as I see it is the propagation and success of bad ideas over good ones. Part of this is to be blamed on us computer scientists. We tell normals that they shouldn't have to learn how to do something to do it. We let them boss us around, demanding more and more features that follow no algorithmic logic and are just a mashing together of vague whims (much like their thoughts, I suspect). First, we need to purge the collaborators from computer science and send them over to IT where they belong. Then, we need to lord our powers over the plebeians, and make them do things our way. To the average end user, software should be obscure, non-intuitive, and take years to master.

So, the moral of the story is I think I'll just kill the Linux install on my laptop and use the space for more games or something. Vista x32 annoys me too, of course. Even Solaris does regularly, but at least I can tell intelligent people worked on certain aspects of them. Cygwin is the first thing any intelligent person installs on Windows anyway, so what does Linux gain the non-n00b besides weeks of IT monkey-work and a bunch of buggy applications?


January 16, 2007 - Kingdom's End

This Amiga fanfic is a prequel that happens between Timothy Rue's first viewing of The Matrix and his trip to the Philadelphia Zoo 4 months later. It's the first installment of a larger series.

KNOWLEDGE ENABLE
----------------

Chapter 1: Kingdom's End

Timothy Rue looked at the public restroom and began to frown. It was out in the middle of a deserted highway in once glorious suburbs of Westchester, PA. These were the homes that once sheltered the creators of the greatest system, the greatest OS, and greatest file manager ever; architects to a modern Tower of Babel and a postmodern utopia. The vacant lots and stripped shells of cars reflected the dream that was lost. "why wuodl soemone maintain a rest st0p out here?" Tim wondered.

"hurry up yuo fag0rt!@11" Skal Loret's angry voice echoed over the infertile eastern Pennsylvanian plains.

Timothy suddenly remembered the fecal matter and gaseous bacterial wastes that had formed a crowded single-file line in his gastrointestinal tract, awaiting a violent turd-birth into a cruel world. Tim thought about how the Taco Bell stop Skal and he had made at the PA Turnpike's Norristown exit was causing his irritable bowel syndrome to act up at yet another inconvenient time. "a butterfly flaps his wings..." Tim whispered into the night.

A fluffy bed of crisp nachos, adorned with hand-diced, sun-ripened tomatoes. A gentle cloud of the finest sour cream. This mouth-watering hors d'oeuvers was followed by a regale of two fine soft tacos, lovingly hand-wrapped in stone-ground tortillas, aged 2-6 weeks to perfection. Nestled inside was lightly spiced and slow-cooked Grade C Argnu beef. This royal banquet was heaven on the Rue palette, but apparently Tim's intestinal flora disagreed.

As Tim rounded the corner of the rest area structure towards the men's room entrance, he glanced back at the Buick to make sure Skal was still seated within. Confirmed, a predatory glint formed in Tim's eyes as he turned back slowly and raised his arms in dramatic rapture. Tim's left arm turned into the D sword and his right into the hammer from Axel's Magic Hammer. He floated into the air in slow motion while the camera panned around his graceful body, his hair suspended upward in mid-flight in an untamed masquerade. Tim projected wind bolts, laser beams, and 4 pixel dashes from his weapon-appendages at various rouge programs and Agent Smith clones. Tim's epic battle was won by the time he reached the door. "i know kung f00," Tim chuckled confidently.

As Tim breached the threshold of the public men's room, his mind, though brilliant, was also innocent to the horrors of the true world. Of course, Tim knew of pain, as any Amiga owner does. Yet few grown men learn that life itself can be horror and suffering. Little could Tim fathom that there was a darkness still lurking in this graveyard - within the very shadow of the Amiga Corporation's cyclopean walls.


November 15, 2006 - Robot need oil.

"MUNUS SIGSIGGA AG BARA YE INNIN AGGISH XASHXUR GISHNU URMA SHAZIGA BARA YE ZIGASHUBBA NA AGSISHAMAZIGA NAMZA YE INNIN DURRE ESH AKKI UGU AGBA ANDAGUB!"
- Al Azif

Allow me to admit upfront that I think Linux, generally speaking, sucks. Note that when I speak of Linux, I'm referring to the kernel, not the OS, which is GNU (I'm not a salivating Richard Stallman fanboi either). There are significant technical shortcomings in the kernel that are causing mayhem in the OS and world at large.

First, a little history lesson is in order. In the late 1980's GNU was working on a free UNIX-like OS to replace the proprietary, big-iron UNIXes which were closed source and often the catalyst for vendor lock-in and considerable agony in systems software development. By 1990, pretty much the entire GNU OS was complete with the exception of a functioning kernel. Work began on a kernel called GNU Hurd, which, employing the many lessons learned in kernel design over the history of computing and the best theories of computer scientists of the day, was to use a microkernel architecture.

Without digressing into too much detail, microkernels can be summed up as system cores where the kernel itself is stripped of all but the most necessary functionality. The rest of what had historically been part of the kernel (the filesystem, network stack, thread manager, etc.) are then moved into userspace. Among the many benefits gained by this approach, foremost to our discussion is interprocess security and code manageability (more on this later).

Circa 1991 Hurd development was slow, but progressing. Meanwhile, Linus Torvalds birthed his crudely created Linux kernel, beating Hurd to production release. After all, kernel size at the time was quite small by modern standards (1.0 only being about 176,000 lines of code) - quite easy to complete when you don't have to worry about adhering to complex design principles.

An unusually honest comment from arch/mips/kernel/sysirix.c:

/* 2,191 lines of complete and utter shit coming up... */

You don't get anything for free, even in software engineering. A quick and dirty hack will get the job done this instant, but without any architectural forethought, you pay for this time saved later when you try to maintain, debug, or expand upon such haphazardly assembled code. Sure, we got our UNIX clone a few years earlier than we would have otherwise, but today the Linux kernel is a 7 million line lumbering beast (often over 300 million lines including drivers, the source of most bugs, which Linux foolishly includes in the kernel as well). No one could begin to contemplate enumerating the possible states of such a bloated mess, and the exponential explosion of closed but unfixed or forever open bugs proves this. Basically, no one has any idea what's going on, even in outline. Features and bugfixes are added wherever seems to make sense at the time, duplicating existing code in complete ignorance and causing other obscure bugs in remote locations. Long since have we passed the point where a little extra thoughtfulness early in the game would have paid off in the long run.

In monolithic kernels (like Linux and Win9x), if any part of the kernel dies, the system kernel panics and the whole precariously balanced shanty comes down. In the microkernel paradigm, a rare bug in the scheduler may crash that user-process, but it can then be restarted and the system re-stabilized. Furthermore, a wayward microkernel process can't corrupt the domain of others, as it exists in userspace and only has the associated limited rights.

The cretinous blob of a kernel that system administrators and software engineers have now inherited is a doomed one. It's a simple matter of logistics and ever-diminishing returns of effort that irreversibly condemn the Linux kernel to a grave it never should have risen from in the first place. It may take 10 years or more, but it will eventually happen, and the longer we wait, the more painful the fateful day will be. Even Microsoft and Apple know this, and have rewritten their kernels from the ground up based on the hybrid kernel architecture (moving the vast majority of system processes out of the kernel.)

I join the true OS visionaries (such as Andrew S. Tanenbaum and Albert Woodhull) in lamenting the sad results of mob mentality and I too cringe every time I see some clueless Linux weenie ejaculating his fanboi drivel in praise of Torvalds and his supposed brilliance. Curse you, Torvalds! Lo, I curse your dull pencil of an intellect from the very core of my being!

Should any breathing human have read this far, I commend your constitution. I promise to limit my nerdlike ramblings as much as possible in the future.


November 14, 2006 - There is no cow level.

"Imagination does not breed insanity. Exactly what does breed insanity is reason. Poets do not go mad... mathematicians go mad."
- G.K. Chesterson

After thinking about it for a few months, I've decided to give the webjournal thing another try. I've written webjournals in times past, yet when reviewing old entries, I would get disgusted with myself and delete them. Since then, I've only posted something nonpersonal once every several months. So, why the change of heart? Well, when I look back on all those un-journaled years, it's hard to recall what I was thinking back then. A course of action for the present needs historical context to be an informed one, after all. Not that this would solve the problem, but putting one's thoughts into words can make the memory more concrete, not to mention be therapeutic.

Having read literally hundreds of webjournals myself, I know the typical pitfalls in their regard. Nothing's worse than reading someone else's daily grocery list or recap of social events where nothing noteworthy occurs. Not that I could do such even if I desired, as a minimal amount of events actually occur in my life. I don't expect anyone to actually read this anyway, as I have nearly zero friends and can't imagine that I will one day get the energy to collect a circle of them. Thus, this journal's intended audience is one Bruce C. Miller, not that I care should another human read anything herein. So without ado, an ellipsis shall now segue us into the needlessly verbose musings of I...

What elevates the contents of one's pulsating conglomeration of neural cells over another? Possibly order, I suspect. After all, entropy is commonplace. There's nothing particularly remarkable about a multitude of atoms that are swirled together in a more or less homogeneous slew. Letters combined to form words and words carefully combined in an orderly fashion to produce meaningful text will keep a reader's attention longer than a random mashing of keys. Simply put, in this context, we can equate entropy with the lack of intelligence.

Likewise, the human brain, or any massively parallel computing device, can be ranked according to order, though quantifying this order is another matter and beyond our immediate scope. Naturally, one may wonder what manner of order is present in one's own mind. An interesting statistic I read on the BBC site the other day indicates that the vast majority (over 85%) of humans consider themselves to be above average intelligence. Obviously, some of these people must be mistaken, since we can't all be above average. Could it be that the ability to evaluate one's own mental capacity is limited by that same mental capacity?

It's easy to imagine being dumber than we already are. A reminder is only as far away as a six-pack or self-inflicted jab to the face. But try to imagine being smarter than you are now. What insights would such lucidity bring? Would uber-self find proto-self's dullard nature revolting?

The reason I bring this up is because I myself question whether my instinctive feeling of mental superiority over the unwashed masses is justified or illusory. Is my anti-social behavior and revulsion at collective activity a personality trait/flaw, or is my inability to relate to others, in truth, their fault?

Imagine a particle physicist stranded on an island of bonobos. This unfortunate person has but two social options. One would be to seek social acceptance and engage in the established social traditions of the local populace (which in the case of bonobos, includes eating lice, rubbing their genitals on trees and each other, etc.) Else, he can attempt to content himself in lonely solitude. One thing's for sure: the primates certainly aren't going to change.


October 18, 2006 - Operation Nubspank

Had I more time, I would like to write more fan fiction. I've written Les Mis and Amiga fanfic, but this is my first stab at Star Trek. It's only the first part though. I may finish it someday if the motivation strikes me.

star trek enterprise - teh planet of teh nubs
*********************************************

chapter 1 teh shuttle bay

walking toward teh shuttle bay are captain archer me and teh doctor phlox0r.. i chekcing out teh phaser gun it seemed to be fully loaded... was preparing for teh worst :(

y0 bm3719 u must understand taht nothing down tehre make any sense for u taht is but for tehm it very clear.. he sez 2 me

i watched up to him he had taht i concerned about cr00 member going down to hostile planet l00k on him face..... :\

ya captain i now i fully briefed on teh subject... i sez to him as doctor phlox t00k a hold of i hand and gave shot of some hsit.. i think 2 meself i dont liek teh way phl0x0rz touches a nigga...... it kinda teh ghey

mmh oh ya taht is better!! :P!! phlox sez holding teh hand looking happy liek he alway did.. waht a fag0rt

what was taht? i asked from him my voice liek all purposely annoyed n hsit.. onli being nice cuz teh caption was here

oh!! nothing u should worry about teh gravity in nubz0r 7 is leik more then one g teh shot i gave u will liek make yuor steps a little more spirngy!!! he sez with taht st00pid grin alll happy and hsit

chapter 2 operatoin nubspank

nubz0r 7 was a fugly ass planet all liek polluted thru and thru... i seen from hundreds miles up thru teh window of a shuttle craft it depressed teh hsit out of a nigga

y0 captain i going down!!! i sez as teh shuttle do down..

i hear u bm3719 porthos wishes u g00d luck!# i heard porthos bark in teh background... id liek to give taht dog a good kick out teh airlock

chapter 3 nubt0wn

now i supposed to meet teh vulcan ambasador aid savek for nubz0r 7 at teh edge of teh town... teh town was liek all blocky and low poly and hsit with what looked liek 16 bit textures with no ansotropic fitlering of course this was liek real life and hsit but tahts how hsitty this place was and u could see teh nubs walking around here and there liek lots of them

i knew tehy lived undeground no one had make a model or texture for centurys.. tehy were perfect targets for teh spawn camping and nade spamming and other nub tactics taht this planet was full of... i slowed down teh speed of teh shuttle and turn on navigationing thrustors

y0 captain i approaching teh rendevounz point but tehre seems to be nuthing but nubs here.. i sez.. watching at below

u should be near now

i keep on scanning teh ppl below with my eyeballs

tehn i saw teh onli one who was not wearing normal clolthes with elfy face and those pointy ears..

w00tage i see teh dewd captain i going down

chapter 4 walk

tehre have are peace negotions go on for teh last 400 years.. sez teh aid who introduce self as tova sez 2 me as we were trying to walk forward in teh crowd of similar faced yellow nubs..

4 hundred years?!@ i sez shaking head at teh impossible job...

yes but it is hopeless tehse ppl have geneticlly adapted to living short lives tehy spawn and teh nare killed quick and have short lifespan but there alway more of then it liek they keep coming back..

do not tehy want to live? i sez being careful not to step to teh substance taht l00ked and smelled liek a p00p...

then i hear explosion in teh distence.. no one seemed to pay any attention to it..

wtf?>?did yuo hear taht? i asked from tova...

for teh 15th tiem tova sez kept a pause and continued today towards a entrance to undeground passages with large signs on teh front of it.. little did a nigga now what this would lead 2

chapter 5 teh vulcan embasy

savek was a vulcan woman in her 20s.. she greeted me with a hug which was strange her being a vulcan and all

welcum to nubz0r 7 mr bm3719 she sez to me

splendid braests!! love tehm i thouht

w00ts up nigga i is pleased to be here.. i told for her......

u could not be no one is.. :( she sez and gazed towards teh ceiling as if she looking to teh stars towards her home planet she obviously not happy here

this is a ugly planet she sez

so liek why u chose to cum here? i sez to her..

well i am expert in peace negotions taht is what i studied all my life but on thihs planet none of taht seem to help.. she sez leading me towards a dining r00m

chapter 6 f00dz0r

teh r00m was gray teh table was gray but teh dishes were made of plat which i figure teh vulcans must have bring of bought from a plat farmer

savek was looking over a plate full of fish at least taht is what it tasted liek but it look liek a grey rectangel..

on tihs planet i coem to understands taht some ppl need tehir emotions.. she lifted her eyes twd me tehse ppl used to no g00d from evil but somehow tehy seem to have lost touch taht knowlegde.. she sez.. i was liek prepering myself for a speech as i was eating teh fish it was g00d once i added some ketchup.. yes i sez back drinking a fruity drink with a little bit of gin in it which reminded a nigga of a drink i used to make back in HS called thugs passion

teh prollem is taht tehy respect tehir fatehrs and they were teh ones who began all this mess.. savek sez as she was cutting thru teh fish into smaller rectangels.. in a perfect world tehy could have liek a sort of server wipe liek u call on earth without history from a clean table but now taht is not possible both teh nubs and non nubs have they history it is habit to tehm and any one who wants to fix maps or expliots tehy get complained about on teh forums.. she sez and eatibng teh fish with her plat fork looking sorta plsed at least for liek a vulcan

so dewd how long u vulcans have been liek aruond here? trying to negotion peace? i asked eating teh last of teh rechtangle and ketchup

from teh beginning she sez....

gheyz0rz :( i sez....


August 28, 2004 - On Fat (or... Satan's Punches Bounce Off)

When assigning ranks for combat of any scale, one should not overlook overweight and obese fighting stock. Fat, with its low mass:volume ratio, absorbs the kinetic energy from physical damage of the blunt force trauma type - that is, damage that is spread out over a wide enough area not to exceed the maximum surface tension of human skin. This damage type can be encountered from attacks that include but are not limited to:

  • Unarmed blows - punches and kicks of all types, elbow smashes, charge attacks, trampling, bodyslams, jump attacks, and head butts.
  • Blunt melee weapons - clubs, quarterstaves, scepters, nightsticks, war hammers with smooth contact faces, and maces and flails of the non-spiked and non-flanged variety.
  • Blunt thrown/launched weapons - throwing hammers, sling bullets, non-lethal firearm projectiles, bolos, rocks, bricks, and so on.

Non-combat related injury resistance bestowed by fat can include damage incurred from vehicle or mount accidents, falling rocks, staircase falls, and certain wild animal attacks (such as from constriction snakes and antlered quadrupeds).

There is also medical evidence to suggest that a thick, unsightly layer of fat can shield ones vital organs from other forms of damage that would normally prove disabling or fatal to those of more reasonable proportions. For example, fire damage, jets of acid, frost burns from supercooled gases, or blasts from plasma weapons will dissipate as they contact solids and in some cases a few extra inches of fat may be just enough to shield the more vital organs, allowing a fat victim of such an attack to survive with only superficial damage.

Of course, there are certainly downsides to deploying fat personnel into a combat situation. The foremost weakness of fat people are edged and projectile weapons dealing out damage of the the piercing and slashing type. Fat is still part of the body which can take damage like any other part and offers no protection from any weapon with parts even remotely wedge-shaped and propelled by any considerable force.

Additionally, with a higher volume and surface area, a fat combatant will be easier for the enemy to hit with any attack. This problem is compounded by the fat person's low agility, making dodging blows or projectiles much harder. Other penalties include low dexterity, making effective attacking and parrying difficult, and a low endurance, meaning fat units will tire more quickly during prolonged engagements.

An effective combat strategy with fat units at hand should only see them deployed them under certain favorable conditions where they are not likely to be exposed to their weaknesses. For example, they can act as a shielding wall, buffering against charging ranks of light infantry wielding blunt melee weapons. While that headlong attack is being delayed, a mobile force of heavy cavalry could be manouvered for a flanking attack to roll up the enemy ranks from the side. Another possibility in the same scenario would be to deploy fat columns on the sides of an expected enemy charge, allowing them to be channeled into a salient, walled by impenetrable fat infantry. The intelligent general's options are limited only by his creativity.

Aspiring military officers may find the following tips of mine helpful:

  • Fat units are best deployed in conflicts against the armies of the past, as any modern army or militia will be armed with projectile weapons, negating the benefits of fat on the battlefield. The only present day exception would be when fighting unarmed civilian mobs, such as in riots or peasant revolts.
  • Armor selection for these units should address their weaknesses. Since the bane of any fat soldier is piercing or slashing damage, armoring them with chainmail, ringmail, or kevlar will effectively turn them into tanks having high immunities to almost any damage likely to be encountered.
  • Given fat peoples' inability to wield weapons requiring a great deal of manual dexterity, they will need to be armed accordingly. Probably an effective balance would be a weapon such as the Roman hasta paired with a gladius, which doesn't require a great deal of skill to effectively parry a charging force with.
  • If you've time traveled back into such an era (14th century or earlier), another good idea will be to arm your fat legions with pikes and deploy them as a phalanx, which are strong against mounted charges and chariots. Though this tactic fell out of favour by Medieval times, it should still be effective until the introduction of firearms, provided you back your fat ranks up with ranged support (i.e. lines of pilums or javelins behind them and lines of archers even further back).
  • Never move your fat ranks once the battle is joined. Their primary purpose is only to act as a buffer or wall to allow your more mobile or ranged units time to do their job or to act as a diverting obstacle to force the enemy into a position that will give you a strategic advantage. They aren't meant to deal decisive blows.
  • If battle turns against you and you are forced to retreat, your obese friends won't be joining you due to their relative immobility. They could act as a sacrificial barrier to delay pursuit, though their lines will likely break when they see their commander abandon them. Later, you can time travel back to the present day America and recruit more, but if this is happening often, you've obviously got bigger problems.

Remember that every battle is won before it is ever fought. The battle itself is just the formality that realizes your superior strategy. Fat is but one tool in the arsenal of a great general.

Any military scientists or historians who feel I've left out anything of significant substance or who would simply like to heap praise upon me for the revolutionary ideas above should feel free to mail me their thoughts. Invitations to lecture at military academies will be considered strictly on a basis of institutional prestige.


November 1, 2003 - Our sugar is yours, friend.

It's about that time of the year to start thinking about what to get bm3719 for xmas, so allow me to enlighten you to the existence of my amazon.com wishlist, which is full of products I simply cannot do without. Large, non-taxable monetary contributions, precious gems, and ink cartridges will also be accepted. You may now be thinking, "At last! The perfect opportunity to practice my culturally-conditioned values of selfless altruism and wealth redistribution along with my normally conflicting natural predisposition for mindless consumerism!" Well, off you go then!


April 15, 2003 - May you walk on warm sands.

Check out my new illustrated adventure. Oh, and happy tax day, kiddies! :\


March 3, 2003 - Frist Psot

Here's some pictures of my Morrowind stronghold in Vivec and some other stuff. The house is from the Morrowind Abodes mod. I pretty much just spend my time in Morrowind there, picking stuff up and setting it back down again in order to make sure it's lined up perfectly. The best way to align weapons, books, and other objects perpendicular to the table or shelf you place it on is to align a horizontal edge (such as the edge of the table) with the bottom of your monitor. You should then press your face against the monitor to see if the pixels are staircasing at all, and if so, gently adjust your perspective. Once you've acquired an aligned viewpoint, use the movement keys, jump button, and menu mode as needed to commence decorating.


Projects

org-mode lists
2014 | older

The Affairs of Men

MV Rockzap

L1J-En

Commercial Angler

quadgt.c


Articles/Essays

Technical Interview Questions

Installing FreeBSD 9.2-REL

The Adventures of Scroto Baggins


Self-related

about bm3719

.emacs file

GitHub repository

w3m bookmarks

images

audio files

macroexpand.com

bm3719@gmail.com