Option Monad in Scala

I’m finally succumbing to one of the clichés of functional programming interest: writing a monad tutorial. My only point here is to show the use of perhaps the simplest monad to avoid an ugly, but not uncommon pattern: nested if statements checking for null. If you’re already turned off by the word Monad, just replace it with the word “thingy” or perhaps “dingus” as you read.

Consider the java code:

  static public void main(String[] args) {
    Object r1 = args[0];
    Object r2 = f1(r1);
    if( null != r2 ) { 
      Object r3 = f2(r2);
      if( null != r3 ) { 
        Object r4 = f3(r3);
        if( null != r4 ) { 
          System.out.println("You all everybody!");
        }   
      }   
    }   
  }

Clearly no thinking person should be reduced to writing such a disaster. The Option monad in Scala can let you deal with these cases with elegance:

  def f1(r : AnyRef) = "you"
  def f2(r : AnyRef) = "all"
  //def f3(r : AnyRef) = "everybody"
  def f3(r : AnyRef) : AnyRef = null

  val r1 = "start"
  val fin = for( r2 <- Option{ f1(r1) };
       r3 <- Option{ f2(r2) };
       r4 <- Option{ f3(r3) } ) 
    yield r4
  fin.foreach { res => println("you all everybody") }

This code is very similar to the above Java. The for statement above is equivalent to the following syntax:

  def f1(r : AnyRef) = "you"
  def f2(r : AnyRef) = "all"
  //def f3(r : AnyRef) = "everybody"
  def f3(r : AnyRef) : AnyRef = null

  val r1 = "start"
  Option{ f1(r1) }.
    flatMap( r2 => Option{ f2(r2) }). 
    flatMap( r3 => Option{ f3(r3) }). 
    foreach { res => println("you all everybody") }

What’s happening here? It’s simple, Option is a class that either holds Some(x) or None. When None enters your calculation at any stage, None will be the final result. Otherwise, if every step returns Some, you should complete the full calculation. None causes you to bail out. This is similar to using exceptions for control flow, or how NaNs propagate in IEEE-754 floating point arithmetic. Option in scala is pretty much identical to the Maybe Monad in Haskell. In fact, this has been implemented in Java as well.

So what exactly is a Monad? It’s pretty simple, but its name (being Greek, I guess) scares the hell out of everyone the first time they hear it. A Monad is just something that has two functions, called return and bind, which have the following rules (in scala-esque pseudo code)[see monad axioms]:

Monad.return(x).bind(y => f(y)) == f(x)
m.bind(y => Monad.return(y)) == m
m.bind(y => f(y)).bind(z => g(z)) == m.bind( y => f(y).bind(z => g(z)) )

In Scala, the return function is just Some(x).

Option {x}

is similiar, it returns Some(x) if x is not null, None otherwise. Bind is called flatMap, which on None returns None, on Some(x) returns Some(f(x)). None is also a monadic zero, in that when you call bind on it, like multiplication by zero, it always returns None. The analogy here in IEEE754 is if you bind with NaN the output always returns NaN (IEEE754 has embedded the Option/Maybe monad). One of the awesome things about Haskell is that they built a way to represent all sorts of things as Monads: IO, transactions, mutable memory, state-machine transitions, and many more.

Like I said, it is a total cliché to write one of these posts. You can find them by the hundreds on the Web (here’s a more technical and very similar one: Monads in Scala), so, if functional programming is going to change the way we develop software, and I believe it already has and will continue to, I suppose we’ll be seeing lots more pages such as this one.

Diet Change: Vegan to Grain-Free

I am an extremist. The simplicity of extremes is appealing as one avoids the complexities of grays. For the past two years or so, I have followed a rather strict vegan diet motivated by the health benefits claimed by The China Study, and not particularly by the idea that it is immoral to eat animals. Recently I have had a number of questions in my mind as to the evidence for and against such diets, and ultimately decided to add preferably lean, organic and non-feedlot meats back into my diet. At the same time, I am experimenting with removing grains from my diet. Here’s why:

Is the evidence for a vegan diet very strong?

The China Study presents a few lines of evidence to support that protein, probably by IGF-1, can increase cancer risks. However, upon reading The Protein Debate, it seems to me that Dr. Campbell believes all protein does this and a primary reason to go Vegan is that such a diet very likely limits total protein to less than 10%. If you are vegan and you eat enough legumes or vegan protein supplements to get that number to 20-30%, are you not violating the fundamental argument for the anti-cancer benefit?

Virtually none of the people studied in The China Study were vegan. An extrapolation is made that goes from low animal protein to zero should be helpful. Is that reasonable? As recently as 1998, new nutrients were recognized as essential. What essential nutrients have yet to be discovered? Perhaps even low levels of meat supplies something essential that is as of yet unknown, without which health is impaired. No population of humans that I am aware of have lived on vegan diets for their entire lives. I’d prefer to be conservative and adopt a diet with some consensus behind it, namely, what did groups of healthy and long-lived people eat? The Blue Zones project seeks to address this. They identified many groups of long-lived people. Only one of them had significant populations of vegetarians (Seventh-day Adventists), and even most of them consumed some fish and eggs. Granted, Adventists who ate more meat had higher cancer rates, but how controlled were the studies? Were those processed meats? A recent meta-analysis found processed meats increased heart disease and diabetes, but not red meat. Many studies lump all meats together, which may be throwing the baby out with the bathwater.

What will I eat?

If you are not on a tight budget, you have many options for food. My current experiment is to add meats back to my diet, but remove grains. Why am I removing grains? I was influenced by two arguments. The first being The Paleo Diet, the second being general low-carb diets that avoid grains such as rice, bread, pasta, and so on to reduce insulin production. The core idea is that there are some foods to which were are more adapted to eating than others, and grains are particularly bad. This is a reasonable hypothesis, but it needs to be substantiated by evidence before it should be treated as true. My ancestors have likely been farming for 10,000 years or more, and that may have been enough time to completely adapt to a grain-based diet. However, for this experiment, I’m removing grains. From a standpoint of nutrient density, grains are not so great. Take a look at the The World’s Healthiest Foods. Very few grains compare favorably against fruits, vegetables, and meats for nutrients per calorie. I am going to focus on very low glycemic index foods. The exception will be during or after longer running events or workouts. I will use bananas, watermelon, pineapple and sweet potatoes after workouts to get non-grain high-GI foods. I will also eat lentils and beans, which are low-GI, but not Paleo-approved. Some might say, this sounds like an Atkins diet, and that is not healthy. It appears to me concerns about lower carbohydrate diets seem to lack evidence. A recent 2-year study, sometimes called the ATOZ study, found Atkins dieters lost more weight and improved metabolic risk factors more than traditional, Ornish or Zone dieters. I can’t find any evidence that these diets are a risk. Can you?

Should you change your diet?

I believe humans are very metabolically flexible. If you have no problems with your health, athletic performance, or happiness that could plausibly be connected to diet, and you are pleased with your diet, I’m not sure there is strong evidence to change. If you are overweight, struggle to maintain your weight, are frequently injured, or feel that your workouts don’t go well, perhaps changing your diet is worth a try. I don’t think anyone can convincingly say much about diet other than if you are obese, it is harming your health. If your diet is not preventing obesity, you probably need a change.

Update 2/27/2011: I found this criticism of the China Study to make good points (and a few of the same ones I made). It would be interesting to see more a response to these questions and criticisms from Dr. Campbell.

Vitamix Whole Bean Soy Milk / Soy Yogurt

I’ve recently been making some soymilk with my vitamix. The idea is simple: grind the hell out of whole soybeans and get a wholefood soymilk. Usual recipes will have you strain the soymilk, which removes nutrients (particularly fiber). The resulting soymilk is a bit grainier, but the vitamix does an excellent job of producing a smooth milk.

The recipe is here. The cost of this is very low. Soy beans are about $1/lb at my local bulk bin, and this recipe uses about 1/4 lb, so I can produce two quarts of soy milk/yogurt for about 30 cents total. Considering that a quart of soy yogurt is usually about $3.50 or so, this saves me about 6 dollars per batch.

Three things I want to stress:
1) USE BOILING WATER. Using boiling water when grinding deactivates an enzyme that can give soymilk a beany flavor that most people don’t like as much.
2) The simmering for 20 minutes is to deactivate trypsin inhibitors in soy which are potentially problematic in soy-based foods.
3) I added sugar to this recipe because I use the soymilk to make yogurt. My results were poor fermenting the unsweetened soymilk. Once I added the sugar (which gives it a calorie density very comparable to 2% milk), fermentation worked great.

I use this to make yogurt, of which I eat about one cup per day. The total amount of soy in that one cup is not very great, so I don’t worry too much. The yogurt actually turns out great. It’s very creamy, much more so than the skim yogurt I used to make with dairy. As a note, to get started, I purchased some soy yogurt, and used a bit of it to start the culture. Since then, it has been self sustaining.

Lastly, I don’t think this would work with a standard blender as I doubt it would grind the soy up fine enough. A vitamix, or similarly powerful blender, is probably needed.

Getting Antioxidants on a Budget

Recently, I posted about the problem that cheaper foods tend to include a lot of junk foods. For instance, you can easily get all your daily calories by buying the cheapest options at McDonalds or by buying M&Ms in bulk. That post left open the question: what should I eat if I want to get good nutrition and stay on a budget?

I took a simplified look at this problem. In addition to calories, I looked at the ORAC level of foods, which is a measure of their antioxidant power. To do this, I found an excellent ORAC table from the USDA. ORAC levels are often quoted per 100 gram sample (about 1/4th of a pound, or 4 oz). While this is a fair basis for comparision, it is fairly irrelevant to an eater. As an eater, I care much more about the ORAC units per calorie or ORAC units per dollar. The limits of my calorie budget (to avoid obesity) or my financial budget (to avoid bankruptcy) are much more restrictive than my limits due to stomach size. Doing evaluations on price is more difficult because unlike ORAC density or calorie density, price is not a property of the food, but of a local and fluctuating market. So, your results may be slightly different, but I collected these prices from the lowest available in my area (Gainesville, FL, USA) during late 2008 and early 2009. The results are as follows.

If I only want to maximize ORAC per calorie, which is to say: “price be damned, I only care about not getting too fat”, these are the foods that will help me do that:

Food Orac/100g Cost/100g Cal/100g Orac/cal Orac/dol
Tea, green, brewed 1253 0.02 1 1253.0 71697.55
Spices, Cinnamon, ground 267536 0.66 247 1083.1 406225.23
Spices, cloves, ground 314446 17.21 323 973.5 18272.73
Spices, oregano, dried 200129 3.53 306 654.0 56636.51
Spices, turmeric 159277 5.94 354 449.9 26830.59
cocoa dry powder, unsweeted 80933 3.45 229 353.4 23470.57
Spices, basil, dried 67553 0.66 251 269.1 102572.11
Coriander (cilantro) raw 5141 1.4 23 223.5 3683.3
Ginger root 14840 0.81 80 185.5 18258.43
Plums (raw) 6259 0.42 46 136.1 15034.85
Blueberries, raw 6552 0.69 57 114.9 9463.23
Strawberries 3577 0.37 32 111.8 9759.36
Spices, pepper, black 27618 2.56 255 108.3 10798.42
Spices, Ginger, ground 28811 5.3 347 83.0 5435.68
Apples Granny Smith (with skin) 3898 0.42 52 75.0 9363.45
Spinach, raw 1515 0.85 23 65.9 1791.17
Goji Berries 25300 2.35 400 63.3 10775.05
Red table wine (cab) 5034 0.53 83 60.7 9438.75
Apples (with skin) 3082 0.37 52 59.3 10846.73
Spinach, frozen 1687 0.28 29 58.2 6105.13
Peppers, sweet, green, raw 923 0.28 20 46.2 3248.39
Applesauce canned, unsweeted 1965 0.19 43 45.7 10492.36
Juice, Concord Grape 2377 0.25 57 41.7 9582.49
Beets, raw 1767 0.66 43 41.1 2683
Broccoli, raw 1362 0.39 34 40.1 3534.96
Dark Chocolate 20823 3.5 520 40.0 5949.43
Peppers, sweet, orange, raw 984 1.1 25 39.4 895.26
Onions, red, raw 1521 0.28 40 38.0 5352.98
Oranges, raw, navals 1819 0.44 49 37.1 4149.88
Grapefruit, pink red 1548 0.15 42 36.9 10068.65
Garlic 5346 0.5 149 35.9 10598.62

Notice, that spices are so high in ORACs, they are an easy way to increase the ORACs in your diet. There are some of the usual suspects up there as well: green tea, berries, apples, spinach, red wine. Tea has almost no calories, so it naturally will be high on this list.

But let’s look at how to get a sufficient amount of ORACs within both a calorie and financial budget. To do that, we need to identify the budget. Exactly how many ORACs a person needs is probably not a completely well defined question because of individual differences and the limitations of ORACs as some kind of unified measure of nutrition (which it is not, and I am not claiming that it is). That having been said, I’ve seen the number 5000 ORAC/day as a target (which is approximately what you’d get if you get 5 servings of most fruits or vegetables a day). For the calorie budget, I’ll assume 2000 calories per day (get a better estimate for yourself with the Nutritiondata.com daily needs tool). For the financial budget, I found a 2003-2004 USDA study on food spending that found that the poorest 20% spent on average 1737 per year in 2004, so that gives us 4.76 to spend per day. Since many high ORAC foods are not consumed in large quantities (such as spices), but some other medium ORAC foods are (such as beans or shreaded wheat), I limited the foods to more than 272 cal/dol, which is $7.35/day. I did this to get a list of 20 foods. Then I sorted them according to highest ORAC/dollar. The following list is the cheapest way to get ORACs and still get enough calories each day to not spend too much on food:

Food Orac/100g Cost/100g Cal/100g Orac/cal Orac/dol cal/dol
Spices, Cinnamon, ground 267536 0.66 247 1083.1 406225.23 375.04
Spices, basil, dried 67553 0.66 251 269.1 102572.11 381.12
Beans, kidney, raw 8459 0.22 333 25.4 38403.86 1511.82
Beans, black, raw 8040 0.22 341 23.6 36501.6 1548.14
Lentils, raw 7282 0.22 353 20.6 33060.28 1602.62
Plums (dried) 6552 0.44 240 27.3 14902.38 545.87
Garlic 5346 0.5 149 35.9 10598.62 295.4
Grapefruit, pink red 1548 0.15 42 36.9 10068.65 273.18
Nuts, pecans 17940 1.98 691 26.0 9059.8 348.96
Nuts, walnut 13541 1.65 654 20.7 8207.76 396.42
Raisins, seedless 3037 0.49 299 10.2 6156.67 606.14
Bananas 879 0.15 89 9.9 5783.57 585.59
Potatoes, red, flesh and skin, raw 1098 0.22 70 15.7 4994.91 318.44
Peanuts, raw 3166 0.66 567 5.6 4791.21 858.06
Nuts, almonds 4454 1.54 575 7.7 2892.87 373.46
Cereal, shreaded wheat plain 1303 0.66 340 3.8 1986.53 518.36
Popcorn, airpopped 1743 0.99 387 4.5 1757.1 390.13
Watermelon, raw 142 0.11 30 4.7 1293.67 273.31
Nuts, cashew 1948 1.87 553 3.5 1041.69 295.71
Olive oil, extra virgin 1150 1.27 884 1.3 907.34 697.47

It’s interesting that when we sort by ORAC/dollar and put a price threshold, very different foods show up. We can see how great beans are with this list: when you buy dried beans in bulk you get an extremely healthy food which is also extremely economical: more than 1500 calories per dollar! Of course, these prices assume you are getting the very best deals: so one needs to shop at club stores and buy food from the bulk bins. Dried Plums, or Prunes, also show up as big winners: about twice the ORACs/dollar of raisins with about the same calories/dollar. Notice also, that stawberries and blueberries are great (high ORAC/calorie as we saw in the first chart), but they are too expensive to form a significant portion of your calories. When it comes to nuts, pecans and walnuts are excellent choices: they give you lots of ORACs and lots of calories.

One last point I want to make is that paying attention to the seasonal sales in fruits and vegetables makes a lot of sense. The prices may change by more than a factor of three as items go in and out of season, so make sure to try to choose seasonal vegetables and fruits. Also, compare the calories/dollar of canned, frozen and dried vs. fresh fruits and vegetables. Often fresh costs more and in many recipes you won’t notice any difference.

You can find the above data on a google spreadsheet containing the ORAC data.

Update 3/10/2009: Here’s a related NY Times article: “Eating Well on a Downsized Food Budget” published 3/2/2009.

New Year’s Resolutions

I listened to a Science Friday podcast on New Year’s Resolutions yesterday. It turns out almost half of them are achieved (if I got that right). A couple of things that help are making realistic goals and sharing them with others to get support.

So, here goes: I’ve made an account (johnynek) on 43things to track some goals for the year and for life in general. Please bug me about these, encourage me, and hold me to them. Also, tell me about your goals and I’ll do the same for you.

Happy New Year!

Marathon (26.2 Miles) in 2:57:18 (6:46/mile)

Finishing the Memphis Marathon

About six months ago, my friend Jake Logan asked me if I was interested in training for a marathon together. I was reluctant because I had been injured on and off for a while at that time, but I agreed. I’m so glad Jake and I started our training together. Having a friend doing the same training program (The Furman Institute of Running and Scientific Training, FIRST, program), was a huge motivator for both of us. I think I speak for us both when I say that the FIRST program is excellent and a great way to prepare for a first marathon.

On December 6, 2008, I ran the St. Jude Memphis Marathon in 2:57:18 missing my goal time of 2:55 by slightly more than 2 minutes. It was a cold day. The race started at about 30 degrees. I was 51st overall and 10th in my age group out of more than 2200 finishers. The official results are here, and here are my approximate splits taken from my watch:

Mile Lap Pace Split Overall Pace
3 19:12.94 6:24.3 19:12 6:24.3
6 19:56.78 6:38.9 39:09 6:31.5
9 18:57.23 6:19.0 58:06 6:27.3
12 20:19.78 6:46.5 1:18:26 6:32.1
15 20:04.41 6:41.4 1:38:31 6:34.0
18 20:29.08 6:49.6 1:59:00 6:36.6
21 20:14.12 6:44.7 2:19:14 6:37.8
24 21:38.23 7:12.7 2:40:52 6:42.1
25 7:20.44 7:20.44 2:48:13 6:43.7
26.2 9:05:40 7:34.5 2:57:18 6:46.0

There are a few pictures from the race with my Flickr marathon tag. There are also some professional pictures you can see accessing my bib number (259).

I was pleased with my performance, but I think I went out too fast, which is one of my common problems. One problem was that I really didn’t know what I was capable of, but I should have stuck better with my game plan of shooting for 2:55. Instead, at the halfway mark, I was on pace for 2:50. To qualify for the NYC marathon, I needed to run 2:55. I can also qualify for NY by running a half-marathon in 1:23. My current PR for the half is 1:25 (which I ran on the way to my 2:57 marathon). My plan for the future is to first rest and make sure I’m really strong and injury free before starting any hard training. Secondly, I plan to train for a half-marathon with a goal of doing 1:21 sometime this spring. With that qualifying time, I would then train to do the NY marathon in the fall.

Road Thrill Wins the 194 Mile Florida Ragnar Relay

I’m incredibly proud to have been a member of the excellent Road Thrill team:

Team Road Thrill at the starting line

We won the first Florida Ragnar Relay, 194 miles from Clearwater to Daytona. Our team average 6:51/mile for 22 hours and 13 minutes. The second place team, a men’s team called Legends Plus from Florida College, was more than 39 minutes behind us. We had six men and six women (winning both the open and mixed (men and women) divisions):

Women:
Ashley Espy
Jaclyn Solodovnick
Jami Ludwig
Kristine Poyner
Jaclyn Solodovnick
Lindsay Sundell
Melanie Ladenheim

Men:
Oscar Boykin
Ed Dunne
Jake Logan
Julio Palma
Alex Phipps
Andrew Robinson

I hope I won’t embarrass my teammates by heaping praise on them, but I witnessed some truly heroic running on their parts during our 22 hours and 13 minutes over those 194 miles. If you know any of these runners, congratulate them and implore them to regale you with tales of running through the night across Florida.

I twittered the event and you can read those twitter posts here. Some of the pictures from the event are on flickr with my Ragnar tag.

All I can say is that this was an other-wordly experience. Running through the night with such support was amazing. Watching that runner come to the exchange (in my case, Julio Palma) and running to get the baton to the next runner (in my case Jami Ludwig) was really inspiring. The team was split into two vans. I was in Van 1 with Jaclyn, Jami, Kristine, Jake and Julio. It took us a couple of exchanges to get the hang of dropping off a runner, cheering them in the middle (and maybe giving water) and then moving into position so the next runner could go. When it was my turn to run, I knew that after the drop off I could expect to hear my team cheering about 10 minutes later, and I knew I wanted to be looking strong when they went driving by.

You can see all the legs on the Ragnar site. I was runner 3. I did 3.6 miles at 6:31/mile, 9.5 at 6:34/mile, then 3.7 at 6:50/mile. I “slept” for about an hour at exchange 12.

Ragnar tried to arrange it so the teams would arrive in a narrow time window. That meant the slowest teams started first, at 8:00am, and the faster teams later. We started with the last group at 2:00pm. It was exciting, because when we started, no one was behind us. We didn’t see many runners, and the exchanges were dirty and used. As we got a few hours in, we started to pick up runners from earlier start groups. That was really exciting to us. By the second and third sets (legs 13-24) we were really starting to pass a lot of runners. Then, it died off. We were fighting Legends Plus for most of the race, but by the start of the third set it looked like pretty much had them thanks to our van 2, which was by far the strongest van in Ragnar. Towards the end, we heard there were only a few teams ahead of us, all of whom started earlier than we did. We started to get ambitious and hoped to not only win overall, but finish before any team. We almost did it, but one team, Steamed Muscles, that started at 11am, finished about 30 minutes before us. They finished third in the mixed division and fifth overall, congratulations to them! We spoke to some of the second place mixed finishers, “12 Hearts, 36 Legs, No Brains – Brandon Runners”, at the start. They were really nice and very encouraging. Congratulations to them as well.

I look forward to next year. Let’s see if we can go under 22 hours!