18:38 CST | category / entries / tweets
permanent link | comments?
18:38 CST | category / entries / tweets
permanent link | comments?
14:25 CST | category / entries / tweets
permanent link | comments?
Old co-worker Stephen Crowley posted a link to Destiny’s Child on ukulele. I’ve got a couple good responses that are too long for tweeetr.
Here it goes - While my Guitar Gently Weeps
And here’s a snippet of a story I randomly heard on NPR (story with audio, transcript) on the way going somewhere. Sarah Jarosz normally sings bluegrass, but being a teen she also rocks out with a Gnarls Barkley’s “Crazy” Cover (mp3 link) Luckily I was alone in the car so I could rock out with them. Technically a mandolin not a ukulele, but the girl has an awesome voice and I love hearing famous songs with acoustic interpretations, which of course brings up the Obadiah Parker / Hey Ya Cover.
Why do I love the weird stuff?
09:14 CST | category / entries
permanent link | comments?
11:02 CST | category / entries / tweets
permanent link | comments?
Getting Started with Functional-Style Programming
I was talking with my friend Chris after watching high-school football, and the topic of functional programming came up. If you’re just getting started with functional-style programming there are a few easy wins right off the bat you can start using.
State is Evil. State is the Devil. State is the destroyer of sleep and deadlines. If you only try one thing, recognize this fact.
It is a necessary evil- you won’t get very far if you don’t keep state somewhere, but within your domain objects and calculations you want to be very conservative about where and how you keep state.
Unnecessary state is evil primarily due to how it introduces order dependency.
$obj->load(); $obj->frib_frobber(); $obj->froob_flanger(); $obj->bingo_bongo();
What happens if you change the order of those operations? Can you bingo the bongo before froobing the flanger?
At first keeping state in your object ~feels~ helpful by reducing parameter lists but it quickly leads to bugs and is a maintenance nightmare. Let’s pretend that yes, indeed, you have to froob the flanger before bingo-ing the bongo.
In a functional style, you state your order dependence (state dependence / data dependence) via the function call stack.
$obj->load(); $obj->frib_frobber(); $obj->bingo_bongo( $obj->froob_flanger() );
Now, ask the same question again. Can you bingo the bongo before froobing the flanger? Not unless you can get the froob data from somewhere else. GASP! This leads directly to the next point.
$obj->bingo_bongo( $obj->froob_flanger() );
Before, the object contained state that was modified by different functions. Now, you have all the same code in that object but you’ve explicitly declared that bongos depend on froobing.
This makes maintenance easier as well as making things more modular. All of a sudden you can get that froobing data from some other place because bingo_bongo doesn’t care where it comes from, only that you pass it what it needs.
The generic term to look up here is “dependency injection” or “DI” as an architectural decision. For now I’ll gloss over it and just suggest that you should understand what it offers and consider how it might be applicable to your use cases.
Yes, idempotent. The $0.10 word that basically means “you can test it”.
If you know that the output of a particular function depends only on the input that you give it, it becomes trivial to test. If you know that function doesn’t modify any state (indeed - if it can’t modify state) then you can call that function as many times as you want and not have to worry.
Let’s go back to our example above:
$result = $obj->froob_flanger();
This function doesn’t take any arguments. If it didn’t depend upon state, it would always return the same value, meaning you could just replace it with a constant. Obviously it’s doing something or depending on something but:
WHAT STATE DOES IT DEPEND ON? WHAT STATE DOES IT MODIFY?
Right now, it’s impossible to tell.
Let’s pretend it depends on a username and password:
$result = $obj->froob_flanger( $username, $password );
Aha! Now we can test it. Now it’s idempotent (output only depends on it’s inputs - it can be run as many times as you’d like with the same effect).
Does the function verify the user is logged in? Does it check password strength? Does it change the user’s password?
Well, if you’re truly trying to be functional, you’d say it can’t depend on accessing the database because you’re not specifying it as a depedency in the argument list:
$result = $obj->froob_flanger( $db, $username, $password );
But in any case it is infinitely easier to test what the function does and that it works properly when you can simply change the arguments and call it a few times in a row. The setup / teardown requirements for testing are simpler and easier when you write your programs in a functional style.
On a final note, I would suggest some simple naming conventions to make it more clear what’s going on in your program.
“do”, “get”, and “calc”
You cannot avoid modifying state, but you should always defer to the caller, let the caller choose to modify state or not, not you. This basically means your libraries get split up into two types of functions - those that modify state, and those that do not.
Prefix the ones that modify state with do and use some other verb that means “just returning what you told me to”.
Before:
$obj->load(); $obj->frib_frobber(); $obj->froob_flanger(); $obj->bingo_bongo();
After:
$obj->do_load(); $obj->do_frib_frobber(); $obj->do_bingo_bongo( $obj->get_froob_flanger( $username, $password ) );
Now, you can see the structure and dependencies in the code immediately.
You know there are three discrete actions which most likely have an ordering dependency.
You know that froob_flanger depends on $username and $password.
You can validate that get_froob_flanger works right in all your major test cases simply by calling it a few times with your requirements.
You can switch out what do_bingo_bongo operates on by simply calling it with a different function.
You can validate that do_bingo_bongo does the right thing simply by calling it with static data. There’s no need to set up a whole request chain, just validate that do_bingo_bongo( 1 ); do_bingo_bongo( 2 ); do_bingo_bongo( 3 ); all do what you want.
And you can sleep a bit better know your code is testable (hopefully tested!), and easier to maintain.
20:07 CST | category / entries
permanent link | comments?
18:16 CST | category / entries / tweets
permanent link | comments?
Now you’re speaking my language…
At Google, we generally program in three languages: C++, Java, and Python. None of them are functional languages: are all state-heavy, imperative, object-oriented languages. But the more I’ve read and written code in this code-base, the more I’ve found that functional code is the best way of building large things.
[link]
Nice little article about the benefits of functional-style programming.
17:17 CST | category / entries / links
permanent link | comments?
11:41 CST | category / entries / tweets
permanent link | comments?
11:42 CST | category / entries / tweets
permanent link | comments?
18:26 CST | category / entries / tweets
permanent link | comments?
23:00 CST | category / entries / tweets
permanent link | comments?
In the world of Facebook development with Python there are two major choices. minifb and pyfacebook. They both suck in their own unique and special ways.
First off, developing and integrating with Facebook itself is hard enough. Hire some tech-writers, guys. Actually, hire more of them and delete your wiki. It is far too cluttered and disorganized to be doing much good.
Second of all, if you’re not in PHP, you’re already a half-step behind. It looks like the PHP libraries + integration are pretty good, well tested, well documented, etc.
Between minifb.py and pyfacebook you have a stark gap.
The Facebook API makes sense (it really does, mostly). facebook.bar.doBlap() is what you want to call, you do some sig=, verify=, blah blah, and you’re good to go.
MiniFB gives you just enough to do that. It’ll sign requests and verify signatures and that’s about it. Everything looks like: call( “foo.bar.doBlap”, blah, blah );
PyFacebook is more along the lines of the facebook-client.php library. It’ll import a bunch of calls into the python namespace, so you can do: facebook.foo.bar.doBlap( blah, blah ); In addition, it does all the right collapsing of GET/POST/COOKIES and generally makes it more comfortable to work with Facebook.
This is great in theory, but again there is a huge documentation gap with far too much “magic” that goes unexeplained. Facebook’s documentation is self-referential and assumes you intimately know every aspect of how Facebook works already. Add to it that PyFacebook spends about 99% of the time on how to wire it up to Django and you have a recipe for fail.
I want MiniFB++, which is conceptually as simple as PyFacebook, but doesn’t suck so hard in the documentation aspect. I cannot over-emphasize the craptitude that is the documentation of pyfacebook and facebook in general. Amplified by the fact that every n00b is tweeting in the echo chamber about facebook facebook python pyfacebook, twteeeeeT! and nobody’s actually saying anything.
All apologies to the PyFacebook peep(s?) … I will be more than happy to write my own series of tutorials on things if I can ever get up the learning curve.
My recipe to fix things:
Back to “work”.
20:35 CST | category / entries
permanent link | comments?
14:04 CST | category / entries / tweets
permanent link | comments?
08:08 CST | category / entries / tweets
permanent link | comments?
16:58 CST | category / entries / tweets
permanent link | comments?
13:31 CST | category / entries / tweets
permanent link | comments?
Reposting this into my new “recipes” section because it’s so good. Good fillings I’ve tried are with Nutella, Chopped Ham and Cheese, caramel syrup / chocolate syrup (both can be a bit runny), and of course the old standbys of jam/jelly, etc.
INGREDIENTS
DIRECTIONS
I’m gonna state that adding the butter last is a good idea (otherwise the flour wants to stick to it and get a bit clumpy), but that you might try the wet-first, then dry method.
These crepes are neutral in flavor. It sounds interesting to do a bit of savory crepes for maybe chicken or potatoes. I’d hesitate to make them sweeter if you’re doing a sweet filling because you really do get enough sweetness from the ingredients and the neutral flavor of the crepe keeps your teeth from falling out.
Bon Appétit!
15:11 CST | category / entries / recipes
permanent link | comments?
15:07 CST | category / entries / tweets
permanent link | comments?
This is a shorthand recipe for making “authentic” tomatillo salsa, so the actual measurements are yours to make the salsa your own. I’ll try to give some basic guidelines.
Choose Carefully: Boil Tomatillos (salsa for enchiladas) or Fry Tomatillos (salsa for dipping).
No matter what you did above:
Blend the tomatillos (strain out most of the water if you boiled them) in a blender. Optionally throw in some cilantro during blending (probably a bit less than 1/4 cup of just the leafy parts). For extreme bonus mexicano points you can use a molcajete, but it will take quite a bit longer and you might end up with a bit of grit depending on how well-seasoned your molcajete is.
In the saucepan again, fry up some oil + chopped onion bits on high heat until the onion bits are transparent. Add in blended tomatillos. Reduce and check taste. At this point (while reducing) slowly add powdered chicken boullion or stock until you avoid too much bitterness with the flavors. You don’t want it too bitter or too salty.
Use for enchiladas, chilaquiles, spicing up rice / chicken … basically put it on anything you see at a mexican restaurant. :^)
18:17 CST | category / entries / recipes
permanent link | comments?
14:41 CST | category / entries / tweets
permanent link | comments?
Watching this video right now, it’s a great useful overview of how YUI 3 works. Very accessible even if you’re not a YUI/JQuery/Dojo/MooTools whiz.
In some cases I don’t like videos b/c it’s easier to just read and absorb the information. When you’re new to the topic, these types of well-produced training videos are great because they go at the right pace and are focused on communicating more than on documenting.
11:39 CST | category / entries
permanent link | comments?
09:22 CST | category / entries / tweets
permanent link | comments?
This is awesome. tl;dr: Grumpy old man calls cops “too much” on single parent + kid across the street. Cop and dispatchers get drunk, egg his house, and presumably drive away hitting fire hydrants and telephone poles in their daring escape. Chief steps in like a boss and terminates those involved.
Yes, I feel sorry for all of the individuals involved. But I stand firmly on the side of law and order in this case, and that probably means “Don’t throw eggs at peoples houses.”
I am a big fan of law enforcement even when I am on the wrong side of it. That’s why I pay my speeding tickets — dur, I was probably speeding. You treat me with respect and I treat you with respect. But with great power comes great responsibility. If I were to egg my coworker’s house, I’d probably get a stern talking to and would probably not get fired. But if you’re a cop with guns and authority and all that comes with it, then you shouldn’t be in the business of retaliating against your customers.
I found this story through the DMN’s Carrollton blog, and you can read the police chief’s full statement on the matter as well, or Steve Blow’s column on the whole thing.
Again, my sincere condolences to all the individuals involved, but the action that the organization took has made me trust the Carrollton Police Department a lot more as a whole. Having a bright line against abuses of power is what will hopefully prevent future abuses and just plain stupidity.
19:55 CST | category / entries
permanent link | comments?
Advice to Future Travelers to Paris
Bety and I just got back from Paris, spending ~5 days there. Our feet are sore, our sleep schedule is jacked, but our photos are imported. Some advice for those who are thinking of going.
Location location location, but not the location that you think. Everything in Paris is done on foot, on bike, or on the Metro. To easily rent the bikes in the city supposedly you need a credit card with the little chip in it, and you’ll probably be doing most of your stuff by foot anyway. As a matter of fact we never used a taxi the whole time we were there, VERY cool!
To minimize the time you’re spending on foot getting from place to place, get a “tourist map” that includes the subway (metro) lines as well as the famous landmarks (Louvre, Eiffel Tower, Notre Dame, etc). Then figure out how to minimize the following things in this order:
Basically if you can get a hotel within a block of a metro station and you can cross the entire city with that metro line (examples: Line 6 Nation/Etoile, Line 14 Madeline/Bibliotheque, and Train line “B” North-South) … it doesn’t matter too much how far away you are away from the city center. You get on the metro (which shows up in ~2 minutes), you ride 5 stops (which takes ~5 minutes), switch trains once (~2 more minutes) and get off at the next stop.
Contrast that with staying “too far” from a metro line, or staying near a “wrong” metro line… you’ll end up walking 5-10 minutes to get to a metro line, and then have an extra 1-2 transfers at the start and end of your day… it gets to be a beating.
We ended up splitting our hotel stays between two areas of the city, the 15th (Southeast) and the 5th (very central… just south of Notre Dame). The two areas had very different feels, especially after dark.
The first half of our trip we were on the southeast side of the city between Place d’Italie, Chevaleret and Campo Formio, which turned out to be a surprisingly decent location considering it was selected almost at random because our first hotel option had sold out.
The second hotel was right near Cluny La Sorbonne, which we selected to be closer to the action (after we’d figured out what really mattered w.r.t. location in the city) and more importantly to be super-convenient when heading to the airport on our return (no transfers, just schlep the bags two blocks and get on the train going north).
The nightlife near the second hotel was palpably different … much more activity after 9-10pm, lots of little shops, restaurants, bars, night-spots. It was in/near the latin quarter which actually is an interesting, vibrant place, especially contrasting with it being so close to the Notre Dame cathedral and right on the banks of the Seine. Be sure to take into consideration that Paris is a city just like any other, with the “fun” districts and the “damn, I have to wake up at 7am tomorrow” districts.
It was our first time in Europe and we ended up splitting time between the obvious touristy things and wandering around the city. The only thing we regretted doing was visiting the Pantheon… it had nice examples of architecture, paintings and a reproduction of Focaults Pendulum in the original location where Focault demonstrated it, but it basically felt like a government building… a little too clean, a little to modern, and majority of things to see were just concrete coffins. It did, however, give me a much greater appreciation for French contributions to what we take for granted.
France has kindof a nationalistic “Science, it works, bitches!” bent. We didn’t get a chance to go into the Charles Darwin Museum (it was closed on Monday or Tuesday, like many of Paris’s museums), but did see their dinosaur carousels and the gardens surrounding the museum. In the pantheon, there are a variety of signs pointing out the accomplishments of people buried there, Louis Braille, Carnot (of the Carnot cycle, I believe), Victor Hugo, Alexandre Dumas… lots of culturally and scientifically relevant people, not to mention all the history of art (Monet, Van Gogh, etc.) that have a connection to France. In that regard, I was glad to have visited the pantheon, but you’re better of reading up on French history and taking some pictures of the outside.
If you’re looking for some recommendations for books by french authors, I think all my favorite classics were written by French people. The Three Musketeers is a great action book, Les Miserables is fantastic story and musical (but get the abridged version, it cuts out all the boring politics), the Phantom of the Opera was a good story and very famous musical. All of them really deserve your attention if you haven’t read them, and based on this trip I think I’m going to pick up The Hunchback of Notre Dame to read - hopefully it’ll be as good as the other french authors I’ve read and it will have a lot more context after having seen the church with all its gargoyles and architecture.
Language. If you speak another language already (ie: Spanish, Italian) you won’t have too much problem getting around. Definitely do the Pimsleur French audio lessons, I got to lesson 4-5 and that combined with knowing cooking terms, paying attention, and having learned a language before (ie: using context clues to translate items from restaurant menus), it meant that I could fumble around and ask for directions and use the automated ticket machines.
If you don’t speak another language, definitely do the Pimsleur stuff and get some kind of laminated top 100 words for tourists card. A lot of people speak some level of english, but you just want to be really polite and not at all bossy. Younger people seem to be more likely to know some english than older people, but I was really surprised by the amount of tri- and quatro-lingual people we met. One guy in a chocolate shop spoke French, English, German, Spanish, and half the time the asian people were speaking French, the white people were speaking German and the French people were speaking Spanish. You just never know what languages people speak, and usually what other language they happen to speak too.
We would have liked to spend some more time in the surrounding areas / cities, our Versailles trip was quite a bit of fun (took probably half a day to do the palace and everything, got back to Paris around 8-9pm). Versailles itself was impressive again because of the history of France and the sheer magnitude of the palace and surrounding gardens.
Remember that Paris itself is pretty small (relatively speaking) but much more densly packed. The whole city-center is about the size of Carrollton actually, so on the map if something looks like it’s a few streets over, it’s literally within walking distance and the climate (even in the “hot” summer) is amenable to walking if you’re from Texas.
Speaking of summer, don’t forget about France’s national “vacation month” which was exactly when we showed up (mid-to-late August). The French get six weeks vacation and they all go skiing or motor scootering or something during August, at least the Parisians. So expect that you’ll find more tourists and less natives, combined with overall less availability of local shops and restaurants. We missed out on a few of the music shops near the Metro Gare St. Lazare on street Rue de Rome because of these holidays, but other than that it didn’t affect us too much. We were more interested in the touristy things than anything else, but if you want to experience Paris in full-swing, you might avoid the end of summer.
Last two things - Take a look at WikiTravel for a pretty good overview Paris guide, and also consider travel to Mexico City. Mexico’s capitol shares a lot with Paris in that it’s a major world city, is very urban, has lots of culture, a robust public transportation system, signs in foreign languages, a plethora of local shops, dirty streets, foreign currency… the list goes on, and the flight might be a lot shorter. I got the impression that Paris was safer overall, but staying in “the right areas” of Mexico City is pretty safe as well although crime of opportunity does seem to have more “opportunity” to occur in Mexico City. As always, be safe and don’t be a target wherever you go.
Visiting Paris has definitely got me looking forward to our next opportunity to travel somewhere new and exciting…
23:02 CST | category / entries
permanent link | comments?
21:44 CST | category / entries / tweets
permanent link | comments?
Surprisingly quick. It took me longer to blur out my email subject lines than it did for YMail to mark 8000+ mail messages as read (in a folder of 11k+).
You could say “it should have just done it in the background” but this thing worked better than any of my corporate email clients have with that amount of mail (I’m glaring at you Entourage).
New YMail is looking pretty good, and the new Yahoo! homepage is incredible. Definitely check it out if you’re not on the new mail version yet.
15:16 CST | category / entries
permanent link | comments?
16:32 CST | category / entries / tweets
permanent link | comments?
08:38 CST | category / entries / tweets
permanent link | comments?
Down with Twitter, Up with Bash
It is the act of normalizing my activity streams that has exposed the fraud that is Twitter.
Don’t be fooled by my blog’s grey and white color scheme, it is actually on the cutting edge of web 2.whatever we’re on right now.
You see, I’ve been posting information to my blog for a little over four years now (slowly but surely), and as I’ve found good sources of ancillary RSS / syndictable content (such is video postings, public bookmarks), I’ve done my best to pull them in so you can get a flavor of who I am. Unfortunately Facebook has beaten the pants off me in regards to the quality of implementation.
They accept multiple RSS input sources and aggregate them into one user-timeline, as well as handling the differentiation between public, private, and protected data, and the associated “social network” aspects of things. In addition to this they do photo hosting, comments, invites, etc., etc., and more etc.
But back to Twitter, I originally wanted to bring my “tweets” into my blog … people at work have started using it, their content is alternately relevant or funny, and thus worth my while, so I check it fairly regularly and have been posting my own little snippets as I run accross them.
Writing thoughtful blog posts is hard, writing witty one-liners is correspondingly easier and would make for a nice snack between my longer blog posts. By putting mah tweets in mah blawg, it made me realize that really they were just short, one-line blog posts, and that the value add of twitter was “Hey this might be relevant or might not be, but you can see who is subscribed to your tweeting, and btw, it’s guaranteed to be short”.
Twitter does a bunch of stuff ~socially~ that is interesting:
…but fundamentally RSS is public email, your social web is public address book, and “direct messages” are email-writ-small.
And when I say “public” I really mean “public, private, protected, or segregated into groups”. So any VC people who are looking for the next big thing, here is your recipe for success:
Facebook is on the right track … if they could snarf up Twitter and Linked-In, they’d almost have a lock on all social networks. If they added in some extra sending / receiving options and tied in a bit better with physical devices in the real world (ie: calendaring + invites + twittering) they’d be totally awesome except for the fact that everything is hidden behind requiring a Facebook login.
The funny thing is that I can envision a future where “Facebook” replaces email, but currently Facebook requires an email address to log in.
And my bash tweet?
“Use comments with bash commands so you can edit them in your history: echo !123 or #<paste><enter> will display and edit, but not execute”
Remind me again What do I need twitter for?
22:31 CST | category / entries
permanent link | comments?
11:13 CST | category / entries / tweets
permanent link | comments?
11:08 CST | category / entries / tweets
permanent link | comments?
Actually, I lie. It’s not Deep Space Nine (DS9), but instead The Original Series (TOS), but I’m taking some poetic liberty here on account of its awesomeness.
Star Trek + NIN Closer == Awesome.
In other news, I’m attempting to aggregate my social media again. Hopefully I’ll get my tweets, my delicious links, other RSS, etc. Oh, the perils of not giving in and just using facebook.
17:27 CST | category / entries / links
permanent link | comments?
10:11 CST | category / entries / tweets
permanent link | comments?
08:03 CST | category / entries / tweets
permanent link | comments?
10:51 CST | category / entries / tweets
permanent link | comments?
12:22 CST | category / entries / tweets
permanent link | comments?
09:35 CST | category / entries / tweets
permanent link | comments?
bash Pro-TipTM: Select a Random Line
I can’t count the number of times I’ve wanted a simple random selection from a file. I always get confused by trips down $RANDOM and perl-isms, but no more! I present to you:
... | sort -R | head -1
sort -R — sort by random hash of keys.
Developers of sort, you are mad geniuses for hiding “put things in correct order” and “put things in totally incorrect order” in the same place.
16:09 CST | category / entries
permanent link | comments?
11:07 CST | category / entries / tweets
permanent link | comments?
15:34 CST | category / entries / tweets
permanent link | comments?
22:48 CST | category / entries / tweets
permanent link | comments?
The Development of Spaces and Tabs
In the beginning a developer uses tabs in GWBasic and cries because they take up so much space.
Very soon after the developer uses spaces and engages in vigorous debate with his peers about whether to use 2, 3, or 4 them.
Then our developer realizes: “Hark! I shall use tabs for indentation and each shall be able to set the amount of space they consume to their liking. Verily the inventors of tabs were wise beyond their years.”
Our developer is a tireless advocate for tabs for they are flexible, lead to smaller files, and may be customized to your liking.
But there are still those who choose to use spaces, and yet worse, intermingle spaces and tabs! Although they do this unknowningly, it is a tiresome chore to continually clean the droolstains of others.
Finally, the developer reaches enlightenment and decrees: “There will be no more tabs in files on disk! No more will I clean the drool from other peoples chins, for those that insist on banging the spacebar and backspace key four times more than necessary shall be happy with their spaces and so shall I with my set tabstop=4; set softtabstop=4; set shiftwidth=4; set expandtab; or similar settings for the editor at hand, at least until elastic tabstops become standard.”
Spaces still suck, but not as much as this mess (pulled from fairly popular open source project file):

09:01 CST | category / entries
permanent link | comments?
23:31 CST | category / entries / tweets
permanent link | comments?
09:51 CST | category / entries / tweets
permanent link | comments?
13:05 CST | category / entries / tweets
permanent link | comments?
12:55 CST | category / entries / tweets
permanent link | comments?
18:53 CST | category / entries / tweets
permanent link | comments?
11:02 CST | category / entries / tweets
permanent link | comments?
09:11 CST | category / entries / tweets
permanent link | comments?
09:08 CST | category / entries / tweets
permanent link | comments?
15:02 CST | category / entries / tweets
permanent link | comments?
11:12 CST | category / entries / tweets
permanent link | comments?
Hopefully we are both still gainfully employed. Even more hopeful that it’s still at Yahoo!
10:00 CST | category / entries
permanent link | comments?
09:29 CST | category / entries / tweets
permanent link | comments?
09:22 CST | category / entries / tweets
permanent link | comments?
I want to revisit run on programming because there are some subtleties that I don’t think were clear enough in the first go around.
The example again (reproduced at the bottom) is like a run-on sentence but with functions. It is characterized by a series of functions or statements that have neither function parameters nor return values, especially such that functions written in this style call other functions written in this style.
Implicit in this code organization are two items which necessarily impact maintainability and reliability.
These two issues lead necessarily to a third point, that the function or class in question is nigh-upon impossible to test.
A “good” function depends only on its input arguments. function area( radius ) { return 3.14 × radius × radius; } is a canonical example. A function that takes no input arguments had better always return the same value (making it a constant) or be a getter. If it the function results change from invocation to invication, it necessarily depends on or modifies global/class state.
If a function takes no parameters but returns no value then it uses global/class state, or must necessarily modify global/class state. A canonical example might be function print() { echo x + “, ” + y; } or function reset() { this.x = 0; this.y = 0; }.
That means that class.reset(); class.print(); is different from class.print(); class.reset();.
In the silly example below, you can kindof test the functions used in the last block (soTired(), and finish, things, up). But to test functions in imTired() you must either mock soTired() or finish, things and up. Going back to doSomething() the problem is compounded even more. To test any one individual component requires you to new the object from scratch and call the dependent functions in a particular order per each test.
The other problem is that temporal dependence is not clear from the program structure. What happens if you called up(); finish(); things(); instead of finish(); things(); up();? It is not possible to know strictly from the existing code whether changing the order will introduce bugs.
With everything I’ve learned about functional programming, I’ve learned it is better to explicitly deliver global state to functions in form of parameters, as well as to generally delegate global state modification to the calling function.
Following those simple guidelines generally leads to independent, testable, and re-usable functions where temporal dependence (calling order) is represented more explicitly by function parameters and return values.
Using the print() and reset() examples, you could imagine that we could write a print() function that took a class to print as input, and instead of printing it, returned a string.
function print( class ) => String
{
return class.x + ", " + class.y;
}
Now the print() function is side-effect free, testable, and doesn’t depend on global / class state (look up the Law of Demeter for a slightly less extreme example).
What about reset()? It simply becomes a factory method.
// This is bad for different reasons... // please see the eminently wise and hard to type // blog of Miško Hevery for more information. function reset() => MyClass { return new MyClass(); }
This pushes responsibility for modifying state to the calling function (a-la Haskell if I’ve read the literature correctly). In the case of print(); reset(); or reset(); print();, it instead becomes:
function one()
{
x = new MyClass();
echo x.print( x ); // print the class before resetting
x = x.reset();
}
function two()
{
x = new MyClass();
x = x.reset(); // reset the class before printing
echo x.print( x );
}
Each function is testable. Side-effects are contained only in the calling function, functions are order-dependent, but that order is explicit via function parameters and all is right in the world.
This is the exaggerated (anonymized) code snippet that inspired the original run on programming post.
function doSomething()
{
doThis();
doThat();
doTheOther();
imTired();
}
function imTired()
{
doMore()
andMore()
andEvenMore()
soTired()
}
function soTired()
{
finish()
things()
up()
}
09:48 CST | category / entries
permanent link | comments?
Obama’s: “Yes Pecan” and Bush’s: “___________”
Some of my underrated favorites…
Nougular Proliferation
Strategeberry
Watermelonboard
Osama Split
Oh internet how you make my day.
13:02 CST | category / entries / links
permanent link | comments?
Like what you just read? Subscribe to a syndicated feed of my weblog, brought to you by the wonders of RSS.
Thanks for Visiting!