Tuesday, July 28, 2009

Fuggin Programming



WARNING: STRONG LANGUAGE AND BAD CODE

Hey, Folks! Blago here.
I'm programmin now! What, you didn't know I was doin that? Well, fuck you. I don't have much know-how under my belt yet, but I'm learnin this Scala shit that all the kids seem to be playin with. It's fuckin great. I mean, where else can I make a method name of "?<!#%^&*" and get away with it? The syntax looks just like I talk.

So, what can I code? What I know about is governing, so let me distill this knowledge down to a mini-quick how-to-govern trait:


trait Governance {

type Favor
type Promise
type ShitIWant
type Lobbyist
type Bribe

def solicit(favor: Favor)(lobbyist: Lobbyist): Bribe
def pickBest(bribes: Seq[Bribe]): Bribe
def accept(bribe: Bribe): Promise
def collect(promise: Promise): ShitIWant

def govern(lobbyists: List[Lobbyist], power: Seq[Favor]) = {
for (favor <- power) yield
collect(accept(pickBest(lobbyists.map(solicit(favor)))))
}

}



I make it look easy, huh? Let's break it down now. The world of politics is made up of Lobbyists, Favors, Promises, and Bribes. Oh, and also shit-I-want. The whole point of all the other stuff is to get more shit-I-want.

So, let's look at the govern method. The inputs needed to govern are Lobbyists and Power. The Power gives you a steady stream of Favors that you can do for people, and you can keep that power as long as you *ahem* stay in office. Then, you got the Lobbyists. These fuckin pricks just want to get you to do favors for them for free. Don't be a dumbass, if you got somethin golden, make'em pay up the ass for it.

def govern(lobbyists: List[Lobbyist], power: Seq[Favor]) = { ... }


How can you get the best deal for your Favors? Well, you can't just give it to the first asshole that comes along. You gotta shop it around. Get out your little black book and make some calls. This is illustrated in the solicit method

def solicit(favor: Favor)(lobbyist: Lobbyist): Bribe


So you solicit your current Favor to every fuggin lobbyist you know, and try to get a Bribe from each of them. Then, you can compare them all to get the best one.

def pickBest(bribes: Seq[Bribe]): Bribe


The best Bribe you can then accept, getting a Promise to pay up. You then collect on that Promise to get the ShitIWant, which is usually in the form of small unmarked bills (but not /that/ small).

def accept(bribe: Bribe): Promise
def collect(promise: Promise): ShitIWant


Notice that I'm usin what they call "abstract types" in this trait. That means that a type like "ShitIWant" could really be anything (like money), and needs to be defined by the implementing class.

What? You thought I was gonna implement the class myself and do all the work for you? Why don't you fuck yourself in the ear. Then, when you're done with that, go fuck yourself in the other ear. Then, come back and ask nicely, cause I'm not your fuckin jump-to-it kid.

Oh, all right. Since I'm such a nice guy, here's what a class might look like that extends my Governance trait.


object MyGovernance extends Governance {

type Lobbyist = { def bribe(f: Favor): Bribe }
type Favor = String
case class Bribe(favor: Favor, amount: BigDecimal)
case class Promise(bribe: Bribe)
case class ShitIWant(amount: BigDecimal)

def solicit(favor: Favor)(lobbyist: Lobbyist) = {
lobbyist.bribe(favor)
}

def pickBest(bs: Seq[Bribe]) = {
bs.foldLeft(Bribe("Nothing",0))((a,b)=> if(a.amount >= b.amount) a else b)
}

def accept(bribe: Bribe) = {
Promise(bribe)
}

def collect(promise: Promise) = {
ShitIWant(promise.bribe.amount)
}

}



Notice that all those abstract types used to really be nothin more than names just floatin in space. But I had to tie them to something to implement the class. So, the "Favor" type is now just a type-alias for a String, so it could be something like "Pardon a rich man" or "Direct money to Project X". Other types, like Bribe, I defined directly.

So the jagoff implementing this class only needs to implement the component methods solicit, pickBest, accept, and collect. The basic structure of governing is already defined by me in the govern method, and it doesn't need any improvement. I heard some asshole talking about "idiomatic scala" and he said my code don't have it. Well, I told him that he must be an idiomatic because he didn't get any oxygen to his brain when he was in the womb and his mother was a whore.

But anyway, I can take constructive criticism. And, I started hearin about this shit called "composable functions". What's that? You just take some of these methods and plugem together to make new ones. You don't even need to define arguments and return types and shit like that, although the compiler will make sure you don't do anything stupid. Like, the place where I cherry-pick the best bribe and follow-through on it. In scala, I can define something like this:

def cherryPick = pickBest _ andThen accept andThen collect


Lookit that. Now I got a new method that combines all those other methods together, but I can treat it like a single thing. Also, I can plug in the pieces of this thing in other ways to into other methods and treat them like lego building blocks. I love legos. Then, my govern method becomes more compact.

def govern(lobbyists: List[Lobbyist], power: Seq[Favor]) = {
for (favor <- power) yield
cherryPick(lobbyists.map(solicit(favor)))
}


If you were payin attention, you might be thinking that I could've saved a lot of trouble in defining all of those methods to plug together if I just would've defined the combined function from the start to implement at once:

def cherryPick(bribes: Seq[Bribe]): ShitIWant


Then, you can implement it all at once and skip those pesky pickBest, accept, and collect methods:

def cherryPick(bribes: Seq[Bribe]): ShitIWant = {
val amt = bribes
.foldLeft(Bribe("Nothing",0))((a,b)=> if(a.amount >= b.amount) a else b)
.amount
ShitIWant(amt)
}


Whoah... slow down there, brother. I could have also just stubbed out the "govern" method and made you implement the whole fuckin thing. But, I'm tryin to supply a structure for you to base you implementation on. If you want to learn how to govern you better shuddup and pay attention. Not just the structure of the code I'm givin you is important, but also the semantics of the code. I took painstaking effort to name the types and variables so that you can understand the subtle meanings of all the players in this dance.

As a side note, the type names can (and should) be changed to reflect new meanings and realities. They are a communication tools just like code comments. But, also like comments, they can lie to you if you're lazy and let your code drift. For example, I recently found out that Lobbyists are not the only entity from which I can extract bribes. So, I should have refactored my code to include some super or genric type that includes Congressmen. So, if type/method/variable names are like comments and can lie to you. Maybe we should all just be using one-character variable names to at least limit the damage they can do. Then, the structure of the code pops out at you, unhindered by the story told by the names.

This guy obviously has mental problems:
After you have spent a certain amount of time in the compiler, you will
come to feel angry resentment at every comment you encounter, because it
might be trying to mislead you! I have modified my editor not to show me
any comments in scala sources so they cannot tempt me with their siren
songs of reasons and explanations. AH THE LIMITLESS SERENITY


Michael Feathers is all over this topic today on Tweeter. See if you can pick out the posts that matter from all of the other crap on there. I swear, people join Twatter because they think other people like the smell of their farts, then they stay because they start to like the fart-smell themselves. Fuggidaboutit.

The trade-off between names and structure appears to be constrained by ease-of-comprehension on one end and the need for reuse/composability on the other. Feathers considers that there are certain classes of code that are better understood in terms of their structure, effectively bridging the comprehension/composability divide.

Ha! He'll never get anything done if he keeps jackin around thinkin useless thoughts like that. Meanwhile, I just automated the entire process of executive governing. I'm ready for my next challenge to help the world... I think I'll make a web-framework in Java. That'll be fuckin Golden!

No comments: