Skip to content
Browse files

Merge branch 'master' of

  • Loading branch information...
2 parents 262056d + d943a35 commit 2289df33baaf1802c8ca0ea88835b8ef3a61c93e @KirinDave committed May 15, 2012
5 Makefile
@@ -7,8 +7,11 @@ Main: Main.hs
_site: Main css/*.css js/*.js posts/*
./Main rebuild
+sync: _site
+ s3cmd -P sync _site/ s3://
find . -name '*~' | xargs rm
find . -name '#*#' | xargs rm
find . -name '*.o' | xargs rm
- rm Main.hi
+ rm Main.hi
0 css/handheld.css 100755 → 100644
File mode changed.
9 css/neoclassical.css
@@ -70,6 +70,11 @@ p {
font-family: "Sorts Mill Goudy";
+blockquote {
+ font-family: "Sorts Mill Goudy";
+ color: rgb(100,100,100);
+ font-size: 11pt;
p + p {
margin-top: 1em;
@@ -126,3 +131,7 @@ a:hover {
body {
font-family: "Sorts Mill Goudy";
+code {
+ font-family: "Courier New", Courier, monospace;
0 css/style.css 100755 → 100644
File mode changed.
BIN images/img.png
Deleted file not rendered
BIN images/spark_prompt.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
0 js/libs/dd_belatedpng.js 100755 → 100644
File mode changed.
0 js/libs/jquery-1.5.1.js 100755 → 100644
File mode changed.
0 js/libs/jquery-1.5.1.min.js 100755 → 100644
File mode changed.
0 js/libs/modernizr-1.7.min.js 100755 → 100644
File mode changed.
0 js/plugins.js 100755 → 100644
File mode changed.
0 js/script.js 100755 → 100644
File mode changed.
152 pending_posts/2011-10-stop-having-boring-coffee.markdown
@@ -14,19 +14,157 @@ different types of coffee and why I like to prepare them, they usually
don't understand why I'd do that much for "just coffee." Then they try
some of the coffee I make; most people understand after that.
-I think a lot of people like coffee, but evidence suggests they don't
-really understand how to make good coffee. Many people have never
-even tasted a good cup of brewed coffee, so they have no basis for
+I focus on brewed coffee in this guide (as opposed to espresso, which
+is its own discipline). Brewed coffee is great to take up at home
+for a few reasons:
+1. The quality of the coffee can be quite high even with very basic
+2. The equipment that brewed coffee requires is inexpensive.
+3. It's a lot easier to get a huge diversity of flavor without extra
+effort with brewed coffee.
+Still, a lot of people believe that making their own coffee would daunting,
+difficult, or too expensive. The reality is that it simply doesn't
+take *that much* skill to make a competent cup. I've taken some of the
+things I've learned about coffeemaking and put them into a simple
+list, ordered by the impact it will have on your experience.
## 5 Steps To Better Coffee
-### 1. Grind your coffee freshly.
+### 1. Grind Your Coffee Freshly
+It turns out that the worst thing we do with our coffee is that we
+pre-grind it. When a coffee bean is ground, it is basically shattered
+and all the flavor starts to seep out. If you leave it sitting
+overnight this way (even sealed), all the compounds that give the
+coffee flavor either seep away or get oxidized. The result is muddy,
+boring, vegetal coffee.
+So, the first order of business for getting better coffee is to get an
+inexpensive conical burr grinder. You can get some pretty fancy
+hardware with this, but for starters there are two good, inexpensive
+1. A simple hand grinder. These are cheap, they do a surprisingly good
+job (for brewed coffee's medium and coarse grinds), and they help you
+gt in shape. You cannot use them to make a lot of coffee at once, but
+that's generally not a problem when you're making coffee after first
+light. I recommend [this model]()
+2. An inexpensive electric grinder. You can go really deep down the
+rabbit hole on this, but a lot of people have had great luck with the
+[](), which costs less than $80 and is easy to find.
+Once you have a good coffee grinder, grinding your coffee right before
+you use it is pretty easy. Even with store-bought coffees you will
+notice an immediate improvement in the quality of yor cup. Roasted
+coffee goes stale much more slowly than ground coffee, so if nothing
+else you can keep coffee longer.
### 2. Buy Fresh Coffee
-### 3. Don't Use A Drip Machine
+Now that you're grinding your coffee freshly, it makes sense to get
+fresh coffee. Most major cities in America have coffee roasteries now,
+so look around and experment! You can also order bags shipped in from
+fairly good roasters around the country.
+This is the point where you'll probably start to notice a really big
+quality difference between your coffee and the coffee you drink
+everywhere else. Freshly ground, freshly roasted coffee is really a
+lot better than what most poeple drink.
+I reached this state and said to myself, "Gosh it's nice having a good
+cup of coffee in the morning, but I sure do wish I could have this at
+work too." It turns out that there's an easy way to do this.
+### 3. Measure Your Coffee & Water
+Once you're picking out freshly roasted coffee and grinding it at
+home, you no longer have the benefit of using pre-measured coffee. You
+have to worry about how much coffee you put in the pot: too much and
+you're wasting coffee, too little and your coffee is an undrinkable
+bitter desert.
+Fortunately, it's pretty easy to figure this stuff out. Use a simple
+gram-accurate kitchen scale (even inexpensive ones will do) and stick
+to the simple ratio. When we make coffee, we are using water to
+extract flavor from the beans. If we extract too little, our coffee is
+watery and vegetal. Too much, and our coffee is bitter and
+It turns out that we can handle this problem by comparing relative
+weights, which means we can use simple ratios. A good "safe" ratio to
+start with is 15:1, meaning 15 parts water to one part coffee. For
+example, if you want to make 400ml of coffee (2 cups), you'd use about
+27g of coffee (to account for what you'll lose in the grinding). As
+you get better at making coffee, you can try more aggressive ratios
+like 1:17.5. For now, just focus on making better coffee.
### 4. Try Aeropressing Your Coffee
-### 5. Try simple pour-over methods.
+Now it's time to get into the fun coffee gadgetry. First of all, we're
+going to ditch your drip machine. Sorry, but very few drip coffee
+makers do a good job, and those that do often cost over $150. _We_, as
+DIY coffee fans, are going to pay a fraction of that cost for a much
+better result!
+The Aeropress is a simple one-cup brewing method that is as much a kit
+for experimenting with coffee as a tool for your morning ritual. It's
+a small, light plastic cylinder that houses a plunger. People often
+compare it to a [french press](), but it uses paper (or
+[finely perforated metal]()) filters and thus results in a clarified
+cup. It's inexpensive, easy and brilliant.
+The instructions it comes with are adequate, but you also might want
+to try the ["Viking/FourBarrell Method"]() that I detailed on
+Quora. Excluding the time it takes to heat the water, the process
+takes less than 4 minutes. It takes less time to make a cup of great
+coffee than to wait for a whole carafe of mediocre quality.
+If you've gotte this far, congratulations. You are now making better
+coffee at home than you can buy in most cafes.
+### 5. Try Simple Pour-Over Methods
+Now that you've taken a dip into hand-brewing your coffee, you'll see
+that it actually doesn't take much to get started. The next step are
+pour-over methods, of which are are a two options that I think are
+#### The Ghetto Gold
+You get a large mason jar and an inexpensive
+[Ditting Swiss Gold #2 Reusable Filter]. Then you get a kettle that is
+not awful ([the Hario Bun is popular]()). You grind your coffee the
+same way you grind for aeropress, and pour over. It should take about
+3 minutes for 27g coffee/405g water (you use a timer and pour slowly
+and periodically). This method is inexpensive, easy, and produces an
+interesting cup of coffee.
+#### Chemex
+Much can be said about the [design and history]() of the
+venerable Chemex devices. They are more expensive and require
+(inexpensive) disposable filters. There are a lot of tutorials for the
+Chemex online, but in general you follow the same simple procedure;
+for 27-35g of coffee you pour water at a 15:1 ratio and it should take
+around 3-3.5 minutes.
+A lot of people say Chemex produces their favorite variety of
+coffee. There's a lot of merit to this, and the process is very
+relaxed and fairly forgiving. If you want to have a method to make
+coffee for two or more that can be as fast or as showy as you want,
+the Chemex is a go-to method.
+## Good Coffee Everywhere
+You don't have to settle for bad coffee at home or at work. A good
+coffee setup can cost less than $50 if you bargain-shop and it quickly
+pays for itself if you frequent a local cafe (or, dare I utter it,
+Starbucks). The only investment is your time, and I value the
+5 minutes away from my desk that an afternoon aeropressing gives me.
+What's so shocking about all this is that *these methods just aren't
+that hard!* Making great coffee consistently is an art, but making
+good coffee consistently is just being methodical.
1 posts/2011-10-4-rubyists-already-use-monadic-patterns.markdown
@@ -301,3 +301,4 @@ that I think are interesting to mention:
Maybe monad. You cannot express nested maybe types, which a real Maybe
type would let you do. As an example, consider "Just Nothing".
2. @alanmalloy reminded me that flatten is too aggressive. What I wanted was #flatten(1). Thanks!
+3. The entire ruby community seems to want to argue about what ||= really means. For pedanic completenes, by expansion `(x ||= y # -> x = x || y)` is only correct for locals, where it is the closest approximation to what actually happens. Ruby has a whole separate set of rules when you call it on an object, and in that case it is closer to `( x[:a] ||= y # x[:a] || x[:a] = y )`. Please keep this in mind, but in practice it seldom makes a difference to the end result of your code.
140 posts/2011-11-02-loyal-opposition-to-not-ten-years-ago.markdown
@@ -0,0 +1,140 @@
+title: The Unbearable Lightness of Modern Typed Programming
+date: 11-02-2011
+tags: programming, static, dynamic, types
+author: Dave Fayram
+description: Static typing need not be an epic stone around your neck.
+Recently I've been seeing a lot more debate online about the relative
+merits of static and dynamic typing for the "average programmer". I
+think it's great that we're having this conversation, but I've been
+picking up on a subtle point I wanted to briefly talk about. It
+started when I read [this post by Jeremy Askhenas]( It's
+mostly Jeremy asking for a better tomorrow. It's a noble rallying cry, but I
+can't help but note this sentiment:
+If I had my druthers, would generally embrace the spirit of
+JavaScript's dynamism (and freedom), and try to push those aspects further
+-- with better introspection and more flexibility -- instead of
+compromising with more restrictive static languages and adding lock-down
+keywords so that some programmers might "feel safer".
+This echos
+[a tweet by @DHH, another strong opponent of static typing](!/dhh/status/123773621771583488),
+which says:
+I've never had that as a real problem in the wild. Passing "the wrong
+thing" to a method is a fantasy boogeyman of the
+Now, maybe 5 years ago I might have read this and nodded. Before I
+took my excursion into functional programming, I just sort of assumed
+that all static typing is like C++ (circa 1999) and Java 1.2: agony on stilts. It's
+all keywords and nonsense and repetitive cruft, right? Turns out I was
+wrong, and these guys have a very dated view of what modern static
+typing is.
+When I sit down and write code in Haskell (something I don't get to do
+very often), I am not suddenly burdened with the unbearable weight of
+types. If anything, they're there as something I can lean on to help
+me reason about my code. When I refactor, the types are likewise there
+to help (something that only a battery of cleverly written unit tests
+can give you in dynamic land).
+## Modern Type Inference, With & Without Explicitly Written Types
+As an example, I've excerpted a bit of code from a library I use to
+manage my chef 0.9 environment. I have to switch between several
+configurations and amazon keys throughout my work day. This code shows
+a nice string ("ubuntu@production" or "none") explaining what my knife.rb says about
+which chef environment I am currently pointed at:
+import System.IO
+import Data.List
+import Data.Maybe
+import Control.Monad
+import HSH (glob)
+isQuote x = x == '"' || x == '\''
+isntQuote = not . isQuote
+lineWith pat strs = find (isInfixOf pat) strs
+fileLines floc = do
+ cH <- openFile floc ReadMode
+ lines `fmap` hGetContents cH
+knifeLines = do
+ g <- glob "~/.chef/knife.rb"
+ case g of
+ a:_ -> fileLines a
+ _ -> return []
+getQuotedValue line =
+ takeWhile isntQuote startOfValue
+ where startOfValue = drop 1 $ dropWhile isntQuote line
+userString user env = user ++ "@" ++ env
+main = do
+ kl <- knifeLines
+ let klWith = (`lineWith` kl)
+ qname = getQuotedValue `fmap` klWith "node_name"
+ qenv = getQuotedValue `fmap` klWith "builder_cluster"
+ name = liftM2 userString qname qenv
+ putStrLn $ fromMaybe "none" name
+This code, as written, has no explicitly written types. The types of a value are
+mentioned in text only once, on the final line. This code compiles and
+works. Now, it's a little unrealistic to write Haskell this way. Not
+because it's terribly difficult (it is not), but rather because the
+way we often start thinking about writing a module is by thinking
+about what we want to write...
+lineWith :: String -> [String] -> Maybe String
+fileLines :: FilePath -> IO [String]
+knifeLines :: IO [String]
+getQuotedValue :: String -> String
+... and then start writing from there. This is analogous to a
+lightweight test-first process. We can lay out these type annotations
+and then sketch the code in underneath them. Like in the dynamicly-typed
+programming world, it's fairly easy not to make the mistake of passing
+the wrong item to a function. Unlike the dynamicly-typed programming world, we
+have the compiler watching out back and making sure we don't get
+distracted and commit that subtle error.
+Even better, later we can use those type signatures to help write
+randomly generated tests that help us catch the edge cases we
+*weren't* thinking of. So not only do the type signatures give us a
+nice starting point for writing a unit of code, but they also can go
+above and beyond later in the code life cycle when we start to ask hard
+questions about how durable our software is.
+## They Call Him, "The Straw Man"
+This is what a modern type system offers for you. You will spend time
+interacting with it, but more as a partner and a tool for letting you
+write more expressive code (the only reason we could use liftM2 was
+because we had type inference figuring out that qname and qenv are
+Maybe's). And you don't need to go all the way into the Haskell world to
+get these benefits; there are several languages for a variety of
+runtimes that give you modern, powerful type systems that act as your
+ally instead of your taskmaster. Even the venerable C++ is [adding limited type inference](
+So let's stop spreading the misconception that static typing is all
+about "keywords" and "const" circa 1999. Sure, some statically typed
+languages use these constructs. But, that's not really related to
+static typing so much as their heritage. Let's stop straw-manning a very promising
+branch of the programming language family that has come a long way
+over the past 20 years.
+And of course, I'd like to thank the folks who helped suggest how to
+clarify my code on Freenode. In particular: shachaf, luite, c_wraith, Nimatek and grey_wolf.
0 templates/toplevel.html 100755 → 100644
File mode changed.

0 comments on commit 2289df3

Please sign in to comment.
Something went wrong with that request. Please try again.