run the fuck away

Haskell - Programming Language

I've been hearing all sorts of stuff about Haskell lately. It's a programming language that has all of my favorite features: it's a functional language, it uses pattern matching on function definitions, and it's got a very sparse, simple, syntax.

While it doesn't have quite the rarefied elegance of LISP, it has one other really fantastic feature: it uses lazy evaluation all the time. In contrast, pretty much every other language uses eager evaluation most of the time.

For example, if I did this in pretty much any language:
x = 2 * 2
It would execute 2 * 2 and put the result into x. This is eager evaluation. In Haskell, on the other hand, it doesn't execute anything, it just creates what's called a "thunk" and says, "hey, if anybody ever wants to know what's in x, tell them it's 2 * 2. I won't figure out what 2 * 2 is until someone actually wants to know what's in x."

This has some weird effects. For one, you never know precisely when a line of Haskell code is going to execute. It doesn't execute code in order, only as needed. Some code will never execute, because Haskell never decides it needs the results of that expression. And because of all that, you can do something in Haskell that you can't do in most languages: create infinitely long data structures.

For example, I could define a function like this in Haskell:
makeList n = n : makeList (n + 1)
*

That defines a function called makeList that takes one parameter (n). After the "=", it explains what it does: take n, and construct a list (:) with the result of calling makeList on the value n + 1. If I invoked makeList 0, it would return a list like this: [0,1,2,3,4...∞].

Obviously, it's impossible to create an infinitely long list, but since Haskell doesn't actually evaluate the list, I can actually call makeList 0 and get back a thunk capable of producing an infinitely long list.

But it gets better- since the function is recursive, Haskell can execute any arbitrary number of recursions without needing to produce the entire list. So, for example, if I wanted to get all of the list after the first element, I could write this statement:
tail (makeList 0)

That returns a list containing all integers from 1 on up. And if I wanted the 1,000,000th number in that list? I could actually grab it, and Haskell would execute up to that number, and no more.

I can understand why mathematicians like this language. It's the first one that has a really good grasp of how to handle infinities.

*This is not the most elegant way to write an infinite list in Haskell. Much more easily, I could write: [1,2,..]. [1,2,..] !! 1000000 would return the 1,000,000 element of the list (the number 1,000,000 in this case).
run the fuck away

Remy & Minna's Guide to Buying a Home, pt. 1

I'm putting Minna's name on this, but she may desire edits. Right now, we're in the process of buying our first home, and we've taken our time doing it. The main reason for taking our time: avoiding the mistakes so endemic to buying a home, and learning about the process. We initially started the homebuying process before leaving Albany, over two years ago. We've been engaged in homebuying ever since.

Homebuying

The Process

Before you can buy a home, you need to understand what you're in for. This is a high-level view of the steps:
  • Save
  • Find a place
  • Put in an offer
  • Get it inspected
  • Get a mortgage
  • Close

Each of these steps is surprisingly complicated. At every step, someone is out to rip you off. At least one someone, probably a bunch. The entire industry of real estate is built around ripping people off. So this homebuying guide is going to focus on avoiding getting ripped off, and avoiding the many pitfalls that most first-time homebuyers fall into. It's only through some good fortune that we've avoided some of them, and some education has helped us avoid the rest.

One note: this assumes that we're talking about conventional, fixed rate mortgages. For some people, an adjustable rate mortgage may make sense, but in most cases, it's a risky gamble. ARMs played a big role in the economic problems we're seeing today, so let's just avoid them and let people who have some experience buying and selling property worry about them. A first time homebuyer should never consider an ARM.
Collapse )

The remaining steps, getting an inspection, getting a mortgage, and closing, are ones I haven't done yet. But, once your offer has been accepted, you have a clock ticking to accomplish two major tasks: get an inspection and apply for a mortgage.

Depending on your local rules, and the stuff you put in your offer, you're going to have about 10-15 days to get these tasks done, so it is important to jump on them quickly. I applied for a mortgage today, but it takes days or weeks to get an approval back (depends on the bank, your credit rating, and how their underwriting process works). But when you apply, you do lock in your interest rate, usually for 60 days. This means, when we're approved, we're locked in for a 4.375% interest rate which is suhweet.

As for the inspection, you do want to find an American Society of Home Inspectors (ASHI) certified inspector, and there's a lot of things to consider in that step.

Everything I've covered so far in this post has been stuff I've actually done. Since I haven't actually gotten approved for a mortgage or had a home inspected, I will refrain from commenting further on them, for now. Expect a part two next week, discussing the inspection, and future installments as I cover the remaining steps.
run the fuck away

Well, that was sudden

Last week, we noticed a listing for a property that was interesting. Our sort of place, from the pictures. Not perfectly located, but well located for us. It's one mile from all the little shops we like, and closer to even some of the other shops we like. Near a park, on a quiet, quiet street.

We saw an open house on Sunday, got a buyer's agent and saw it again on Monday night, went back to her office, wrote up an offer, and submitted it. It was accepted today. So… we're buying a house, in Shadyside. 2BR, 1.5 bath. The first floor is a gorgeous open plan space. Kitchen is brand new; the stove has never even been used. A new patio was installed. Furnace, hot water, all new. The upstairs isn't quite as nice, but certainly nice enough. The washer and dryer are antiques and will need to be replaced.

It's not under contract with us yet; we need the realtor to bring over some paperwork. Tomorrow I'll try and hire an inspector, and then we'll work on getting the mortgage. We're excited, and a little trepidacious.
run the fuck away

Email to Notational Velocity : an Idea Mining Solution

I've discussed Idea Mining before: every idea that pops into your head, jot it down. When you're looking for inspiration, or have some time to develop some idea, poke around in your mine and see what grabs you.

I started using Evernote, which had the advantage of syncing, but recently switched to Notational Velocity. It lacks syncing, but is much more lightweight. When I'm sitting at my computer, the amount of friction in jotting down new notes is minimized. It's a great tool, but by switching to it, I gave up syncing. This means, for example, I can't jot ideas on my phone and have them show up on my computer.

At least, not by default. But I'm not going to be thwarted by such details. So, I sat down, banged out some settings and scripts that let you sync emails in your GMail account to Notational Velocity.

What follows is a high level overview of the steps. It's not hard to do, although it took a little doing to figure out.

You're going to need the following things:
  • OSX Leopard or later
  • Developer tools installed (on your OSX install disk, or downloaded from Apple)
  • Notational Velocity
  • A Gmail account with IMAP enabled

Configure Notational Velocity


Once you have Notational Velocity installed, you're going to need to make one settings change: on the Notes tab of the Preferences window, change "Store and read notes on disk as:" to Plain Text Files. Note also the Folder that you store your notes in on this pane.

Configure Gmail

You need to enable IMAP from the settings pane.

You also need to configure a filter for a pseudo-address. In the filter section of settings, create a filter along these lines:
Matches: to:([your email]+mine@gmail.com)
Do this: Skip Inbox, Apply label "Notes"

This means that, every time you send an email to [your address]+mine@gmail.com, it's actually going to come to your account, but get labeled with Notes (which is a folder in IMAP).

Get SSH Prepared


This step, sadly, does involve a little command-lineage. You can only connect to Gmail's IMAP interface over SSH, and fetchmail needs the certificates where it can find them for this to work.

From /Applications/Utilities fire up Terminal, and type the following:
openssl s_client -connect imap.gmail.com:993 -showcerts

This command will output a big pile of of text, but up at the top, you'll see a large block of output that starts with:
-----BEGIN CERTIFICATE-----
(a big bunch of characters here)
-----END CERTIFICATE-----
(there are two of these blocks, you want the first one, which is actually for imap.gmail.com.

Copy that text (including the BEGIN and END lines) and save it to a file called ~/.ssl/certs/gmailimap.pem. You will likely need to create those directories before you can save it.

You need one more certificate, which you can download from here (where it says "Equifax Secure Certificate Authority (Base-64 encoded X.509"), and save it as ~/.ssl/certs/equifax.pem.

To make these certs usable by fetchmail, you have to run one last command at the command line:
c_rehash ~/.ssl/certs.

This step is a lot easier if you know your way around the command line. The bulk of this SSH section was adapted from here.

Notes.pl

Download this file and save it in ~/Scripts (a directory you'll need to create). You'll also need to make it executable, which involves another command-line bit:
chmod +x ~/Scripts/notes.pl

Open that file in a text editor and change the first two lines per the instructions in the file. Basically, you need to tell it where to find your mail (/var/mail/[your mac username]) and your Notes folder (remember I told you to keep track of that).

This script parses your local Unix mail (deep inside OSX, it has nothing to do with Mail.app or Thunderbird or anything you normally use for email) and turns what's there into notes in Notational Velocity.

We're almost done. The last step is to…

Configure Fetchmail

If you're using Snow Leopard or Leopard, fetchmail is already installed. It's a powerful tool for one task: downloading email from remote systems and putting them on yours. Specifically, into the local Unix mail.

Fetchmail works off of a configuration file. Create a file called ~/.fetchmailrc. In this file, you'll need to paste these settings:
set daemon 1300 #the number is the number of seconds between polling attempts

poll imap.gmail.com proto IMAP port 993 user "youraddress@gmail.com" password "yourpassword" keep folder "Notes" ssl mda "/usr/bin/procmail -d %T" postconnect "~/Scripts/notes.pl && > /var/mail/yourmacusername"

Change "youraddress" and "yourpassword" to your Gmail username and password. Change "yourmacusername" to whatever your username on your Mac is. It may contain spaces, in which case you'll need to escape them like so: /var/mail/Remy\ Porter. Note, that is a "\" followed by a space.

To test this much, send yourself some emails that should be turned into notes (don't forget the +mine!), and then, at the command prompt, simply type the command:
fetchmail.

Once it works, we want to make sure it runs every time you log on, so download this file and put it in your scripts folder. From the command line, type:
chmod +x ~/Scripts/fetchmail.command.

Now, in your OSX System Preferences, go to Accounts, select yours, and add a Login Item that runs fetchmail.command.

TADA!

Using It

Now that you've got it set up, send an email to youraccount+mine@gmail.com. The subject line is the note title, in Notational Velocity, and the body is the content of the note. It'll sync however frequently you want it to, by modifying the indicated line in your .fetchmailrc.

Also, if you want to be able to read notes on your phone, you could use something like Dropbox, which is what I do. Also, the way this works is to append to an existing note. There's no real way to edit.

Warnings

I'm not super sure how this will work if you have multiple accounts on your Mac that you want to use this. You may need to instead configure fetchmail.command to run as a system startup item, and then there may be issues with using "~/Scripts"- you may need to use an absolute path. The Googles are your friend, if that's what you decide you want to do.
viking

Joseph Campbell Killed Genre Fiction

This has been irking me for a long time, but in light of Stross's anti-Star Trek rant and this rant about sexist/feminist influences in SF, I think it's time for me to put this idea down on page.

Joseph Campbell killed genre fiction. Mostly SF, but genre fiction in general. It wasn't his fault. Joseph Campbell did something fairly brilliant: he saw a way to take traditional stories and build them together into a single taxonomy. He found elements that crossed cultures (although it's definitely got a Western bias) and synthesized a sort of "grand unified theory" of mythology and literature.

I'm not here to debate the veracity of this idea. Campbell is right in enough ways that his ideas have explanatory power, even if there are cases that fall outside of his scope.

Sometime between when he had those ideas and today, people blew his findings out of proportion. Repeatedly, I've dealt with people that use Campbell to defend unoriginal literature, claiming he proved that all stories were the same anyway. Those not as well read might not name-drop Campbell, but they like to trot out the "finite number of stories" canard.

It's simply not true. While there are some commonly used story templates, there are as many unique stories as there are ways to arrange words into meaningful sentences.

And this gets us back to the death of genre fiction. Modern science fiction, especially in TV and movies, takes the stance that stories are the same, and are inherently about the characters, and that science fiction or fantasy is just another costume to dress the same story up in. Some might consider this the "literary" tradition. In this approach, all the trappings of the setting exist only to drive up the special effect's budget and provide trailer-fodder, while the story could be told equally well in any other setting. Star Wars is the most obvious example of this: sword and sorcery fare in spaceships. But pretty much every Star Trek episode from some point in the middle of the TNG era also fits the bill.

What you find is that the setting is just props and costumes. For some stories, that's fine, but genre fiction used to be about exploring ideas. Whether it's taking a modern idea and casting it in a different light by analogy or imagining a world drastically altered by some new technology or idea, in classical genre fiction, it was always the ideas that took center stage.

In some cases, notably the likes of Heinlein and Asimov, the result was cardboard characters that generally could be grouped into a handful of niches, few of which ever truly leapt off the page. At the same time, these books are rife with ideas. Different social codes, technologies that reshape society in strange ways.

I'm not trying to say that character driven drama is bad and idea driven drama is good. But the best genre fiction can do both. Sterling's Holy Fire builds a fascinating world, and then shows it to us through the eyes of a newly rejuvenated octogenarian learning about the gerontocracy from the ground up. Vonnegut, of course, was a master of mixing bizarre ideas with likable characters.

My main complaint is that the pendulum has swung away from "big ideas", at least in mainstream sci-fi. It's hardly dead, but sometimes, it feels like somebody slit genre fiction's throat.
IOCCC Original Winner

"Breathtaking" code

Words like "breathtaking", "stunning", "astounding", "amazing", and "incredible" are not positive words. Oh, they're often used in a positive context, but in reality, they only convey a sense of wonder and disbelief. They can be applied to something horrifying just as easily as something delightful.

Such has been my experience over the past few days.

Once upon a time, some fragment of the giant behemoth I work for needed an application to manage some inventory tracking and similar tasks. They found an external contractor that would make it for them. In that era, the app was built in VB6 with an MS Access back end. Horrible, yes, but hey, it was the 90s.

Well, now it's time to upgrade. So they go back to the same contractor. "Hey, we want it to be .NET and use SQL Server. Here's a check."

Well, it wasn't that easy, of course. There are policies. Checkpoints. Oversight. I was part of the oversight, and my job was to get the application through our "gates". Since this was a purchased application, we didn't care if it was terribly well designed, so long as it worked. We weren't going to have to maintain it. So we got some design diagrams from the contractor, sanity checked them, and then called it a day.

More fool I.

Last week, I hear, "Hey, that application- they're not satisfied with the support from the vendor. They want to bring it internal. Hey, Remy, find out what you need to do to make it fit with our standards."

Now, when we develop an app internally, or have a contractor develop an app that we intend to support, the auditing requirements are much stricter. We don't care if an outside vendor has to suffer under horrible support issues, but if we're wasting time on stupid support work, we're unhappy.

So, the first step then, would be to audit the application via a code review. I sat down in a room with three other developers, we pulled up the code, and we started skimming through it.

It was breathtaking.

The first, most glaring thing, was that the actual design and the provided diagram had no relationship to each other. That didn't bode well. And it was all downhill from there. As a sampling of some of the amazing things we saw:
  • One window in the application has all of the business and data access code bundled up in it. It's like they took all the functions and dumped them into a bucket.
  • But not all functions. For example, when that main window wants to log an error message, it calls out to a class called "Utility". When it does that, the Utility class makes a call against the main window. Not only is the code just a disorganized pile in a big bucket, but sometimes the bucket says, "Hey, you gotta go look in another bucket to find that!" and when you do, the other bucket says, "Nope, it's actually back out in the original bucket."
  • All of the database access stuff is hard coded strings. With no SQL injection protections.
  • It stores passwords in plaintext
  • The most stunning thing, however, is what the application does every time it launches. Every time the application launches, it attempts to add columns to a bunch of tables. If those columns already exist, this would cause an error, so it just ignores the errors. Since, once the app has run once, the columns will exist, that means every time a user runs the app, it's trying to add columns to tables for no damn reason.
There's more, but I won't bore you with the details. I wrote a 2,200 word code review document. Normally, these documents follow this form: "File X, Line 128, variable strFoo should be named foo, we don't use Hungarian Notation." For even large projects, they don't tend to get that long, just because they're so terse. This, this was a 5 page essay. I couldn't even call out flaws by line numbers, just because the developer was so clearly incompetent. I've dealt with some bad code in my day, but this is just special.

There's a punchline. They started development using .NET 1.x, and then partway through switched to .NET 2.0. In .NET 1.x, there was no built in FTP functionality. If you wanted to do FTP, you needed to write your own class to do it, or steal some. Microsoft's developer documentation site, MSDN, had an MSFTP code sample, which demonstrated how one could implement their own FTP code. The developer copypasted this- despite the fact that .NET 2.0 had all the functions he needed- and included a class called "MSFTP" in his project.

He couldn't just use the class as it was, however. There were some quirks in our FTP server it didn't handle. And while he was at it, he added a "Dispose" method to handle cleanup, replacing Microsoft's use of the "Finalize" method. This is actually a good .NET technique for technical reasons that are irrelevant here, so he obviously read a book. He didn't read it closely enough, because his Dispose is actually implemented wrong, but that's neither here nor there.

In the comment above his "Dispose" method, he had the gall to include this:
'M$ should have implemented this. Man, this code is sloppy.

When I read that, I just started cracking up.

Until I saw how much my company paid for this. And then I started crying.
Rippy the Razor Animated

Weekend Revolutionaries

The G20 protests haven't gotten too out of hand, but there's a lot of broken windows. Thus far, only 66 arrests and 6 injuries, nothing serious or life threatening from what I can get from the news.

But there was something else I caught on the news that gave me pause: some of these kids out on the streets are under the impression that they're fighting a revolution. They wear masks because the government could "vanish" them away into a prison. The various G-20 protest organizing sites use the terminology "revolution" and "images of revolt".

What an incredible degree of inflated self-importance. These kids show up for their "revolution" for a few days, throw some rocks, pretend that they've done something and taken a significant risk to life and liberty, and then go back to their lives. A few months later, some other protest-worthy event comes up, rinse and repeat.

They're revolutionaries like a guy driving a Prius is an environmentalist. As someone pointed out, Pittsburgh was home to the Homestead labor strikes. Steel workers wanted to unionize and it turned into a gun battle between them and the Pinkertons. Cannons were involved.

That puts a little pepper-gas in perspective, doesn't it?

With all that in mind, I would like to clarify a few things for our visitors:
  • Protesting is awesome. Seriously, enjoy the fact that you live in a country where this can happen. The Beijing G20 Summit in 2005 didn't see these kinds of protests- and we all know why.
  • Permits are awesome too. Chants of "Who's streets? Our streets!" resonate on a deeply emotional level, but the reality is large clusters of people pose a safety risk. So when the police attempt to disperse the crowd, they're not doing it to silence anyone, they're doing it because they are concerned about property damage, injury, and the ability of emergency vehicles to get through. Also, people actually live and work on those streets, and they have just as much right to use them as a protest does. There is no conspiracy to silence you, and requiring permits for large gatherings is not an unreasonable requirement.
  • There is no revolution. Don't kid yourself. If there were a revolution, you wouldn't do this for the few days when G20 was in town, but every day. You wouldn't be facing down pepper-gas and rubber bullets. You'd be dealing with real bullets, made of metal, that would kill and maim you.
  • The idea that the protesters and the police are adversaries is a dangerous and wrong idea. Everyone is responsible for keeping an event like this safe. Only someone deficient in basic humanity would actively wish harm on the protesters or the police.
  • Property damage is not communication. It's shitheaded jackassery. If you want to achieve social change, you need people to build a consensus. Smashing windows isn't a good way to do that.


I could go on, but this covers the key points. As I said, dont be a jackass, and you'll go far.

Also, Pamela's was one of the places that got its windows smashed. That's just not cool man, not cool at all. Pamela's is a Pittsburgh institution and home of the best pancakes in America. Not. Cool.
Tom Baker

I'm Local Famous

Last week, I put together DontBeAG20Jackass.com, and started sharing it with the world. Today, my phone has been ringing left and right as local news agencies call to ask about interviews and the like.

Today, I was on the local TV station, with this interview, and tomorrow I'll be on the associated radio station for a five minute interview in the morning. The local newspaper has a brief blurb about me on their paywalled-site (I'm not sure how they expect to make money, but they're trying).

Based on watching the traffic and such from the site, I'm going to put together an after-action-summary this weekend, because I learned a few things doing this.
run the fuck away

I Still Live: Updates

I am still alive. I have not fallen off the Internet. Since the last time I actually got things together to post, life has continued unabated, and all sorts of fun and interesting things happened, mostly of personal interest.

A few things of a more global interest:
HitTrack, my first iPhone application, got approved and now languishes in the iTunes store. It's nothing spectacular, but it's a workable D&D hit point tracker application, with some nicely done eye candy.

Of more current interest, I assembled Don't be a G20 Jackass, a site that allows people in and around Pittsburgh to sign a polite request that, when the G20 protesters show up next week, that they keep in mind that people actually live here, and would very much like it if the city government doesn't have to pay huge lump sums to clean up and repair damage. I don't think it'll matter, but it was a fun, easy project, and at least grants the illusion of efficacy.

Also, I have a laptop for sale: a Core Duo MacBookPro, 2GB RAM, 2GHz processor, 100GB HDD. Let me know if you're interested.