<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:media="http://search.yahoo.com/mrss/" xmlns:yt="http://gdata.youtube.com/schemas/2007" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">
   <channel>
      <title>Jan'uary</title>
      <description>Pipes Output</description>
      <link>http://pipes.yahoo.com/pipes/pipe.info?_id=cLQTEc_Q3RGGXiz8bLsjiw</link>
      <pubDate>Fri, 10 Jul 2009 12:01:51 -0700</pubDate>
      <generator>http://pipes.yahoo.com/pipes/</generator>
      <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/January" type="application/rss+xml" /><item>
         <title>今年的比赛</title>
         <link>http://feedproxy.google.com/~r/January/~3/lJ14jcIAe1o/post.3433099.html</link>
         <description>今年在上海举行的花式比赛已经变成了世界锦标赛，多么开心的一件事情。可惜世锦赛的选拔比赛放在酒泉进行，又是多么的悲剧。于是大部分浪人选手也只能参加一下降级为国内比赛的上海公开赛了。&lt;br /&gt;
&lt;br /&gt;
也许这是最后一个夏天了吧...&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/January?a=lJ14jcIAe1o:eHYjznNj_b8:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/January?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/January?a=lJ14jcIAe1o:eHYjznNj_b8:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/January?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/January?a=lJ14jcIAe1o:eHYjznNj_b8:2mJPEYqXBVI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/January?d=2mJPEYqXBVI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/January/~4/lJ14jcIAe1o" height="1" width="1"/&gt;</description>
         <guid isPermaLink="false">http://jan.ycool.com/post.3433099.html</guid>
         <pubDate>Fri, 03 Jul 2009 20:07:22 -0700</pubDate>
      <feedburner:origLink>http://jan.ycool.com/post.3433099.html</feedburner:origLink></item>
      <item>
         <title>不怕狼一样的对手，就怕猪一般的盟友</title>
         <link>http://feedproxy.google.com/~r/January/~3/bqVwhJlzwPs/post.3354957.html</link>
         <description>兄弟我这两天真的很郁闷，连续两个晚上，每一把星际群殴都遇人不淑。其实我要求不高，只要你能自保就行了，至少不要被矿后光炮这种多少年前的招式搞死。。&lt;br /&gt;
&lt;br /&gt;
老天保佑今天不会继续衰下去。。你已经下雨弄的我没平花玩了，星际就帮帮我吧，请你吃牛肉。...&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/January?a=bqVwhJlzwPs:wQenwrKogpM:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/January?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/January?a=bqVwhJlzwPs:wQenwrKogpM:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/January?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/January?a=bqVwhJlzwPs:wQenwrKogpM:2mJPEYqXBVI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/January?d=2mJPEYqXBVI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/January/~4/bqVwhJlzwPs" height="1" width="1"/&gt;</description>
         <guid isPermaLink="false">http://jan.ycool.com/post.3354957.html</guid>
         <pubDate>Wed, 17 Jun 2009 04:06:23 -0700</pubDate>
      <feedburner:origLink>http://jan.ycool.com/post.3354957.html</feedburner:origLink></item>
      <item>
         <title>告别孩子气</title>
         <link>http://feedproxy.google.com/~r/January/~3/O7RrwGQxLlY/post.3240199.html</link>
         <description>&amp;ldquo;你们要做将来的领袖，不仅求得一点专门的知识就足够，必须具有清醒而富有理智的头脑，明辨是非而不徇利害的气概，沉思远虑，不肯盲从的习惯，而同时还要 有健全的体格，肯吃苦耐劳，牺牲自己努力为公的精神。这几点是做领袖所不可缺乏的条件。&amp;rdquo; &amp;ldquo;诸位，现在我们若要拯救我们的中华民族，亦惟有靠我们自己的力量，培养我们的力量来拯救我们的祖国。这才是诸位到浙江大学来的共同使命。&amp;rdquo; &lt;br /&gt;
&lt;br /&gt;
国立浙江大学校长竺可桢 1939年2月4日...&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/January?a=O7RrwGQxLlY:Fd23TaMkoa0:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/January?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/January?a=O7RrwGQxLlY:Fd23TaMkoa0:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/January?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/January?a=O7RrwGQxLlY:Fd23TaMkoa0:2mJPEYqXBVI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/January?d=2mJPEYqXBVI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/January/~4/O7RrwGQxLlY" height="1" width="1"/&gt;</description>
         <guid isPermaLink="false">http://jan.ycool.com/post.3240199.html</guid>
         <pubDate>Wed, 13 May 2009 00:05:33 -0700</pubDate>
      <feedburner:origLink>http://jan.ycool.com/post.3240199.html</feedburner:origLink></item>
      <item>
         <title>想去天堂吗？欢迎来杭州</title>
         <link>http://feedproxy.google.com/~r/January/~3/qJ1DRVZN3Tk/post.3236362.html</link>
         <description>&lt;a rel="nofollow" target="_blank" href="http://70yard.com"&gt;70yard.com&lt;/a&gt;...&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/January?a=qJ1DRVZN3Tk:wzAv3j7Eof8:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/January?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/January?a=qJ1DRVZN3Tk:wzAv3j7Eof8:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/January?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/January?a=qJ1DRVZN3Tk:wzAv3j7Eof8:2mJPEYqXBVI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/January?d=2mJPEYqXBVI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/January/~4/qJ1DRVZN3Tk" height="1" width="1"/&gt;</description>
         <guid isPermaLink="false">http://jan.ycool.com/post.3236362.html</guid>
         <pubDate>Sun, 10 May 2009 20:05:02 -0700</pubDate>
      <feedburner:origLink>http://jan.ycool.com/post.3236362.html</feedburner:origLink></item>
      <item>
         <title>吗隔壁</title>
         <link>http://feedproxy.google.com/~r/January/~3/pok5_KuQxhc/post.3234855.html</link>
         <description>&lt;a rel="nofollow" target="_blank" href="http://club.china.com/data/thread/3212956/281/48/90/7_1.html"&gt;http://club.china.com/data/thread/3212956/281/48/90/7_1.html&lt;/a&gt;&lt;br /&gt;
&lt;a rel="nofollow" target="_blank" href="http://www.19lou.com/forum-5-thread-17461954-1-1.html"&gt;http://www.19lou.com/forum-5-thread-17461954-1-1.html&lt;/a&gt;...&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/January?a=pok5_KuQxhc:x4tvu9bapv4:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/January?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/January?a=pok5_KuQxhc:x4tvu9bapv4:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/January?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/January?a=pok5_KuQxhc:x4tvu9bapv4:2mJPEYqXBVI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/January?d=2mJPEYqXBVI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/January/~4/pok5_KuQxhc" height="1" width="1"/&gt;</description>
         <guid isPermaLink="false">http://jan.ycool.com/post.3234855.html</guid>
         <pubDate>Sat, 09 May 2009 09:05:21 -0700</pubDate>
      <feedburner:origLink>http://jan.ycool.com/post.3234855.html</feedburner:origLink></item>
      <item>
         <title>五一劳动节快乐</title>
         <link>http://feedproxy.google.com/~r/January/~3/49-8O31-L-g/post.3225211.html</link>
         <description>直到今天我才明白，为什么那些伟大的先人要把五月一日设定为国际劳动节，因为在这一天劳动的感觉实在是太好了。。。&lt;br /&gt;
&lt;br /&gt;
万恶的资本主义。...&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/January?a=49-8O31-L-g:TPTmwUoz4kY:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/January?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/January?a=49-8O31-L-g:TPTmwUoz4kY:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/January?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/January?a=49-8O31-L-g:TPTmwUoz4kY:2mJPEYqXBVI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/January?d=2mJPEYqXBVI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/January/~4/49-8O31-L-g" height="1" width="1"/&gt;</description>
         <guid isPermaLink="false">http://jan.ycool.com/post.3225211.html</guid>
         <pubDate>Thu, 30 Apr 2009 19:05:59 -0700</pubDate>
      <feedburner:origLink>http://jan.ycool.com/post.3225211.html</feedburner:origLink></item>
      <item>
         <title>China vs US Economy</title>
         <link>http://feedproxy.google.com/~r/January/~3/O8t1ZCD7KA8/post.3217482.html</link>
         <description>&lt;a rel="nofollow" target="_blank" href="http://node3.foto.ycstatic.com/200904/24/d/27730077o.jpg"&gt;&lt;img src="http://node3.foto.ycstatic.com/200904/24/d/27730077o.jpg"/&gt;&lt;/a&gt;...&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/January?a=O8t1ZCD7KA8:lH70bzR6V14:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/January?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/January?a=O8t1ZCD7KA8:lH70bzR6V14:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/January?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/January?a=O8t1ZCD7KA8:lH70bzR6V14:2mJPEYqXBVI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/January?d=2mJPEYqXBVI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/January/~4/O8t1ZCD7KA8" height="1" width="1"/&gt;</description>
         <guid isPermaLink="false">http://jan.ycool.com/post.3217482.html</guid>
         <pubDate>Thu, 23 Apr 2009 21:04:25 -0700</pubDate>
      <feedburner:origLink>http://jan.ycool.com/post.3217482.html</feedburner:origLink></item>
      <item>
         <title>两份武学秘籍</title>
         <link>http://feedproxy.google.com/~r/January/~3/TWXmN7dSfjI/post.3217470.html</link>
         <description>&lt;a rel="nofollow" target="_blank" href="http://node1.foto.ycstatic.com/200904/24/7/27730071o.jpg"&gt;&lt;img src="http://node1.foto.ycstatic.com/200904/24/7/27730071o.jpg"/&gt;&lt;/a&gt;&lt;br /&gt;
&lt;a rel="nofollow" target="_blank" href="http://node1.foto.ycstatic.com/200904/24/6/27730070o.jpg"&gt;&lt;img src="http://node1.foto.ycstatic.com/200904/24/6/27730070o.jpg" alt=""/&gt;&lt;/a&gt;&lt;br /&gt;
&lt;a rel="nofollow" target="_blank" href="http://node1.foto.ycstatic.com/200904/24/5/27730069o.jpg"&gt;&lt;img src="http://node1.foto.ycstatic.com/200904/24/5/27730069o.jpg" alt=""/&gt;&lt;/a&gt;...&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/January?a=TWXmN7dSfjI:Woq-aqlfipM:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/January?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/January?a=TWXmN7dSfjI:Woq-aqlfipM:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/January?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/January?a=TWXmN7dSfjI:Woq-aqlfipM:2mJPEYqXBVI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/January?d=2mJPEYqXBVI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/January/~4/TWXmN7dSfjI" height="1" width="1"/&gt;</description>
         <guid isPermaLink="false">http://jan.ycool.com/post.3217470.html</guid>
         <pubDate>Thu, 23 Apr 2009 20:04:04 -0700</pubDate>
      <feedburner:origLink>http://jan.ycool.com/post.3217470.html</feedburner:origLink></item>
      <item>
         <title>贾樟柯</title>
         <link>http://feedproxy.google.com/~r/January/~3/086aji1N4Vk/post.3206413.html</link>
         <description>"后来我通过采访发现，那一代父母因为在内心里他们有被牺牲的感觉，所以他们索性更加牺 牲，一辈子攒的钱，孩子结婚买房，给出去。或者孩子在工厂上班，同事们都不错，都有车，那就把自己所有的积蓄都拿出来。亏了自己没关系，绝对要保护孩子， 绝对要让孩子没有任何阴影，因为他们了解到社会的差距，他们心里有一个落差，所以他们用全部的积蓄让孩子没有落差。"&lt;br /&gt;
&lt;br /&gt;
"从日常来说，我觉得没有人没有理想，但大多数人在理想方面挫败是一个常态，实现理想生活 的是一个非常态。成千上万的人没有选择。这个主题不是我故意要拍的，是生活的本质和真相是这样的。如果你是一个悲观主义者，你知道人们缺少爱，你才会有爱 给别人。这就是世界需要悲观的原因，否则不是傻开心嘛。"&lt;br /&gt;
&lt;br /&gt;
"我觉得我是。它不妨碍我在生活中也是快乐的，但当我用一个媒介表达我对世界的看法时，城市的话，我觉得本质就是不快乐的。很简单，生老病死不愉快，年华老去也不愉快。生命的过程就有很多悲哀在里面，所有人类才有充沛的情感啊。"&lt;br /&gt;
&lt;br /&gt;
&lt;a rel="nofollow" target="_blank" href="http://blog.sina.com.cn/s/blog_467a4e7c0100cvov.html"&gt;很喜欢贾樟柯的这些话，我觉得很深刻&lt;/a&gt;。我常常觉得悲哀是世界的本质，悲剧是人类的鸦片，但是我想不出为什么自己会这样想，今天忽然有点儿感觉了。原来乐观的生活并不代表你是一个乐观主义者。...&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/January?a=086aji1N4Vk:zFv_-c41ZKg:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/January?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/January?a=086aji1N4Vk:zFv_-c41ZKg:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/January?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/January?a=086aji1N4Vk:zFv_-c41ZKg:2mJPEYqXBVI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/January?d=2mJPEYqXBVI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/January/~4/086aji1N4Vk" height="1" width="1"/&gt;</description>
         <guid isPermaLink="false">http://jan.ycool.com/post.3206413.html</guid>
         <pubDate>Mon, 13 Apr 2009 22:04:38 -0700</pubDate>
      <feedburner:origLink>http://jan.ycool.com/post.3206413.html</feedburner:origLink></item>
      <item>
         <title>穿越城区的老男人</title>
         <link>http://feedproxy.google.com/~r/January/~3/jB5BHvShGeY/post.3205733.html</link>
         <description>最近的生活发生了挺大的变化。&lt;br /&gt;
&lt;br /&gt;
在我对Apple已经非常不感冒的时候，老板非要给我发一台macbook用来工作。我很有良心的报告说，其实我还是更喜欢PC加双显示器，价格只要macbook的一半，老板很潇洒的回了一句，钱不是问题。唉，啥时候我也能这么潇洒的说这么一句呢。&lt;br /&gt;
&lt;br /&gt;
论实用，macbook确实比不上我的x61。轻便强劲，键盘有手感，linux全面的驱动支持，指点杆完全是神来之笔，配合xmonad之类的wm绝对是天下无敌的开发机器。macbook则完全是一个噩梦。。。08年下半年开始的macbook unibody配的全是broadcom的无线网卡，给他老人家装驱动真是要命，网上文档又特别少，可能花一堆钱买mac偏要装个linux用的人的确太少。。。千辛万苦终于配合着arch/debian/gentoo/ubuntu的文档才搞定。macbook的键盘和触摸板被识别为一个设备，驱动也是超级难搞。最后好不容易能用了，触摸板单击(指tap)和双击(double tap)功能时灵时不灵，palm detection也做的不好，写代码的时候经常一不小心手掌靠上了触摸板，鼠标就飞到你找不到的地方去了，multi touch倒是支持的不错。声卡貌似号称是六声道的，但是用alsa驱动只有前面右边喇叭能出身，其它几个只能发挥配重稳定机身的功能，据大伙儿反映这是驱动的问题，目前没办法解决。显示屏亮度无法控制，每次modprobe mbp_nvidia_bl都出错，google了半天发现ubuntu论坛上有群众也碰倒了这个问题，据那一小撮反映这也是驱动问题，目前无法解决，怒。macbook用的引导系统太先进，装OSX+linux费了老大的劲。OSX花里胡哨的界面越用越烦，据本人客观评价，目前linux上的桌面环境加上compiz一点儿也不比OSX难用。所以我只能恶毒的揣测苹果，把个系统弄的这么不开放就是要把用户绑定的自己的专有平台上面然后杀猪 － 外接显示器接口弄得独一无二，一个转接线标价499，最后370块买下，成本我估摸着2块钱差不多。&lt;br /&gt;
&lt;br /&gt;
黑了半天，说说macbook的优点。屏幕很亮，看着赏心悦目；运行时声音很小很小很小，苹果毕竟还是有水平，忽悠也得有资本；除此之外。。好像没有了。&lt;br /&gt;
&lt;br /&gt;
=======================&lt;br /&gt;
&lt;br /&gt;
公司的办公地点在城西的最东边，我住在城东的最西边，于是公司体恤老男人发了台电动车让我上班轻松点儿，能留下更多精力被剥削。电动车还真的蛮好玩的，最高能加到三十公里每小时，就是瞬间加速太弱了，不知道是故意弄成这样还是电驱动的原因，每当红灯转绿，我要牛b轰轰的一加油门蹭的一下窜出去的时候，可爱的小车车总是慢慢悠悠的开始挪动，刹那间所有的雄心壮志灰飞烟灭。。以后一定要买辆摩托车玩。&lt;br /&gt;
&lt;br /&gt;
显摆到此结束，插播条新闻：&lt;a rel="nofollow" target="_blank" href="http://hamptonroads.com/2009/04/scientist-serve-51-months-giving-technology-china"&gt;牛人勇闯美利坚，一只红杏出墙来&lt;/a&gt;...&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/January?a=jB5BHvShGeY:x79ORQavzv4:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/January?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/January?a=jB5BHvShGeY:x79ORQavzv4:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/January?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/January?a=jB5BHvShGeY:x79ORQavzv4:2mJPEYqXBVI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/January?d=2mJPEYqXBVI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/January/~4/jB5BHvShGeY" height="1" width="1"/&gt;</description>
         <guid isPermaLink="false">http://jan.ycool.com/post.3205733.html</guid>
         <pubDate>Mon, 13 Apr 2009 05:04:47 -0700</pubDate>
      <feedburner:origLink>http://jan.ycool.com/post.3205733.html</feedburner:origLink></item>
      <item>
         <title>Stuck in Code</title>
         <link>http://feedproxy.google.com/~r/January/~3/rmfM5R2LhSY/post.3202786.html</link>
         <description>"I think it is a very *Indian* (or perhaps Asian) thing to expect good developers to "move up" to be managers or directors or Vice Presidents. We are a very hierarchical society and people are very often judged on where we are seen to be on some arbitrary hierarchy. People who work with their hands (or their keyboards) are often considered "inferior"."&lt;br /&gt;
&lt;br /&gt;
&lt;a rel="nofollow" target="_blank" href="http://pindancing.blogspot.com/2009/04/stuck-in-code.html"&gt;http://pindancing.blogspot.com/2009/04/stuck-in-code.html&lt;/a&gt;&lt;br /&gt;...&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/January?a=rmfM5R2LhSY:V_Uwv33vZAQ:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/January?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/January?a=rmfM5R2LhSY:V_Uwv33vZAQ:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/January?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/January?a=rmfM5R2LhSY:V_Uwv33vZAQ:2mJPEYqXBVI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/January?d=2mJPEYqXBVI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/January/~4/rmfM5R2LhSY" height="1" width="1"/&gt;</description>
         <guid isPermaLink="false">http://jan.ycool.com/post.3202786.html</guid>
         <pubDate>Fri, 10 Apr 2009 08:04:10 -0700</pubDate>
      <feedburner:origLink>http://jan.ycool.com/post.3202786.html</feedburner:origLink></item>
      <item>
         <title>美帝貌似有点儿乱套</title>
         <link>http://feedproxy.google.com/~r/January/~3/UmGBS125Hqc/post.3198101.html</link>
         <description>&lt;a rel="nofollow" target="_blank" href="http://news.yahoo.com/s/ap/20090405/ap_on_re_us/binghamton_shootings_victim_vignettes_1"&gt;A look at victims of the Binghamton, NY, shootings&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;a rel="nofollow" target="_blank" href="http://www.dailycal.org/article/105033/uc_berkeley_senior_fatally_shot_in_oakland"&gt;UC Berkeley Senior Fatally Shot in Oakland&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;a rel="nofollow" target="_blank" href="http://www.wthr.com/Global/story.asp?S=10130337h"&gt;Two dead in Shelbyville shooting&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
印象中还有一起，找不到链接了，就是几天之内的事情。失业率真是一个可怕的东西，以前学政治经济的时候感觉就是一个数字而已，现在终于明白为什么当权者对失业率升高那么恐慌。&lt;br /&gt;
&lt;br /&gt;
杭州的夜晚突然多了很多路边摊。...&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/January?a=UmGBS125Hqc:DyVZ0slUuHc:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/January?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/January?a=UmGBS125Hqc:DyVZ0slUuHc:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/January?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/January?a=UmGBS125Hqc:DyVZ0slUuHc:2mJPEYqXBVI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/January?d=2mJPEYqXBVI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/January/~4/UmGBS125Hqc" height="1" width="1"/&gt;</description>
         <guid isPermaLink="false">http://jan.ycool.com/post.3198101.html</guid>
         <pubDate>Sun, 05 Apr 2009 23:04:23 -0700</pubDate>
      <feedburner:origLink>http://jan.ycool.com/post.3198101.html</feedburner:origLink></item>
      <item>
         <title>[ANN] Rubytest.vim 0.9.6 Released</title>
         <link>http://feedproxy.google.com/~r/January/~3/xkuIkZyELjs/ann-rubytestvim-096-released.html</link>
         <description>Rubytest.vim 0.9.6 is just released. This version contains some small fix:&lt;br /&gt;&lt;br /&gt; * support rspec examples looks like&lt;br /&gt; example "this is an example" do&lt;br /&gt; * correctly handle single/double quote escape for rspec examples and vanilla testcases&lt;br /&gt;&lt;br /&gt;Check it out here: &lt;a rel="nofollow" target="_blank" href="http://www.vim.org/scripts/script.php?script_id=2612"&gt;http://www.vim.org/scripts/script.php?script_id=2612&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;* Rubytest.vim is a vim plugin which helps you run ruby tests (including vanilla testcases, rspec examples, shoulda examples ..) quickly.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6265706250887913030-3075508022649285369?l=rwsleep.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ReadWriteSleep/~4/c2a0TGzVqeA" height="1" width="1"/&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/January?a=xkuIkZyELjs:QQb_FZdk5NI:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/January?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/January?a=xkuIkZyELjs:QQb_FZdk5NI:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/January?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/January?a=xkuIkZyELjs:QQb_FZdk5NI:2mJPEYqXBVI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/January?d=2mJPEYqXBVI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/January/~4/xkuIkZyELjs" height="1" width="1"/&gt;</description>
         <author>Jan</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-6265706250887913030.post-3075508022649285369</guid>
         <pubDate>Sun, 14 Jun 2009 19:32:00 -0700</pubDate>
      <feedburner:origLink>http://feedproxy.google.com/~r/ReadWriteSleep/~3/c2a0TGzVqeA/ann-rubytestvim-096-released.html</feedburner:origLink></item>
      <item>
         <title>Infinity in Ruby</title>
         <link>http://feedproxy.google.com/~r/January/~3/hlvS7c-oG4U/infinity-in-ruby.html</link>
         <description>I learned this from a post today:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;irb(main):001:0&amp;gt; Infinity = 1/0.0&lt;br /&gt;=&amp;gt; Infinity&lt;br /&gt;irb(main):002:0&amp;gt; (0..Infinity).include?(100000000000000)&lt;br /&gt;=&amp;gt; true&lt;br /&gt;irb(main):003:0&amp;gt; (0..Infinity).include?(-1)&lt;br /&gt;=&amp;gt; false&lt;br /&gt;irb(main):004:0&amp;gt; (-Infinity..0).include?(-1)&lt;br /&gt;=&amp;gt; true&lt;br /&gt;irb(main):005:0&amp;gt; (-Infinity..0).include?(-100000000000000000000)&lt;br /&gt;=&amp;gt; true&lt;br /&gt;irb(main):006:0&amp;gt; (-Infinity..0).include?(1)&lt;br /&gt;=&amp;gt; false&lt;br /&gt;irb(main):007:0&amp;gt; everything = -Infinity..Infinity&lt;br /&gt;=&amp;gt; -Infinity..Infinity&lt;br /&gt;irb(main):008:0&amp;gt; everything.include? 0&lt;br /&gt;=&amp;gt; true&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;But ruby is not like haskell, which eval lazily - so don't try everything.to_a[0..100] :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6265706250887913030-1471498189051168663?l=rwsleep.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ReadWriteSleep/~4/Lq8sZvbmG38" height="1" width="1"/&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/January?a=hlvS7c-oG4U:N1b0wqoDTOc:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/January?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/January?a=hlvS7c-oG4U:N1b0wqoDTOc:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/January?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/January?a=hlvS7c-oG4U:N1b0wqoDTOc:2mJPEYqXBVI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/January?d=2mJPEYqXBVI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/January/~4/hlvS7c-oG4U" height="1" width="1"/&gt;</description>
         <author>Jan</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-6265706250887913030.post-1471498189051168663</guid>
         <pubDate>Tue, 02 Jun 2009 12:02:00 -0700</pubDate>
      <feedburner:origLink>http://feedproxy.google.com/~r/ReadWriteSleep/~3/Lq8sZvbmG38/infinity-in-ruby.html</feedburner:origLink></item>
      <item>
         <title>[ANN] Rubytest.vim 0.9.5 Released</title>
         <link>http://feedproxy.google.com/~r/January/~3/mO-2WbfT2Xg/ann-rubytestvim-095-released.html</link>
         <description>Rubytest.vim is a vim (http://www.vim.org) plugin, which helps you to run ruby test (including vanilla test, rspec, shoulda etc.) in vim.&lt;br /&gt;&lt;br /&gt;Changelog&lt;br /&gt;---------&lt;br /&gt;&lt;br /&gt;* Support quickfix: you can view test errors in quickfix window now&lt;br /&gt;* Small fixes.&lt;br /&gt;&lt;br /&gt;Get it here: &lt;a rel="nofollow" target="_blank" href="http://www.vim.org/scripts/script.php?script_id=2612"&gt;http://www.vim.org/scripts/script.php?script_id=2612&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6265706250887913030-1918171909884269989?l=rwsleep.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ReadWriteSleep/~4/NI7mj9C5LNw" height="1" width="1"/&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/January?a=mO-2WbfT2Xg:Mkz_TfngZgk:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/January?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/January?a=mO-2WbfT2Xg:Mkz_TfngZgk:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/January?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/January?a=mO-2WbfT2Xg:Mkz_TfngZgk:2mJPEYqXBVI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/January?d=2mJPEYqXBVI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/January/~4/mO-2WbfT2Xg" height="1" width="1"/&gt;</description>
         <author>Jan</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-6265706250887913030.post-1918171909884269989</guid>
         <pubDate>Tue, 12 May 2009 13:49:00 -0700</pubDate>
      <feedburner:origLink>http://feedproxy.google.com/~r/ReadWriteSleep/~3/NI7mj9C5LNw/ann-rubytestvim-095-released.html</feedburner:origLink></item>
      <item>
         <title>The problem with young entrepreneurs</title>
         <link>http://feedproxy.google.com/~r/January/~3/8JX9LGC4wFU/problem-with-young-entrepreneurs.html</link>
         <description>"Most of the time, this leads to the well-known case of “solutions looking for problems” - beautiful technology that can’t become a profitable business.&lt;br /&gt;&lt;br /&gt;Best ideas are a side-effect from solving significant problems that the entrepreneurs themselves experience, observe and intimately understand. As young Web entrepreneurs, we aren’t sufficiently aware of important real-world problems, since our life mostly consists of hacking, coffee and occasional entertainment."&lt;br /&gt;&lt;br /&gt;&lt;a rel="nofollow" target="_blank" href="http://igorfaletski.com/2009/05/01/the-problem-with-young-web-entrepreneurs-myself-included/"&gt;via&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6265706250887913030-6660634708163743352?l=rwsleep.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ReadWriteSleep/~4/1WN5o6dke1w" height="1" width="1"/&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/January?a=8JX9LGC4wFU:AJVMGIJsxjk:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/January?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/January?a=8JX9LGC4wFU:AJVMGIJsxjk:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/January?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/January?a=8JX9LGC4wFU:AJVMGIJsxjk:2mJPEYqXBVI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/January?d=2mJPEYqXBVI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/January/~4/8JX9LGC4wFU" height="1" width="1"/&gt;</description>
         <author>Jan</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-6265706250887913030.post-6660634708163743352</guid>
         <pubDate>Sun, 03 May 2009 20:23:00 -0700</pubDate>
      <feedburner:origLink>http://feedproxy.google.com/~r/ReadWriteSleep/~3/1WN5o6dke1w/problem-with-young-entrepreneurs.html</feedburner:origLink></item>
      <item>
         <title>Something about latest vimperator</title>
         <link>http://feedproxy.google.com/~r/January/~3/HkKjZYusluU/something-about-latest-vimperator.html</link>
         <description>Latest vimperator release doesn't work well with Firefox 3.0.x and TabMixPlus: slow autocompletion, broken tab functions.&lt;br /&gt;&lt;br /&gt;M.Terada provides two patch to make tabs work decently again, I don't know whehter it's included in vimperator's repository now, but you can download them &lt;a rel="nofollow" target="_blank" href="http://www.mozdev.org/pipermail/vimperator/attachments/20090418/2b7ac945/attachment-0002.obj"&gt;here&lt;/a&gt; and &lt;a rel="nofollow" target="_blank" href="http://www.mozdev.org/pipermail/vimperator/attachments/20090418/2b7ac945/attachment-0003.obj"&gt;here&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;For faster auto completion, set complete and preload options like this in your .vimperatorrc may help:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;set complete=sbh&lt;br /&gt;set nopreload&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Some guys suggest setting wildmode to empty, but I don't like that idea.&lt;br /&gt;&lt;br /&gt;Below is mine full .vimperatorrc:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;set pageinfo=gfm&lt;br /&gt;set showtabline=2&lt;br /&gt;set defsearch=google&lt;br /&gt;set complete=sbh&lt;br /&gt;set nopreload&lt;br /&gt;set showstatuslinks=2&lt;br /&gt;set smartcase&lt;br /&gt;set newtab=all&lt;br /&gt;"set wildmode=&lt;br /&gt;&lt;br /&gt;map l gt&lt;br /&gt;map h gT&lt;br /&gt;map b :bmarks!&amp;lt;Space&amp;gt;&lt;br /&gt;map ;; d&lt;br /&gt;map s :js open("mailto:?SUBJECT='" + escape(document.title) + "'" + "&amp;BODY=" + escape(document.getElementById("urlbar").value))&amp;lt;CR&amp;gt;&lt;br /&gt;&lt;br /&gt;map &amp;lt;C-p&amp;gt; :pa&amp;lt;CR&amp;gt;&lt;br /&gt;map &amp;lt;C-k&amp;gt; tg&amp;lt;Space&amp;gt;&lt;br /&gt;map &amp;lt;C-u&amp;gt; &amp;lt;C-v&amp;gt;&amp;lt;C-u&amp;gt;&lt;br /&gt;map &amp;lt;C-y&amp;gt; &amp;lt;C-v&amp;gt;&amp;lt;C-y&amp;gt;&lt;br /&gt;map &amp;lt;C-R&amp;gt; a&amp;lt;Space&amp;gt;-tags=toread&amp;lt;CR&amp;gt;&lt;br /&gt;map &amp;lt;C-r&amp;gt; :bmarks -tags=toread&amp;lt;CR&amp;gt;&lt;br /&gt;map &amp;lt;C-d&amp;gt; :delbm&amp;lt;CR&amp;gt;&lt;br /&gt;"map &amp;lt;C-l&amp;gt; :sidebar LiveHTTPHeaders&amp;lt;CR&amp;gt;&lt;br /&gt;&lt;br /&gt;map &amp;lt;silent&amp;gt; &amp;lt;F9&amp;gt; :js inspectDOMDocument(document)&amp;lt;CR&amp;gt;&lt;br /&gt;map &amp;lt;silent&amp;gt; &amp;lt;F1&amp;gt; :js toggle_element('toolbar-menubar');toggle_element('nav-bar')&amp;lt;CR&amp;gt;&lt;br /&gt;map &amp;lt;silent&amp;gt; &amp;lt;F2&amp;gt; :emenu Edit.Preferences&amp;lt;CR&amp;gt;&lt;br /&gt;map &amp;lt;silent&amp;gt; &amp;lt;F3&amp;gt; :emenu Tools.Live HTTP headers&amp;lt;CR&amp;gt;&lt;br /&gt;map &amp;lt;silent&amp;gt; &amp;lt;F10&amp;gt; :exe ":o dict2 "+content.getSelection()&amp;lt;CR&amp;gt;&lt;br /&gt;&lt;br /&gt;autocmd PageLoad .* :js modes.passAllKeys = /(mail&amp;#92;.google&amp;#92;.com)|(google&amp;#92;.com&amp;#92;/reader)/.test(buffer.URL)&lt;br /&gt;&lt;br /&gt;set nextpattern+=^&amp;#92;s*下一页&amp;#92;s*$&lt;br /&gt;set previouspattern+=^&amp;#92;s*上一页&amp;#92;s*$&lt;br /&gt;&lt;br /&gt;javascript &amp;lt;&amp;lt;EOF&lt;br /&gt;(function(){&lt;br /&gt; var feedPanel = document.createElement("statusbarpanel");&lt;br /&gt; feedPanel.setAttribute("id", "feed-panel-clone");&lt;br /&gt; feedPanel.appendChild(document.getElementById("feed-button"));&lt;br /&gt; feedPanel.firstChild.setAttribute("style", "padding: 0; max-height: 16px;");&lt;br /&gt; document.getElementById("status-bar")&lt;br /&gt; .insertBefore(feedPanel, document.getElementById("security-button"));&lt;br /&gt;})();&lt;br /&gt;EOF&lt;br /&gt;&lt;br /&gt;javascript &amp;lt;&amp;lt; EOF&lt;br /&gt; toggle_element = function (name) {&lt;br /&gt; document.getElementById(name).collapsed ^= 1;&lt;br /&gt; }&lt;br /&gt;EOF&lt;br /&gt;&lt;br /&gt;echo ".vimperatorrc sourced"&lt;br /&gt;&lt;br /&gt;" vim: ft=vimperator sw=2 sts=2&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6265706250887913030-8666538329110457321?l=rwsleep.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ReadWriteSleep/~4/_4fjnGpe_Us" height="1" width="1"/&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/January?a=HkKjZYusluU:DZujUUuVBtw:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/January?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/January?a=HkKjZYusluU:DZujUUuVBtw:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/January?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/January?a=HkKjZYusluU:DZujUUuVBtw:2mJPEYqXBVI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/January?d=2mJPEYqXBVI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/January/~4/HkKjZYusluU" height="1" width="1"/&gt;</description>
         <author>Jan</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-6265706250887913030.post-8666538329110457321</guid>
         <pubDate>Thu, 30 Apr 2009 11:53:00 -0700</pubDate>
      <feedburner:origLink>http://feedproxy.google.com/~r/ReadWriteSleep/~3/_4fjnGpe_Us/something-about-latest-vimperator.html</feedburner:origLink></item>
      <item>
         <title>Announcement of rubytest.vim: a vim plugin aims to help you run ruby test conveniently</title>
         <link>http://feedproxy.google.com/~r/January/~3/eSz8GrfO5cs/announcement-of-rubytestvim-vim-plugin.html</link>
         <description>Rubytest.vim is a vim (http://www.vim.org) plugin, which helps you to run ruby test (including vanilla test, rspec, shoulda etc.) in vim.&lt;br /&gt;&lt;br /&gt;&lt;a rel="nofollow" target="_blank" href="http://www.vim.org/scripts/script.php?script_id=2612"&gt;http://www.vim.org/scripts/script.php?script_id=2612&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Installation&lt;br /&gt;------------&lt;br /&gt;&lt;br /&gt;Copy all files to your ~/.vim directory.&lt;br /&gt;&lt;br /&gt;Usage&lt;br /&gt;-----&lt;br /&gt;&lt;br /&gt;After installation, press t will run the test under your cursor if you are editing a ruby test file.&lt;br /&gt;&lt;br /&gt;example:&lt;br /&gt;&lt;br /&gt;$ cd &lt;br /&gt; $ vim test/unit/user_test.rb&lt;br /&gt;(move cursor into a test case, press t)&lt;br /&gt;&lt;br /&gt;( is mapping to '&amp;#92;' by default in vim)&lt;br /&gt;&lt;br /&gt;You can customize the command which will be used to run the test case by settting these options in your vimrc file:&lt;br /&gt;&lt;br /&gt; let g:rubytest_cmd_test = "ruby %p"&lt;br /&gt; let g:rubytest_cmd_testcase = "ruby %p -n '/%c/'"&lt;br /&gt; let g:rubytest_cmd_spec = "spec -f specdoc %p"&lt;br /&gt; let g:rubytest_cmd_example = "spec -f specdoc %p -e '%c'"&lt;br /&gt;&lt;br /&gt;(%p will be replaced by the path of test file, %c will be replaced by the name of test case under cursor)&lt;br /&gt;&lt;br /&gt;Default Key Bindings&lt;br /&gt;--------------------&lt;br /&gt;&lt;br /&gt; t: run test case under cursor&lt;br /&gt; T: run all tests in file&lt;br /&gt;&lt;br /&gt;You can change default key bindings:&lt;br /&gt;&lt;br /&gt; map &amp;#92; RubyTestRun " change from t to &amp;#92;&lt;br /&gt; map ] RubyFileRun " change from T to ]&lt;br /&gt;&lt;br /&gt;&lt;a rel="nofollow" target="_blank" href="http://www.vim.org/scripts/script.php?script_id=2612"&gt;http://www.vim.org/scripts/script.php?script_id=2612&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6265706250887913030-2295956454832805505?l=rwsleep.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ReadWriteSleep/~4/0ihas0VIzbc" height="1" width="1"/&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/January?a=eSz8GrfO5cs:UnxWSGwE5oo:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/January?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/January?a=eSz8GrfO5cs:UnxWSGwE5oo:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/January?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/January?a=eSz8GrfO5cs:UnxWSGwE5oo:2mJPEYqXBVI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/January?d=2mJPEYqXBVI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/January/~4/eSz8GrfO5cs" height="1" width="1"/&gt;</description>
         <author>Jan</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-6265706250887913030.post-2295956454832805505</guid>
         <pubDate>Sun, 19 Apr 2009 10:47:00 -0700</pubDate>
      <feedburner:origLink>http://feedproxy.google.com/~r/ReadWriteSleep/~3/0ihas0VIzbc/announcement-of-rubytestvim-vim-plugin.html</feedburner:origLink></item>
      <item>
         <title>Bidirectional many-to-many relationship in ActiveRecord</title>
         <link>http://feedproxy.google.com/~r/January/~3/tE8mEdBQPLU/bidirectional-many-to-many-relationship.html</link>
         <description>Bidirectional many-to-many relationship is a common pattern in design, like friendships between users, memberships between users and groups, etc. In this article I'll illustrate how to implement such a relationship in ActiveRecord/Rails.&lt;br /&gt;&lt;br /&gt;Let's start with a little context. Suppose we want to add the populer 'friends' feature for our users, we already have User model, what we need is a join table 'friendships' to connect users.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;class User &amp;lt; ActiveRecord::Base&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;class CreateFriendships &amp;lt; ActiveRecord::Migration&lt;br /&gt; def self.up&lt;br /&gt; create_table :friendships, :id =&amp;gt; false do |t|&lt;br /&gt; t.integer :left_user_id&lt;br /&gt; t.integer :right_user_id&lt;br /&gt; end&lt;br /&gt; end&lt;br /&gt;&lt;br /&gt; def self.down&lt;br /&gt; drop_table :friendships&lt;br /&gt; end&lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;The behavior we want, can be written like this:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;test "should has many friends" do&lt;br /&gt; users(:quentin).friends &amp;lt;&amp;lt; users(:aaron)&lt;br /&gt; assert_equal 1, users(:quentin).friends.reload.count&lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Of course the test is failed when we run it now. After reading our requirements we decide to use has_and_belongs_to_many (habtm) in ActiveRecord because it is enough for now, so we modify our User model like this:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;class User &amp;lt; ActiveRecord::Base&lt;br /&gt; has_and_belongs_to_many :friends, :join_table =&amp;gt; 'friendships',&lt;br /&gt; :foreign_key =&amp;gt; 'left_user_id', :association_foreign_key =&amp;gt; 'right_user_id',&lt;br /&gt; :class_name =&amp;gt; 'User'&lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Now run our test, passed, perfect! We can leave office and enjoy *fill whatever you like* now.&lt;br /&gt;&lt;br /&gt;"Wait", your brilliant colleague says, and add one line to your unit test:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;test "should has many friends" do&lt;br /&gt; users(:quentin).friends &amp;lt;&amp;lt; users(:aaron)&lt;br /&gt; assert_equal 1, users(:quentin).friends.reload.count&lt;br /&gt; assert_equal 1, users(:aaron).friends.reload.count&lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;He runs the test again and it failed. It's unfair if quentin treat aaron as his friend but aaron doesn't do the same to quentin, isn't it? To fix this problem we need to custom insert and delete sql for the habtm relationship:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;class User &amp;lt; ActiveRecord::Base&lt;br /&gt; has_and_belongs_to_many :friends, :join_table =&amp;gt; 'friendships',&lt;br /&gt; :foreign_key =&amp;gt; 'left_user_id', :association_foreign_key =&amp;gt; 'right_user_id',&lt;br /&gt; :class_name =&amp;gt; 'User',&lt;br /&gt; :insert_sql =&amp;gt; 'insert into friendships (`left_user_id`, `right_user_id`) values &lt;br /&gt;(#{id}, #{record.id}), (#{record.id}, #{id})',&lt;br /&gt; :delete_sql =&amp;gt; 'delete from friendships where (left_user_id = #{id} and right_user_id &lt;br /&gt;= #{record.id}) or (left_user_id = #{record.id} and right_user_id = #{id})'&lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;What we do here, is to add two friendship records (both direction) when we add a user to another's friends set. We do the same when delete a user from one's friends set. We rerun the test and it passes as we expected.&lt;br /&gt;&lt;br /&gt;Note the ":id =&amp;gt; false" argument when we create the join table 'friendships', without it you'll have &lt;a rel="nofollow" target="_blank" href="http://blog.martiandesigns.com/2008/04/10/gotcha-habtm-relationships-use-join-table-id-as-model-id/"&gt;troubles&lt;/a&gt; when loading friends objects. I think this is a long history bug of ActiveRecord, I don't know why it is not fixed. If you really want to keep the 'id' field and use habtm at the same time, a workaround is customize the finder_sql:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;class User &amp;lt; ActiveRecord::Base&lt;br /&gt; has_and_belongs_to_many :friends, ...&lt;br /&gt; :finder_sql =&amp;gt; 'select users.* from friendships left outer join users on &lt;br /&gt;friendships.right_user_id = users.id where friendships.left_user_id = #{id}'&lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;The bidirectional habtm we build here, is in fact a self-referential bidirectional relationship, it relates models to the same type of models (users to users). What will happen if the relationship is NOT self referential?&lt;br /&gt;&lt;br /&gt;In that case we should not use habtm, otherwise our (at least my) brain will be burned by the complicated sqls it brings. Don't waste time on those sqls, ActiveRecord provides another way to build many-to-many relationship: has_many :through&lt;br /&gt;&lt;br /&gt;So one day the boss comes to you and asks, "Can we group our friends? I want to put Gates in group Evil and Male, and Linus in group Minix and Antarctic"&lt;br /&gt;&lt;br /&gt;"Sure", you answered, how can you say No to your boss?&lt;br /&gt;&lt;br /&gt;Now the many-to-many relationship is between groups and users, we need to modify User model, create a Group model and write a migration to modify friendships table. Since we'll use has_many :through for this requirement, we also need a model for the join table 'friendships':&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;class User &amp;lt; ActiveRecord::Base&lt;br /&gt; has_many :groups&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;class CreateGroups &amp;lt; ActiveRecord::Migration&lt;br /&gt; def self.up&lt;br /&gt; create_table :groups do |t|&lt;br /&gt; t.string :name&lt;br /&gt; t.integer :user_id&lt;br /&gt; end&lt;br /&gt; end&lt;br /&gt;&lt;br /&gt; def self.down&lt;br /&gt; drop_table :groups&lt;br /&gt; end&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;class Group &amp;lt; ActiveRecord::Base&lt;br /&gt; belongs_to :user&lt;br /&gt; has_many :friendships&lt;br /&gt; has_many :friends, :through =&amp;gt; :friendships&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;class RemodelFriendships &amp;lt; ActiveRecord::Migration&lt;br /&gt; def self.up&lt;br /&gt; remove_column :friendships, :left_user_id&lt;br /&gt; rename_column :friendships, :right_user_id, :friend_id&lt;br /&gt; change_column :friendships, :group_id, :integer, :null =&amp;gt; false&lt;br /&gt; end&lt;br /&gt;&lt;br /&gt; def self.down&lt;br /&gt; change_column :friendships, :group_id, :integer, :null =&amp;gt; true&lt;br /&gt; rename_column :friendships, :friend_id, :right_user_id&lt;br /&gt; add_column :friendships, :left_user_id&lt;br /&gt; # execute "..."&lt;br /&gt; end&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;class Friendship &amp;lt; ActiveRecord::Base&lt;br /&gt; belongs_to :group&lt;br /&gt; belongs_to :friend, :class_name =&amp;gt; 'User'&lt;br /&gt; validates_uniqueness_of :friend_id, :scope =&amp;gt; :group_id&lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Pretty good, it works. But we have the same problem when we use habtm, the relationship is not bidirectional. How can we fix it?&lt;br /&gt;&lt;br /&gt;ActiveRecord allow you to extend the association proxy when use has_many :through, the solution here is to override the proxy's default CRUD methods. Let's create a new file lib/bidirection.rb:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;module Bidirection&lt;br /&gt; def &amp;lt;&amp;lt;(friend)&lt;br /&gt; Friendship.create :group_id =&amp;gt; friend.groups.default.id, :friend_id =&amp;gt; self.proxy_owner.user.id&lt;br /&gt; super(friend)&lt;br /&gt; end&lt;br /&gt;&lt;br /&gt; [:delete, :destroy].each {|m|&lt;br /&gt; define_method(m) {|friends|&lt;br /&gt; friends = [friends] unless friends.instance_of?(Array)&lt;br /&gt; friends.each {|friend|&lt;br /&gt; Friendship.first(:conditions =&amp;gt; {:group_id =&amp;gt; friend.groups.default.id, :friend_id =&amp;gt; self.proxy_owner.user.id}).try m&lt;br /&gt; }&lt;br /&gt; super(friends)&lt;br /&gt; }&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Then enhance our has_many :through with it:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;class Group &amp;lt; ActiveRecord::Base&lt;br /&gt; ...&lt;br /&gt; has_many :friends, :through =&amp;gt; :friendships, :extend =&amp;gt; Bidirection&lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;That's it, you have bidirectional many-to-many relationship between groups and users now. For convinient you can create a default group when create user (use before_create hook), and delegate friends and friends= methods in User model to user's default group, in that way you get the self-referential bidirectional many-to-many relationship betweent users back, as we have when using habtm.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6265706250887913030-6483757490509139067?l=rwsleep.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ReadWriteSleep/~4/Zk75bw5Btmo" height="1" width="1"/&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/January?a=tE8mEdBQPLU:gyIP6v0u1jQ:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/January?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/January?a=tE8mEdBQPLU:gyIP6v0u1jQ:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/January?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/January?a=tE8mEdBQPLU:gyIP6v0u1jQ:2mJPEYqXBVI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/January?d=2mJPEYqXBVI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/January/~4/tE8mEdBQPLU" height="1" width="1"/&gt;</description>
         <author>Jan</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-6265706250887913030.post-6483757490509139067</guid>
         <pubDate>Thu, 26 Mar 2009 17:31:00 -0700</pubDate>
      <feedburner:origLink>http://feedproxy.google.com/~r/ReadWriteSleep/~3/Zk75bw5Btmo/bidirectional-many-to-many-relationship.html</feedburner:origLink></item>
      <item>
         <title>ActiveRecord and DataMapper</title>
         <link>http://feedproxy.google.com/~r/January/~3/qocqkYbn_2I/activerecord-and-datamapper.html</link>
         <description>I jumped into a merb project about 1 month ago, it's really an interesting trip. Working in both frameworks make pros and cons crystal clear to see. Here I'll try to remember some of those I found on the different ORM they use, thus ActiveRecord vs DataMapper.&lt;br /&gt;&lt;br /&gt;* Schema Definition&lt;br /&gt;&lt;br /&gt;ActiveRecord keep all schema definitions in migration files, while DataMapper store most of them in model source code. I prefer DataMapper's way, so you won't need plugins like &lt;a rel="nofollow" target="_blank" href="http://agilewebdevelopment.com/plugins/annotate_models"&gt;annotate_models&lt;/a&gt; any more. Do you use annotate_models in your rails project?&lt;br /&gt;&lt;br /&gt;However, keep model schema in model source code brings more complexity, because sometimes you have tasks which are better written in a migration file instead of model source file. So DataMapper has seperate migrations too, and merb provides more migration rake tasks than rails.&lt;br /&gt;&lt;br /&gt;* Many-to-Many Relationships Through Scoped Join Model&lt;br /&gt;&lt;br /&gt;Sorry for my poor description, &lt;a rel="nofollow" target="_blank" href="http://rails.lighthouseapp.com/projects/8994/tickets/718-has_many-method-doesn-t-handle-conditions"&gt;this ticket&lt;/a&gt; illustrates the problem well. I don't know why this bug won't be fixed in ActiveRecord - below code works well in DataMapper.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt; has n, :bookmarks, :through =&amp;gt; :subscriptions, :conditions =&amp;gt; "subscriptions.notification = 'f'"&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;* scope&lt;br /&gt;&lt;br /&gt;ActiveRecord introduced named_scope in since 2.x (can't remember), and add dynamic scope (scope_by_xxx like dynamic finder find_by_xxx) in the latest 2.3 release, so now you can chain up many dynamic scopes, named scope and find now. That's really cool, but why we need two seperate finders, find and scope?&lt;br /&gt;&lt;br /&gt;In DataMapper, "find" and "scope" is unified. You can do this&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt; class Zoo&lt;br /&gt; # all the keys and property setup here&lt;br /&gt; def self.open&lt;br /&gt; all(:open =&amp;gt; true)&lt;br /&gt; end&lt;br /&gt; def self.big&lt;br /&gt; all(:animal_count.gte =&amp;gt; 1000)&lt;br /&gt; end&lt;br /&gt; end&lt;br /&gt; &lt;br /&gt; big_open_zoos = Zoo.big.open&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;As you can see, the finder #all is able to be chained up or used independently, smart. And I like tye syntax all(:open =&amp;gt; true) than find_all_by_open(true): hash can be auto complete by editors while '_' can not, hash param doesn't require dynamic tricks while find_xxx need. Sometimes I feel rails takes too many cares to his baby programmers, sometimes I feel merb takes too little (not in this case, of course).&lt;br /&gt;&lt;br /&gt;* Inheritance vs Include&lt;br /&gt;&lt;br /&gt;ActiveRecord model is required to inherit from ActiveRecord::Base, while DataMapper model need to include DataMapper::Resource. Composition is better than inheritance, though module inclusion is in fact inheritance in Ruby.&lt;br /&gt;&lt;br /&gt;* Finally&lt;br /&gt;&lt;br /&gt;I didn't realize all the things I written down are votes for DataMapper until I write this sentence .. I want to say ActiveRecord is an excellent ORM framework too, at least it's more mature than DataMapper, I enjoy it at most of the time, it just doesn't work in some few case (I really hope the many-to-many relationship through scope join model problem can be fixed, it's a common pattern I've seen it serveral times). The good news is by Rails and Merb merge, rails will become super flexible and you'll be able to switch between ORMs in Rails 3 easily.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6265706250887913030-7046814332846828713?l=rwsleep.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ReadWriteSleep/~4/MuaT61S9v5U" height="1" width="1"/&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/January?a=qocqkYbn_2I:4CDN6gbgReA:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/January?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/January?a=qocqkYbn_2I:4CDN6gbgReA:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/January?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/January/~4/qocqkYbn_2I" height="1" width="1"/&gt;</description>
         <author>Jan</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-6265706250887913030.post-7046814332846828713</guid>
         <pubDate>Thu, 19 Mar 2009 00:59:00 -0700</pubDate>
      <feedburner:origLink>http://feedproxy.google.com/~r/ReadWriteSleep/~3/MuaT61S9v5U/activerecord-and-datamapper.html</feedburner:origLink></item>
      <item>
         <title>The problem is</title>
         <link>http://feedproxy.google.com/~r/January/~3/Y5FkKSndZcQ/problem-is.html</link>
         <description>"As is often the case when proving things about programming languages, the tricky part here is formulating a precise statement to be proved—the proof itself should be straightforward." - TAPL, pierce&lt;br /&gt;&lt;br /&gt;In schools students are always given clearly defined, already formalized questions, I think that's why the students feel uncomfortable when they come to the real world. I should spend more time on the mathematical modeling class when I was in university :(&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6265706250887913030-3264788476369724800?l=rwsleep.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ReadWriteSleep/~4/RuTnYROJ5Bg" height="1" width="1"/&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/January?a=Y5FkKSndZcQ:ZAdNgWcapQM:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/January?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/January?a=Y5FkKSndZcQ:ZAdNgWcapQM:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/January?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/January/~4/Y5FkKSndZcQ" height="1" width="1"/&gt;</description>
         <author>Jan</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-6265706250887913030.post-3264788476369724800</guid>
         <pubDate>Wed, 11 Mar 2009 00:13:00 -0700</pubDate>
      <feedburner:origLink>http://feedproxy.google.com/~r/ReadWriteSleep/~3/RuTnYROJ5Bg/problem-is.html</feedburner:origLink></item>
      <item>
         <title>Use rails.vim and merb.vim together</title>
         <link>http://feedproxy.google.com/~r/January/~3/H-frRBAi0iI/use-railsvim-and-merbvim-together.html</link>
         <description>I recently works on a merb project. As a vim user I found &lt;a rel="nofollow" target="_blank" href="http://github.com/nono/merb.vim/tree/master"&gt;merb.vim&lt;/a&gt; for syntax highlighting, but it will conflict with &lt;a rel="nofollow" target="_blank" href="http://www.vim.org/scripts/script.php?script_id=1567"&gt;rails.vim&lt;/a&gt;. For example, *before_filter* is a declaration in Rails controller, but in Merb it should *before*. After you installed merb.vim, it will set the file type of your controller file to ruby.merb_controller, so if you open a controller file in a rails project, the 'before_filter' will be highlighten as an error.&lt;br /&gt;&lt;br /&gt;The solution is to find a way to have directory/project specific setting for vim. Luckily it already exists.&lt;br /&gt;&lt;br /&gt;In you ~/.vimrc:&lt;br /&gt;&lt;br /&gt;set exrc&lt;br /&gt;&lt;br /&gt;Then move ~/.vim/ftdetect/merb.vim (this file is installed by merb.vim plugin) to $your_merb_project/.vimrc. Now the filetype setting for merb will only affects the merb project dir only.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6265706250887913030-1392348498731092247?l=rwsleep.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ReadWriteSleep/~4/Z0org4efo3g" height="1" width="1"/&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/January?a=H-frRBAi0iI:akI7rXQjha8:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/January?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/January?a=H-frRBAi0iI:akI7rXQjha8:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/January?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/January/~4/H-frRBAi0iI" height="1" width="1"/&gt;</description>
         <author>Jan</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-6265706250887913030.post-1392348498731092247</guid>
         <pubDate>Tue, 24 Feb 2009 15:56:00 -0800</pubDate>
      <feedburner:origLink>http://feedproxy.google.com/~r/ReadWriteSleep/~3/Z0org4efo3g/use-railsvim-and-merbvim-together.html</feedburner:origLink></item>
      <item>
         <title>Rules a Monad should follow</title>
         <link>http://feedproxy.google.com/~r/January/~3/o-B2MiD0SHg/rules-monad-should-follow.html</link>
         <description>I. return x &amp;gt;&amp;gt;= f === f x&lt;br /&gt;&lt;br /&gt;II. x &amp;gt;&amp;gt;= return === x&lt;br /&gt;&lt;br /&gt;III. m &amp;gt;&amp;gt;= (&amp;#92;x -&amp;gt; f x &amp;gt;&amp;gt;= g) === (m &amp;gt;&amp;gt;= f) &amp;gt;&amp;gt;= g&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6265706250887913030-437932400639421926?l=rwsleep.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ReadWriteSleep/~4/AcgaTVmE6QQ" height="1" width="1"/&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/January?a=o-B2MiD0SHg:VwJVDmxpezI:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/January?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/January?a=o-B2MiD0SHg:VwJVDmxpezI:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/January?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/January/~4/o-B2MiD0SHg" height="1" width="1"/&gt;</description>
         <author>Jan</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-6265706250887913030.post-437932400639421926</guid>
         <pubDate>Sun, 15 Feb 2009 21:32:00 -0800</pubDate>
      <feedburner:origLink>http://feedproxy.google.com/~r/ReadWriteSleep/~3/AcgaTVmE6QQ/rules-monad-should-follow.html</feedburner:origLink></item>
      <item>
         <title>Kernel#eval</title>
         <link>http://feedproxy.google.com/~r/January/~3/QeQPDtMKJB4/kerneleval.html</link>
         <description>There's an interesting post in ruby mailing list today. The discussion started by &lt;a rel="nofollow" target="_blank" href="http://thread.gmane.org/gmane.comp.lang.ruby.general/284375/focus=284422"&gt;a question asked by Jonathan Wills&lt;/a&gt;:&lt;br /&gt;&lt;blockquote&gt;a = 1&lt;br /&gt;eval('a=2')&lt;br /&gt;puts a&lt;br /&gt;&lt;br /&gt;This will print out '2', as I want. However if I remove the first line,&lt;br /&gt;&lt;br /&gt;eval('a=2')&lt;br /&gt;puts a&lt;br /&gt;&lt;br /&gt;r.rb:2:in ` ': undefined local variable or method `a' for&lt;br /&gt;main:Object (NameError)&lt;/blockquote&gt;&lt;br /&gt; Then &lt;a rel="nofollow" target="_blank" href="http://thread.gmane.org/gmane.comp.lang.ruby.general/284375/focus=284422"&gt;Mike Gold gives an excellent explaination&lt;/a&gt;:&lt;br /&gt;&lt;blockquote&gt;The thing to remember is that local variables are always determined at parse time.&lt;br /&gt;&lt;br /&gt;eval("a = 3", binding)&lt;br /&gt;p local_variables #=&amp;gt; ["a"]&lt;br /&gt;p a #=&amp;gt; undefined local variable or method `a'&lt;br /&gt;&lt;br /&gt;We see that the local exists, but because the parser has not seen the "a = ..." syntax, we can't access it.&lt;br /&gt;&lt;br /&gt;Locals are not handled in the same way. The local assignment syntax is subject to special examination by the parser. This does not happen for instance variables and globals. Again, it is the parser that determines locals. If all assignments were the same, this would print '3':&lt;br /&gt;&lt;br /&gt;eval("a = 3", binding)&lt;br /&gt;puts a&lt;br /&gt;&lt;br /&gt;Pickaxe gives this example:&lt;br /&gt;&lt;br /&gt;def a&lt;br /&gt;print "Function 'a' called&amp;#92;n"&lt;br /&gt;99&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;for i in 1..2&lt;br /&gt;if i == 2&lt;br /&gt;print "a=", a, "&amp;#92;n"&lt;br /&gt;else&lt;br /&gt;a = 1&lt;br /&gt;print "a=", a, "&amp;#92;n"&lt;br /&gt;end&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;produces:&lt;br /&gt;&lt;br /&gt;a=1&lt;br /&gt;Function 'a' called&lt;br /&gt;a=99&lt;/blockquote&gt;&lt;br /&gt;But constants and instance variables are different. Which means&lt;br /&gt;&lt;br /&gt;eval("@a=2")&lt;br /&gt;@a # =&amp;gt; 2&lt;br /&gt;&lt;br /&gt;Another interested thing Mike metioned is, when you see this error:&lt;br /&gt;&lt;br /&gt;undefined local variable or method `a' for main:Object (NameError)&lt;br /&gt;&lt;br /&gt;It in fact means 'undefined method a':&lt;br /&gt;&lt;blockquote&gt;... that error message comes from rb_method_missing(), i.e., it was determined to be a method call. Presumably it is worded that way for the user's benefit, in case there was a misspelling or some such. Locals are determined by the parser; method lookup is done when no such local exists.&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6265706250887913030-9118524556981708569?l=rwsleep.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ReadWriteSleep/~4/PYJwhRTM6gM" height="1" width="1"/&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/January?a=QeQPDtMKJB4:GVcnnesbtik:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/January?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/January?a=QeQPDtMKJB4:GVcnnesbtik:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/January?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/January/~4/QeQPDtMKJB4" height="1" width="1"/&gt;</description>
         <author>Jan</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-6265706250887913030.post-9118524556981708569</guid>
         <pubDate>Fri, 06 Feb 2009 17:13:00 -0800</pubDate>
      <feedburner:origLink>http://feedproxy.google.com/~r/ReadWriteSleep/~3/PYJwhRTM6gM/kerneleval.html</feedburner:origLink></item>
      <item>
         <title>Notes of Guy Steele's Lisp Processor Prototype</title>
         <link>http://feedproxy.google.com/~r/January/~3/BXpoD0-938g/notes-of-guy-steeles-lisp-processor.html</link>
         <description>The prototype in paper is different from the well known 'Lisp Machine' which in fact has a hybrid (traditional linear vector memory model + linked list model) architecture (e.g. based on TTL logic, with large ALU) while the prototype is totally build on linked list model (with embedded instruction set and almostly no ALU). The history of this project is a very interesting story :) For youth like me, it's hard to imagine that one obstacle of building such a processor is ALU is too large at that time ..&lt;br /&gt;&lt;br /&gt;And this paper make me think it's not fair to say modern GC (garbage collection) is an innovation from Lisp (you know some Lisp guys always like to say 'hey, XXX has already be seen in Lisp 30 years ago). As you can read from the paper, GC is an inevitable workaround to fill the gap between functional programming (which will produce lots of immutable intermedia) and von Neumann machine (finite memory), it's not invented to free programmers from C++'s malloc/free hell like Java (which is an imperative language). Like Watt found water can be heated into steam to drive machine is of course an innovation, but use water to generate electricity is a totally diffierent thing.&lt;br /&gt;&lt;br /&gt;Most of the contents below are copied from GLS &amp;amp; GJS's paper "Design of LISP-Based Processors", March 1979.&lt;br /&gt;&lt;br /&gt;== Notes of the paper ==&lt;br /&gt;&lt;br /&gt;An idea which has increasingly gained attention is that computer architectures should reflect specific language structures to be supported.&lt;br /&gt;&lt;br /&gt;Stored-program computer is such one that the program and the data reside in the same memory, the program is itself data which can be manipulated as any other data by the processor. Lisp is unusual among high-level languages in that it explicitly supports the stored-program idea, for this reason Lisp is often referred to as a 'high-level machine language'.&lt;br /&gt;&lt;br /&gt;One of the central ideas of the Lisp language is that storage management should be completely invisible to the programmer. Lisp is an object-oriented language, rather than a value-oriented language. The Lisp programmer does not think of variables as the objects of interest, bins in which values can be held. Instead, each data item is itself an object, which can be examined and modified, and which has an identity independent of the variable used to name it.&lt;br /&gt;&lt;br /&gt;A complete Lisp system is conveniently divided into two parts: (1) a storage system, which provides an operator for the creation of new data objects and also other operators (such as pointer traversal) on those objects; and (2) a program interpreter (EVAL), which executes programs expressed as data structures within the storage system. (Note that this memory/processor division characterizes the usual von Neumann architecture also. The differences occur in the nature of the processor and the memory system.)&lt;br /&gt;&lt;br /&gt;Commercially available memories are available only in finite sizes. Lisp (or functional language)'s free and wasteful throw-away use of data objects would be a disaster with finite memory. In order to make such memories useable to Lisp (or functional language) we must interpose between EVAL and the storage system a storage manager which makes a finite vector memory appear to the evaluation mechanism to be an infinite linked-record memory. The memory is "apparently infinite" in the sense that an indefinitely large number of new records can be "created" using the CONS operator. The storage manager recycles discarded records in order to create new ones in a manner completely invisible to the evaluator.&lt;br /&gt;&lt;br /&gt;The storage manager therefore consists of routines which implement the operations CAR, CDR, CONS, etc. in terms of the vector memory, plus a garbage collector which deals with the finiteness of the memory by locating records which have been discarded and making them available to the CONS routine for recycling.&lt;br /&gt;&lt;br /&gt;In Guy Steele's Lisp processor prototype, there is no garbage collector for some reason. And there's even no ALU! (In fact it have simplest arithmetic and logical capabilities, which can only add 1 and test for 0) This is interesting because Lisp itself is so simple that the interpreter needs no arithmetic to run interesting programs (such as computing symbolic derivatives and integrals, or pattern matching).&lt;br /&gt;&lt;br /&gt;This is not to say that real Lisp programs do not need arithmetic, just that the Lisp interpreter itself does not require binary arithmetic of the usual sort (but it does require CONS, CAR and CDR, which in a formal sense indeed form a kind of "number system", where CONS corresponds to "add 1" and both CAR and CDR to "substract 1". In this view, the purpose of the storage manager is to interface between two kinds of arithmetic, namely "Lisp arithmetic" and Peano arithmetic).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6265706250887913030-7092820717061230669?l=rwsleep.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ReadWriteSleep/~4/kXwe97xTvcU" height="1" width="1"/&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/January?a=BXpoD0-938g:_668WNk8ZcI:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/January?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/January?a=BXpoD0-938g:_668WNk8ZcI:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/January?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/January/~4/BXpoD0-938g" height="1" width="1"/&gt;</description>
         <author>Jan</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-6265706250887913030.post-7092820717061230669</guid>
         <pubDate>Tue, 03 Feb 2009 16:50:00 -0800</pubDate>
      <feedburner:origLink>http://feedproxy.google.com/~r/ReadWriteSleep/~3/kXwe97xTvcU/notes-of-guy-steeles-lisp-processor.html</feedburner:origLink></item>
      <item>
         <title>Understanding Git Concepts</title>
         <link>http://feedproxy.google.com/~r/January/~3/K0lBPpLg6D8/understanding-git-concepts.html</link>
         <description>Git in fact is a file system with history.&lt;br /&gt;&lt;br /&gt;All data is saved in git objects. All git objects has a 40bits id which generated by SHA-1 hashing the object's content. There're 4 types of objects:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;blob object: File contents is saved in blob object. No filenames/permissions etc, only contents is saved here.&lt;/li&gt;&lt;li&gt;tree object: Directory structure is saved here. Tree object's content is just a list of its children, either blob object or tree object. A list item will contain either a SHA-1 hash point to a blob object with filename/permissions/etc. or a hash point to a tree object. Here we have got a data structure(tree) which can represent a file system.&lt;/li&gt;&lt;li&gt;commit object: Now we need history. A commit object simple contains a pointer to tree, one or many pointer to parents(also commits) and some booking data like commiter. Commit objects in fact forms a tree graph on a higher layer of blob/tree.&lt;/li&gt;&lt;li&gt;tag object: Tag object is just for referencing an object conviniently. A tag object can have a pointer point to any other git object and a tag, then you can use the tag to reference any object(like an important commit) in your git repo.&lt;/li&gt;&lt;/ul&gt;A git object is immutable. Another concept in git system is Reference, for referencing mutable things like branch and remote.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Branch is just a file in .git/refs/heads/ dir contains the SHA-1 hash of the most recent commit to that branch. When you create a branch in git, git just create a file contains a 40 bytes hash in .git/refs/heads/, and update .git/HEAD to point to it. With your development moves on, git will find current branch in HEAD and update the branch file in refs/heads correctly.&lt;/li&gt;&lt;li&gt;Remote is a pointer to branch(so it's also a branch) in other people's copies of the same repo. If you get the code by clone instead of 'git init', git will add a default 'origin/master' remote branch for you automatically. 'origin' point to the remote copy location, and 'master' means which branch on remote you cloned from.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;When you ask for checking out, git will lookup the argument you provided in .git/refs or .git/HEAD, find the corresponding object/branch/tag/whatever, read the SHA-1 hash which points to a tree from its content, then traverse the tree.&lt;br /&gt;&lt;br /&gt;A fetch will merge all updates on a remote branch to your local. By default it will merge in changes on origin/master, but you can fetch updates on other place like origin/cool. After a series of fetch/merge your history graph will looks like a mess, rebase will help. Rebase will leave orphan objects in your repo(you can use 'git gc' to clean it) and should not be used on a repo which can be fetched by others.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6265706250887913030-2049279533234133037?l=rwsleep.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ReadWriteSleep/~4/xeAqLoYq4AQ" height="1" width="1"/&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/January?a=K0lBPpLg6D8:IfIx7oO16M4:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/January?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/January?a=K0lBPpLg6D8:IfIx7oO16M4:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/January?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/January/~4/K0lBPpLg6D8" height="1" width="1"/&gt;</description>
         <author>Jan</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-6265706250887913030.post-2049279533234133037</guid>
         <pubDate>Tue, 27 Jan 2009 23:11:00 -0800</pubDate>
      <feedburner:origLink>http://feedproxy.google.com/~r/ReadWriteSleep/~3/xeAqLoYq4AQ/understanding-git-concepts.html</feedburner:origLink></item>
      <item>
         <title>Evolutionary algorithm example in Ruby</title>
         <link>http://feedproxy.google.com/~r/January/~3/Yk_SKinUhNc/evolutionary-algorithm-example-in-ruby.html</link>
         <description>&lt;pre&gt;&lt;br /&gt;#!/usr/bin/ruby -w&lt;br /&gt;&lt;br /&gt;# This program is based on this evolutionar computation introduction:&lt;br /&gt;# http://blog.uncommons.org/2009/01/20/practical-evolutionary-computation-an-introduction/&lt;br /&gt;#&lt;br /&gt;# usage: ruby evolution.rb [generations] [goal]&lt;br /&gt;# example: ruby evolution.rb&lt;br /&gt;# ruby evolution.rb 100&lt;br /&gt;# ruby evolution.rb 100 "I make the universe"&lt;br /&gt;&lt;br /&gt;# We can set a goal(string) for evolution, and the Evolution object&lt;br /&gt;# will evolute towards the goal you set.&lt;br /&gt;class Evolution&lt;br /&gt; attr_accessor :set&lt;br /&gt;&lt;br /&gt; # The goal(string) can contain only upcase characters and space&lt;br /&gt; # CHARSET in fact is gene pool&lt;br /&gt; CHARSET = ('A'..'Z').to_a + [' ']&lt;br /&gt; CHARSET_LENGTH = CHARSET.length&lt;br /&gt;&lt;br /&gt; # goal: evolution goal is a string, like 'hello world'&lt;br /&gt; # population: the population of the society. default to 100, means&lt;br /&gt; # there're 100 parents in the initial environment. And&lt;br /&gt; # the environment can only support 100 livings.&lt;br /&gt; # mutation_rate: the possibility of gene mutation. default to 0.01,&lt;br /&gt; # means a gene 'A' in one generation has 1/100 possibility&lt;br /&gt; # to mutate to random gene in CHARSET&lt;br /&gt; def initialize(goal,population=100,mutation_rate=0.01)&lt;br /&gt; @goal = goal&lt;br /&gt; @population = population&lt;br /&gt; @mutation_rate = mutation_rate&lt;br /&gt;&lt;br /&gt; # @set is the environment all livings live in&lt;br /&gt; @set = []&lt;br /&gt; @strlen = goal.length&lt;br /&gt;&lt;br /&gt; # fill the environment with livings&lt;br /&gt; population.times {|i|&lt;br /&gt; str = ""&lt;br /&gt; @strlen.times {|j| str &amp;lt;&amp;lt; CHARSET[rand(CHARSET_LENGTH)] }&lt;br /&gt; @set &amp;lt;&amp;lt; str&lt;br /&gt; }&lt;br /&gt; end&lt;br /&gt;&lt;br /&gt; # evolution function&lt;br /&gt; # reproduce: how many generations should the evolution have&lt;br /&gt; def run(reproduce=1000)&lt;br /&gt; reproduce.times {|i| generation }&lt;br /&gt; sort_and_cut(@set).each {|s| puts "#{s} : #{score s}" }&lt;br /&gt; end&lt;br /&gt;&lt;br /&gt; private&lt;br /&gt;&lt;br /&gt; # one generation&lt;br /&gt; def generation&lt;br /&gt; score_set&lt;br /&gt; pick&lt;br /&gt; crossover&lt;br /&gt; mutation&lt;br /&gt; end&lt;br /&gt;&lt;br /&gt; # give mutation chance to every living in our environment&lt;br /&gt; def mutation&lt;br /&gt; k = 1/@mutation_rate&lt;br /&gt; for str in @set&lt;br /&gt; str.length.times {|i|&lt;br /&gt; str[i] = CHARSET[rand(CHARSET_LENGTH)] if rand(k) == 0&lt;br /&gt; }&lt;br /&gt; end&lt;br /&gt; end&lt;br /&gt;&lt;br /&gt; # choose two parent&lt;br /&gt; # produce offspring&lt;br /&gt; def crossover&lt;br /&gt; set = @set.uniq&lt;br /&gt;&lt;br /&gt; offsprings = []&lt;br /&gt; if set.length == 1&lt;br /&gt; offsprings = @set&lt;br /&gt; else&lt;br /&gt; (set.length-1).times {|i|&lt;br /&gt; (i+1).upto(set.length-1) {|j|&lt;br /&gt; pivot = rand(@strlen) + 1&lt;br /&gt; par1_a, par1_b = set[i][0,pivot], set[i][pivot,@strlen]&lt;br /&gt; par2_a, par2_b = set[j][0,pivot], set[j][pivot,@strlen]&lt;br /&gt; offsprings &amp;lt;&amp;lt; "#{par1_a}#{par2_b}"&lt;br /&gt; offsprings &amp;lt;&amp;lt; "#{par2_a}#{par1_b}"&lt;br /&gt; }&lt;br /&gt; }&lt;br /&gt; end&lt;br /&gt;&lt;br /&gt; @set = sort_and_cut(offsprings)&lt;br /&gt; end&lt;br /&gt;&lt;br /&gt; # pick the good candicates (high score)&lt;br /&gt; # score 2 candicate will have high possiblity to be choosen than score&lt;br /&gt; # 1 candicate&lt;br /&gt; def pick&lt;br /&gt; pool = []&lt;br /&gt; @score_map.each {|str,score|&lt;br /&gt; score.times {|i|&lt;br /&gt; pool &amp;lt;&amp;lt; str&lt;br /&gt; }&lt;br /&gt; }&lt;br /&gt; pool.sort! {|a,b| rand(3) - 1} # shuffle&lt;br /&gt; pool_len = pool.length&lt;br /&gt; &lt;br /&gt; @set = []&lt;br /&gt; @population.times {|i|&lt;br /&gt; @set &amp;lt;&amp;lt; pool[rand(pool_len)]&lt;br /&gt; }&lt;br /&gt; end&lt;br /&gt;&lt;br /&gt; # compute score for every candicates&lt;br /&gt; def score_set&lt;br /&gt; @score_map = {}&lt;br /&gt; for str in @set&lt;br /&gt; @score_map[str] = score(str)&lt;br /&gt; end&lt;br /&gt; @score_map&lt;br /&gt; end&lt;br /&gt;&lt;br /&gt; # score will tell us the simliarity between the str and goal&lt;br /&gt; # score = the same character on the correct position with goal&lt;br /&gt; def score(str)&lt;br /&gt; score = 0&lt;br /&gt; @strlen.times {|i|&lt;br /&gt; score += 1 if str[i] == @goal[i]&lt;br /&gt; }&lt;br /&gt; score&lt;br /&gt; end&lt;br /&gt;&lt;br /&gt; # sort livings by score and only the livings with highest score&lt;br /&gt; # will left. They're the selection of nature.&lt;br /&gt; def sort_and_cut(set)&lt;br /&gt; set.sort_by {|s| -(score s)}[0,@population]&lt;br /&gt; end&lt;br /&gt;&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;if __FILE__ == $0&lt;br /&gt; times = ARGV[0] ? ARGV[0].to_i : 20&lt;br /&gt; goal = ARGV[1] ? ARGV[1].upcase : 'HELLO WORLD'&lt;br /&gt; e = Evolution.new(goal)&lt;br /&gt; e.run times&lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6265706250887913030-8710427874326697526?l=rwsleep.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ReadWriteSleep/~4/TS5WxWERsCA" height="1" width="1"/&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/January?a=Yk_SKinUhNc:SES2zPKNDns:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/January?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/January?a=Yk_SKinUhNc:SES2zPKNDns:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/January?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/January/~4/Yk_SKinUhNc" height="1" width="1"/&gt;</description>
         <author>Jan</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-6265706250887913030.post-8710427874326697526</guid>
         <pubDate>Sat, 24 Jan 2009 16:07:00 -0800</pubDate>
      <feedburner:origLink>http://feedproxy.google.com/~r/ReadWriteSleep/~3/TS5WxWERsCA/evolutionary-algorithm-example-in-ruby.html</feedburner:origLink></item>
      <item>
         <title>Haskell Functor Typeclass</title>
         <link>http://feedproxy.google.com/~r/January/~3/tB49CcknedY/haskell-functor-typeclass.html</link>
         <description>A correct functor instance should follow two rules:&lt;br /&gt;&lt;br /&gt;fmap id == id&lt;br /&gt;fmap (f . g) == fmap f . fmap g&lt;br /&gt;&lt;br /&gt;In natural words, functor should keep data's structure, only change it's value. This rule can't be guranteed by compiler, so we have to remember it by ourselves when implement a functor instance.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6265706250887913030-9034956036155237248?l=rwsleep.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ReadWriteSleep/~4/g3X70oieS-U" height="1" width="1"/&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/January?a=tB49CcknedY:R47sUlwTADc:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/January?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/January?a=tB49CcknedY:R47sUlwTADc:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/January?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/January/~4/tB49CcknedY" height="1" width="1"/&gt;</description>
         <author>Jan</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-6265706250887913030.post-9034956036155237248</guid>
         <pubDate>Tue, 13 Jan 2009 19:01:00 -0800</pubDate>
      <feedburner:origLink>http://feedproxy.google.com/~r/ReadWriteSleep/~3/g3X70oieS-U/haskell-functor-typeclass.html</feedburner:origLink></item>
      <item>
         <title>Functional interpreter and program modularity</title>
         <link>http://feedproxy.google.com/~r/January/~3/BbbXYM-3EjU/functional-interpreter-and-program.html</link>
         <description>The purpose of programming tech evolution is modularity. To get modularity, people need abstractions. What's the differences between abstraction and type-saving sugars? A good package of common patterns (abstraction) encapsulates a higher level concept which has meaning *independent* of its implementation.&lt;br /&gt;&lt;br /&gt;A package is most useful if its behavior is independent of the context(environment/global resource/etc.) of its use. Such a package is called referentially transparent. In other words, the output(behavior) of a referentially transparent package(function) will always be the same with the same input, because the explictly provided input data is the only source it depends. (What does 'same' mean here is an interesting problem, we'll see later)&lt;br /&gt;&lt;br /&gt;To make a modular system, it is often necessary to think of a computational process as having state. In such cases, if the state can be naturally divided into independent parts, an important decomposition may be the division of the program into pieces which separately deal with the part of the state.&lt;br /&gt;&lt;br /&gt;Referential transparency will permit programs to be divided into parts so that each part can be separately specified without a description of its implementation. The desirable result is that pieces can be separately written and debugged. At first people made no free variable recusive interpreter[1] with seperated variable bindings (Environment) and procedure bindings. It's expressive power is very litmited.&lt;br /&gt;&lt;br /&gt;Seperate Env and Procedure symbol tables will make procedure 2nd-class concept (thus you can't define a 'map' function in the interpreter), but merge these two table unintentionally bring in two property: free variables (in fact, before merge, procedure symbols are free variables, but they're not real 'variables' at that time) and dynamic scope variables.&lt;br /&gt;&lt;br /&gt;To avoid function name conflicts, it would be nice to have a notation for functions as objects, or rather a way to write an sexp in code that would evaluate to a procedure. Lisp adapted such a notation from lambda calculus of Alonzo Church.&lt;br /&gt;&lt;br /&gt;But lambda plus dynamic scoping will lead to the famous 'FUNARG' problem, so we need lexical scoping. What we want is when computing a lambda, use the environment in which it's evaluated instead of the environment in which it's executed. The solution is simply save the environment in the procedure object when evaluate a lambda (or function, they're the same thing, function is just a lambda with a name in symbol table). Within this change, we say that the procedure is closed in the current environment, and the procedure object is therefore called a *closure* of the procedure, or a *closed procedure*.&lt;br /&gt;&lt;br /&gt;The problem of lexical scope is in the REPL: the new definition can only refer to previously defined names! We lose the ablity to define recursive procedure. This conflict, between REPL and lexical scope, is unavoidable, because such a incremental interactive top level loop for reading definitions inherently constitutes a violation of referential transparency, which we successfully got in our interpreter. A piece of code can be read in which refers to an as yet undefined identifier (the name of a procedure), and then later a definition for that identifier read in (thereby altering the meaning of the reference). If we insist on maintaining absolute referential transparency, we are forced to eliminate the incremental top level interaction, to give up interactive debugging (we can't redefine erroneous procedures easily), to give up incremental compilation of separate modules.&lt;br /&gt;&lt;br /&gt;If we throw lexical scoping away and turn back to dynamic scoping we would lose a great deal of referential transparency and abstractive power. The solution can be a mixture: procedures must not be allowed to refer to variables internal to other procedures, but only to top-level variables existing at the time they are called. Therefore only the future top-level environment is to be included in the procedure object when it is eventually constructed. In this way free variable references will be dynamic only with respect to the top-level environment.&lt;br /&gt;&lt;br /&gt;At this stage, we made our functions really referencial transparency, with no side effect. No side effect means no state, no state means you have to pass states up and down (as functions input and output) through the whole system. So no side effects conflicts with modular discipline. We are forced to introduce side effects as a technique for constructing modular systems. But side effects violate referential transparency, now we have two techniques for achieving modularity have come into direct conflict.&lt;br /&gt;&lt;br /&gt;The concept of side effect is induced by particular choices of boundaries between parts of a larger system. If a system boundary encloses all processes of interest (the system is closed), we need no concept of side effect to describe that system as a whole in vacuo. If we wish to make an abstraction by dividing the system into modules more than one of which has independent state, then we have by this action created the concept of side effect.&lt;br /&gt;&lt;br /&gt;The concept of side effect is inseparable from the notion of equality/identity/sameness. The only way one can observationally determine that a side effect has occurred is when the same object behaves in two different ways at different times. Conversely, the only way one can determine that two objects are the same is to perform a side effect on one and look for an appropriate change in the behavior of the other.&lt;br /&gt;&lt;br /&gt;if CONS return new object on every call, then it has side effect! Because with the same input, it will generate different output (a totally new object).&lt;br /&gt;&lt;br /&gt;If side effect are to be usable at all, the references to things denoted by variables must not make copies of those things. If the user is to be able to write procedures which produce lasting side effects on their arguments, then there must be a variable binding mechanism which does not make copies.&lt;br /&gt;&lt;br /&gt;The ideal equality predicate should follow these two rules:&lt;br /&gt;&lt;br /&gt;1). Two objects which are observed to behave differently must not be equal.&lt;br /&gt;2). Conversely, we would like two objects which are adjudged unequal to exhibit differing behaviors under suitable circumstances.&lt;br /&gt;&lt;br /&gt;Any useful equality predicate must satisfy 1), but it's hard to satisfy 2). (Another interesting view is, equality predicate should never be false-positive, but may be false-negative)&lt;br /&gt;&lt;br /&gt;Based on above two rules: in the absence of RPLACA ("pure lisp"), EQUAL is preffered to EQ (like (==) in haskell); in the presence of side effects such as RPLACA, EQ is preferred to EQUAL.&lt;br /&gt;&lt;br /&gt;Finally we found set-use-reset pattern is very helpful for modularity, and dynamic scope captures this pattern well. So we want to have both dynamic and lexical scope variables in our interpreter. We need to maintain separate environments for lexical and dynamic variables in interpreter to avoid certain problems. This will require a special syntax for distinguishing references to and bindings of the two kinds of variables.&lt;br /&gt;&lt;br /&gt;Dynamic scoping provides an important abstraction for dealing with side effects in a controlled way. A low-level procedure may have state variables which are not of interest to intermedia routines, but which must be controlled at a high level. Dynamic scoping allows any procedure to get access to parts of the state when necessary, but permits most procedures to ignore the existence of the state variables. The existence of many dynamic variables permits the decomposition of the state in such a way that only the part of interest need be deal with.&lt;br /&gt;&lt;br /&gt;[1] LISP was not originally derived from Church's lambda calculus. In early LISP ppl use "McCarthy conditional" to define recursion:&lt;br /&gt;&lt;br /&gt;factorial[x] = [x=0 -&amp;gt; 1; T -&amp;gt; x*factorial[x-1]]&lt;br /&gt;&lt;br /&gt;while in resursive function theory one would define it like this:&lt;br /&gt;&lt;br /&gt;factorial(0) = 1&lt;br /&gt;factorial(successor(x)) = successor(x) * factorial(x)&lt;br /&gt;&lt;br /&gt;haskell adopt the later notion, while keep the first one too (case expression)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6265706250887913030-773844547472875074?l=rwsleep.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ReadWriteSleep/~4/DXd66e-rOaI" height="1" width="1"/&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/January?a=BbbXYM-3EjU:ZO9bBWxiyKo:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/January?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/January?a=BbbXYM-3EjU:ZO9bBWxiyKo:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/January?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/January/~4/BbbXYM-3EjU" height="1" width="1"/&gt;</description>
         <author>Jan</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-6265706250887913030.post-773844547472875074</guid>
         <pubDate>Sat, 03 Jan 2009 21:19:00 -0800</pubDate>
      <feedburner:origLink>http://feedproxy.google.com/~r/ReadWriteSleep/~3/DXd66e-rOaI/functional-interpreter-and-program.html</feedburner:origLink></item>
      <item>
         <title>Bloom filter</title>
         <link>http://feedproxy.google.com/~r/January/~3/RUiRfixPXZY/bloom-filter.html</link>
         <description>An empty &lt;a rel="nofollow" target="_blank" href="http://en.wikipedia.org/wiki/Bloom_filter"&gt;Bloom filter&lt;/a&gt; is a bit array of m bits, all set to 0. There must also be k different hash functions defined, each of which maps or hashes some set element to one of the m array positions with an even distribution.&lt;br /&gt;&lt;br /&gt;To add an element, feed it to each of the k hash functions to get k array positions. Set the bits at all these positions to 1.&lt;br /&gt;&lt;br /&gt;To query for an element (test whether it is in the set), feed it to each of the k hash functions to get k array positions. If any of the bits at these positions are 0, the element is not in the set – if it were, then all the bits would have been set to 1 when it was inserted. If all are 1, then either the element is in the set, or the bits have been set to 1 during the insertion of other elements.&lt;br /&gt;&lt;br /&gt;&lt;a rel="nofollow" target="_blank" href="http://en.wikipedia.org/wiki/Type_I_and_type_II_errors"&gt;False positive is possible, false negative is impossible&lt;/a&gt; for bloom filter.&lt;br /&gt;&lt;br /&gt;False Positive can be understanded as a "failed positive assertion", e.g. If I report to teacher you cheated in the last exam but in fact you didn't. In bloom filter case, it means the filter may report you the keyword 'd' exists in the set {'a','b','c'}, but the filter will never tell you 'a' or 'b' or 'c' not exists in the same set.&lt;br /&gt;&lt;br /&gt;&lt;a rel="nofollow" target="_blank" href="http://www.igvita.com/2008/12/27/scalable-datasets-bloom-filters-in-ruby/"&gt;igvita provides a ruby implementation&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6265706250887913030-2331821063672848359?l=rwsleep.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ReadWriteSleep/~4/bKOJSeaYiu4" height="1" width="1"/&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/January?a=RUiRfixPXZY:jVW88KwVFA0:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/January?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/January?a=RUiRfixPXZY:jVW88KwVFA0:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/January?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/January/~4/RUiRfixPXZY" height="1" width="1"/&gt;</description>
         <author>Jan</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-6265706250887913030.post-2331821063672848359</guid>
         <pubDate>Sat, 27 Dec 2008 20:04:00 -0800</pubDate>
      <feedburner:origLink>http://feedproxy.google.com/~r/ReadWriteSleep/~3/bKOJSeaYiu4/bloom-filter.html</feedburner:origLink></item>
      <item>
         <title>Rails: ActionController#render become more smarter</title>
         <link>http://feedproxy.google.com/~r/January/~3/xmatoq6P2dI/rails-actioncontrollerrender-become.html</link>
         <description>&lt;a rel="nofollow" target="_blank" href="http://github.com/lifo"&gt;Pratik Naik&lt;/a&gt; pushed a series of commits to make ActionController#render more easy to use.&lt;br /&gt;&lt;br /&gt;1. &lt;a rel="nofollow" target="_blank" href="http://github.com/rails/rails/commit/cd1d6e8768ae13b11bc343701037b20ad35e6f1e"&gt;It will recognize actions&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt; # Instead of render(:action =&amp;gt; 'other_action')&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt; render('other_action')&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;2. &lt;a rel="nofollow" target="_blank" href="http://github.com/rails/rails/commit/d67e03871eabb912434dafac3eeb8e6ea7c5585f"&gt;It will recognize templates&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt; # Instead of render(:template =&amp;gt; 'controller/action')&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt; render('controller/action')&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;3. &lt;a rel="nofollow" target="_blank" href="http://github.com/rails/rails/commit/061952392afd1dae1aa97a816e9a0c79df7c4514"&gt;It will recognize a file path&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt; # Instead of render(:file =&amp;gt; '/Users/lifo/home.html.erb')&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt; render('/Users/lifo/home.html.erb')&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;4. &lt;a rel="nofollow" target="_blank" href="http://github.com/rails/rails/commit/80307c8b0a889acc7abb7f4e52fd4c02e"&gt;It will recognize a symbol&lt;/a&gt;. So in your create action you can just write 'render :new' when model save failed!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6265706250887913030-2047481023969953096?l=rwsleep.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ReadWriteSleep/~4/hhJQPDisxRg" height="1" width="1"/&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/January?a=xmatoq6P2dI:rjvlw9pdrkc:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/January?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/January?a=xmatoq6P2dI:rjvlw9pdrkc:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/January?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/January/~4/xmatoq6P2dI" height="1" width="1"/&gt;</description>
         <author>Jan</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-6265706250887913030.post-2047481023969953096</guid>
         <pubDate>Thu, 25 Dec 2008 10:14:00 -0800</pubDate>
      <feedburner:origLink>http://feedproxy.google.com/~r/ReadWriteSleep/~3/hhJQPDisxRg/rails-actioncontrollerrender-become.html</feedburner:origLink></item>
      <item>
         <title>TDD and BDD</title>
         <link>http://feedproxy.google.com/~r/January/~3/1NrFn28RS_Q/tdd-and-bdd.html</link>
         <description>&lt;span style="font-style:italic;"&gt;Update1: I found I misunderstanded TDD, now I confused with BDD again :(see comments below)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt;Update2: Someone asked me that why we should write tests first? If we write tests immediately after implement a function, what we lose compare to write test first? My answer is simple: how can you know you test will fail before you write the implementation if you don't write test at first? And how can you make sure it's your code made the test pass, not because the test will pass even without your code?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;What's the differences between &lt;a rel="nofollow" target="_blank" href="http://en.wikipedia.org/wiki/Test-driven_development"&gt;TDD&lt;/a&gt; and &lt;a rel="nofollow" target="_blank" href="http://en.wikipedia.org/wiki/Behavior_driven_development"&gt;BDD&lt;/a&gt;? That's always a good candidate question for you recruiting :) It's hard to get the answer from their boring description, at least hard to me.&lt;br /&gt;&lt;br /&gt;Today I found a good example to demonstrate the diff between them - Rails validations. For those who don't use rails, validations is used to guard data correctness, for example, if I wrote this in my rails app:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt;class Book&lt;/span&gt; &amp;lt; style="font-style: italic;"&amp;gt; validates_presence_of :title&lt;br /&gt;&lt;span style="font-style:italic;"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;it will always check the Book's title is not blank when save the object. Now the problem is, should you write tests/assertions for this statement?&lt;br /&gt;&lt;br /&gt;TDD will say no. Rails is released with lots of tests, the validation's correctness has already been guaranteed by it, in other words your own tests are just duplicate works. But from BDDer's POV, you should write tests for it - to describe the Book's *behavior*, not to cover the validation's implementation code.&lt;br /&gt;&lt;br /&gt;So, BDD want to make sure we implemented the right behavior, or function/feature/whatever. If you refactor your code one month later, those seems redundant tests will guarantee your app's behavior is consistent after your refactor.&lt;br /&gt;&lt;br /&gt;This gap between TDD/BDD will lead a inference: 100% code coverage suggests you did very well in a TDD team, but it means nothing if you're in a BDD team. As the example shows, even you didn't write test for the validation, your test will cover it(you tests definitely will save a book object somewhere, thus emit the validation), but you won't know whether your books will still require a title after refactor.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6265706250887913030-2327831753363049869?l=rwsleep.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ReadWriteSleep/~4/daUOBmDd1vk" height="1" width="1"/&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/January?a=1NrFn28RS_Q:_vkoeTHWEJY:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/January?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/January?a=1NrFn28RS_Q:_vkoeTHWEJY:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/January?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/January/~4/1NrFn28RS_Q" height="1" width="1"/&gt;</description>
         <author>Jan</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-6265706250887913030.post-2327831753363049869</guid>
         <pubDate>Mon, 22 Dec 2008 22:05:00 -0800</pubDate>
      <feedburner:origLink>http://feedproxy.google.com/~r/ReadWriteSleep/~3/daUOBmDd1vk/tdd-and-bdd.html</feedburner:origLink></item>
      <item>
         <title>Haskell Numeric Types</title>
         <link>http://feedproxy.google.com/~r/January/~3/8TamMboFEWU/haskell-numeric-types.html</link>
         <description>From &lt;a rel="nofollow" target="_blank" href="http://book.realworldhaskell.org/read/using-typeclasses.html"&gt;http://book.realworldhaskell.org/read/using-typeclasses.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="table"&gt;&lt;p class="title"&gt;&lt;b&gt;Table 6.1. Selected Numeric Types&lt;/b&gt;&lt;/p&gt;&lt;div class="table-contents"&gt;&lt;table border="1"&gt;&lt;colgroup&gt;&lt;col align="left"&gt;&lt;col align="left"&gt;&lt;/colgroup&gt;&lt;thead&gt;&lt;tr&gt;&lt;th align="left"&gt;Type&lt;/th&gt;&lt;th align="left"&gt;Description&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;Double&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;Double-precision floating point. A common choice for floating-point data.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;Float&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;Single-precision floating point. Often used when interfacing with C.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;Int&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;Fixed-precision signed integer; minimum range [-2^29..2^29-1]. Commonly used.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;Int8&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;8-bit signed integer&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;Int16&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;16-bit signed integer&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;Int32&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;32-bit signed integer&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;Int64&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;64-bit signed integer&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;Integer&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;Arbitrary-precision signed integer; range limited only by machine resources. Commonly used.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;Rational&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;Arbitrary-precision rational numbers. Stored as a ratio of two &lt;code class="literal"&gt;Integer&lt;/code&gt;s.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;Word&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;Fixed-precision unsigned integer; storage size same as &lt;code class="literal"&gt;Int&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;Word8&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;8-bit unsigned integer&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;Word16&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;16-bit unsigned integer&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;Word32&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;32-bit unsigned integer&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;Word64&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;64-bit unsigned integer&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;p id="x_mB"&gt;&lt;a rel="nofollow" name="x_mB"&gt;&lt;/a&gt;&lt;/p&gt;&lt;br /&gt;&lt;div class="table"&gt;&lt;p class="title"&gt;&lt;b&gt;Table 6.2. Selected Numeric Functions and Constants&lt;/b&gt;&lt;/p&gt;&lt;div class="table-contents"&gt;&lt;table border="1"&gt;&lt;colgroup&gt;&lt;col align="left"&gt;&lt;col align="left"&gt;&lt;col align="left"&gt;&lt;col align="left"&gt;&lt;/colgroup&gt;&lt;thead&gt;&lt;tr&gt;&lt;th align="left"&gt;Item&lt;/th&gt;&lt;th align="left"&gt;Type&lt;/th&gt;&lt;th align="left"&gt;Module&lt;/th&gt;&lt;th align="left"&gt;Description&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;(+)&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;Num a =&amp;gt; a -&amp;gt; a -&amp;gt; a&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;Prelude&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;Addition&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;(-)&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;Num a =&amp;gt; a -&amp;gt; a -&amp;gt; a&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;Prelude&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;Subtraction&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;(*)&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;Num a =&amp;gt; a -&amp;gt; a -&amp;gt; a&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;Prelude&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;Multiplication&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;(/)&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;Fractional a =&amp;gt; a -&amp;gt; a -&amp;gt; a&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;Prelude&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;Fractional division&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;(**)&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;Floating a =&amp;gt; a -&amp;gt; a -&amp;gt; a&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;Prelude&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;Raise to the power of&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;(^)&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;(Num a, Integral b) =&amp;gt; a -&amp;gt; b -&amp;gt; a&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;Prelude&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;Raise a number to a non-negative, integral power&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;(^^)&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;(Fractional a, Integral b) =&amp;gt; a -&amp;gt; b -&amp;gt; a&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;Prelude&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;Raise a fractional number to any integral power&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;(%)&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;Integral a =&amp;gt; a -&amp;gt; a -&amp;gt; Ratio a&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;Data.Ratio&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;Ratio composition&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;(.&amp;amp;.)&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;Bits a =&amp;gt; a -&amp;gt; a -&amp;gt; a&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;Data.Bits&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;Bitwise and&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;(.|.)&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;Bits a =&amp;gt; a -&amp;gt; a -&amp;gt; a&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;Data.Bits&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;Bitwise or&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;abs&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;Num a =&amp;gt; a -&amp;gt; a&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;Prelude&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;Absolute value&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;approxRational&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;RealFrac a =&amp;gt; a -&amp;gt; a -&amp;gt; Rational&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;Data.Ratio&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;Approximate rational composition based on fractional numerators and denominators&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;cos&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;Floating a =&amp;gt; a -&amp;gt; a&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;Prelude&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;Cosine. Also provided are &lt;code class="literal"&gt;acos&lt;/code&gt;, &lt;code class="literal"&gt;cosh&lt;/code&gt;, and &lt;code class="literal"&gt;acosh&lt;/code&gt;, with the same type.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;div&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;Integral a =&amp;gt; a -&amp;gt; a -&amp;gt; a&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;Prelude&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;Integer division always truncated down; see also &lt;code class="literal"&gt;quot&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;fromInteger&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;Num a =&amp;gt; Integer -&amp;gt; a&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;Prelude&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;Conversion from an &lt;code class="literal"&gt;Integer&lt;/code&gt; to any numeric type&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;fromIntegral&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;(Integral a, Num b) =&amp;gt; a -&amp;gt; b&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;Prelude&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;More general conversion from any &lt;code class="literal"&gt;Integral&lt;/code&gt; to any numeric type&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;fromRational&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;Fractional a =&amp;gt; Rational -&amp;gt; a&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;Prelude&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;Conversion from a &lt;code class="literal"&gt;Rational&lt;/code&gt;. May be lossy.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;log&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;Floating a =&amp;gt; a -&amp;gt; a&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;Prelude&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;Natural logarithm&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;logBase&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;Floating a =&amp;gt; a -&amp;gt; a -&amp;gt; a&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;Prelude&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;Log with explicit base&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;maxBound&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;Bounded a =&amp;gt; a&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;Prelude&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;The maximum value of a bounded type&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;minBound&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;Bounded a =&amp;gt; a&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;Prelude&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;The minimum value of a bounded type&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;mod&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;Integral a =&amp;gt; a -&amp;gt; a -&amp;gt; a&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;Prelude&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;Integer modulus&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;pi&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;Floating a =&amp;gt; a&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;Prelude&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;Mathematical constant pi&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;quot&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;Integral a =&amp;gt; a -&amp;gt; a -&amp;gt; a&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;Prelude&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;Integer division; fractional part of quotient truncated towards zero&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;recip&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;Fractional a =&amp;gt; a -&amp;gt; a&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;Prelude&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;Reciprocal&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;rem&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;Integral a =&amp;gt; a -&amp;gt; a -&amp;gt; a&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;Prelude&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;Remainder of integer division&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;round&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;(RealFrac a, Integral b) =&amp;gt; a -&amp;gt; b&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;Prelude&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;Rounds to nearest integer&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;shift&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;Bits a =&amp;gt; a -&amp;gt; Int -&amp;gt; a&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;Bits&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;Shift left by the specified number of bits, which may be negative for a right shift.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;sin&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;Floating a =&amp;gt; a -&amp;gt; a&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;Prelude&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;Sine. Also provided are &lt;code class="literal"&gt;asin&lt;/code&gt;, &lt;code class="literal"&gt;sinh&lt;/code&gt;, and &lt;code class="literal"&gt;asinh&lt;/code&gt;, with the same type.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;sqrt&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;Floating a =&amp;gt; a -&amp;gt; a&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;Prelude&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;Square root&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;tan&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;Floating a =&amp;gt; a -&amp;gt; a&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;Prelude&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;Tangent. Also provided are &lt;code class="literal"&gt;atan&lt;/code&gt;, &lt;code class="literal"&gt;tanh&lt;/code&gt;, and &lt;code class="literal"&gt;atanh&lt;/code&gt;, with the same type.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;toInteger&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;Integral a =&amp;gt; a -&amp;gt; Integer&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;Prelude&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;Convert any &lt;code class="literal"&gt;Integral&lt;/code&gt; to an &lt;code class="literal"&gt;Integer&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;toRational&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;Real a =&amp;gt; a -&amp;gt; Rational&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;Prelude&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;Convert losslessly to &lt;code class="literal"&gt;Rational&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;truncate&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;(RealFrac a, Integral b) =&amp;gt; a -&amp;gt; b&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;Prelude&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;Truncates number towards zero&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;xor&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;Bits a =&amp;gt; a -&amp;gt; a -&amp;gt; a&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;Data.Bits&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;Bitwise exclusive or&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="table"&gt;&lt;a rel="nofollow" name="numerictypes.typeclasses"&gt;&lt;/a&gt;&lt;p class="title"&gt;&lt;b&gt;Table 6.3. Typeclass Instances for Numeric Types&lt;/b&gt;&lt;/p&gt;&lt;div class="table-contents"&gt;&lt;table border="1" width="100%"&gt;&lt;colgroup&gt;&lt;col align="left"&gt;&lt;col align="left"&gt;&lt;col align="left"&gt;&lt;col align="left"&gt;&lt;col align="left"&gt;&lt;col align="left"&gt;&lt;col align="left"&gt;&lt;col align="left"&gt;&lt;col align="left"&gt;&lt;/colgroup&gt;&lt;thead&gt;&lt;tr&gt;&lt;th align="left"&gt;Type&lt;/th&gt;&lt;th align="left"&gt;&lt;code class="literal"&gt;Bits&lt;/code&gt;&lt;/th&gt;&lt;th align="left"&gt;&lt;code class="literal"&gt;Bounded&lt;/code&gt;&lt;/th&gt;&lt;th align="left"&gt;&lt;code class="literal"&gt;Floating&lt;/code&gt;&lt;/th&gt;&lt;th align="left"&gt;&lt;code class="literal"&gt;Fractional&lt;/code&gt;&lt;/th&gt;&lt;th align="left"&gt;&lt;code class="literal"&gt;Integral&lt;/code&gt;&lt;/th&gt;&lt;th align="left"&gt;&lt;code class="literal"&gt;Num&lt;/code&gt;&lt;/th&gt;&lt;th align="left"&gt;&lt;code class="literal"&gt;Real&lt;/code&gt;&lt;/th&gt;&lt;th align="left"&gt;&lt;code class="literal"&gt;RealFrac&lt;/code&gt;&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;Double&lt;/code&gt;&lt;/td&gt;&lt;td class="auto-generated"&gt;&lt;br /&gt;&lt;/td&gt;&lt;td class="auto-generated"&gt;&lt;br /&gt;&lt;/td&gt;&lt;td align="left"&gt;X&lt;/td&gt;&lt;td align="left"&gt;X&lt;/td&gt;&lt;td class="auto-generated"&gt;&lt;br /&gt;&lt;/td&gt;&lt;td align="left"&gt;X&lt;/td&gt;&lt;td align="left"&gt;X&lt;/td&gt;&lt;td align="left"&gt;X&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;Float&lt;/code&gt;&lt;/td&gt;&lt;td class="auto-generated"&gt;&lt;br /&gt;&lt;/td&gt;&lt;td class="auto-generated"&gt;&lt;br /&gt;&lt;/td&gt;&lt;td align="left"&gt;X&lt;/td&gt;&lt;td align="left"&gt;X&lt;/td&gt;&lt;td class="auto-generated"&gt;&lt;br /&gt;&lt;/td&gt;&lt;td align="left"&gt;X&lt;/td&gt;&lt;td align="left"&gt;X&lt;/td&gt;&lt;td align="left"&gt;X&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;Int&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;X&lt;/td&gt;&lt;td align="left"&gt;X&lt;/td&gt;&lt;td class="auto-generated"&gt;&lt;br /&gt;&lt;/td&gt;&lt;td class="auto-generated"&gt;&lt;br /&gt;&lt;/td&gt;&lt;td align="left"&gt;X&lt;/td&gt;&lt;td align="left"&gt;X&lt;/td&gt;&lt;td align="left"&gt;X&lt;/td&gt;&lt;td class="auto-generated"&gt;&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;Int16&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;X&lt;/td&gt;&lt;td align="left"&gt;X&lt;/td&gt;&lt;td class="auto-generated"&gt;&lt;br /&gt;&lt;/td&gt;&lt;td class="auto-generated"&gt;&lt;br /&gt;&lt;/td&gt;&lt;td align="left"&gt;X&lt;/td&gt;&lt;td align="left"&gt;X&lt;/td&gt;&lt;td align="left"&gt;X&lt;/td&gt;&lt;td class="auto-generated"&gt;&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;Int32&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;X&lt;/td&gt;&lt;td align="left"&gt;X&lt;/td&gt;&lt;td class="auto-generated"&gt;&lt;br /&gt;&lt;/td&gt;&lt;td class="auto-generated"&gt;&lt;br /&gt;&lt;/td&gt;&lt;td align="left"&gt;X&lt;/td&gt;&lt;td align="left"&gt;X&lt;/td&gt;&lt;td align="left"&gt;X&lt;/td&gt;&lt;td class="auto-generated"&gt;&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;Int64&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;X&lt;/td&gt;&lt;td align="left"&gt;X&lt;/td&gt;&lt;td class="auto-generated"&gt;&lt;br /&gt;&lt;/td&gt;&lt;td class="auto-generated"&gt;&lt;br /&gt;&lt;/td&gt;&lt;td align="left"&gt;X&lt;/td&gt;&lt;td align="left"&gt;X&lt;/td&gt;&lt;td align="left"&gt;X&lt;/td&gt;&lt;td class="auto-generated"&gt;&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;Integer&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;X&lt;/td&gt;&lt;td class="auto-generated"&gt;&lt;br /&gt;&lt;/td&gt;&lt;td class="auto-generated"&gt;&lt;br /&gt;&lt;/td&gt;&lt;td class="auto-generated"&gt;&lt;br /&gt;&lt;/td&gt;&lt;td align="left"&gt;X&lt;/td&gt;&lt;td align="left"&gt;X&lt;/td&gt;&lt;td align="left"&gt;X&lt;/td&gt;&lt;td class="auto-generated"&gt;&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;Rational&lt;/code&gt; or any &lt;code class="literal"&gt;Ratio&lt;/code&gt;&lt;/td&gt;&lt;td class="auto-generated"&gt;&lt;br /&gt;&lt;/td&gt;&lt;td class="auto-generated"&gt;&lt;br /&gt;&lt;/td&gt;&lt;td class="auto-generated"&gt;&lt;br /&gt;&lt;/td&gt;&lt;td align="left"&gt;X&lt;/td&gt;&lt;td class="auto-generated"&gt;&lt;br /&gt;&lt;/td&gt;&lt;td align="left"&gt;X&lt;/td&gt;&lt;td align="left"&gt;X&lt;/td&gt;&lt;td align="left"&gt;X&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;Word&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;X&lt;/td&gt;&lt;td align="left"&gt;X&lt;/td&gt;&lt;td class="auto-generated"&gt;&lt;br /&gt;&lt;/td&gt;&lt;td class="auto-generated"&gt;&lt;br /&gt;&lt;/td&gt;&lt;td align="left"&gt;X&lt;/td&gt;&lt;td align="left"&gt;X&lt;/td&gt;&lt;td align="left"&gt;X&lt;/td&gt;&lt;td class="auto-generated"&gt;&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;Word16&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;X&lt;/td&gt;&lt;td align="left"&gt;X&lt;/td&gt;&lt;td class="auto-generated"&gt;&lt;br /&gt;&lt;/td&gt;&lt;td class="auto-generated"&gt;&lt;br /&gt;&lt;/td&gt;&lt;td align="left"&gt;X&lt;/td&gt;&lt;td align="left"&gt;X&lt;/td&gt;&lt;td align="left"&gt;X&lt;/td&gt;&lt;td class="auto-generated"&gt;&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;Word32&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;X&lt;/td&gt;&lt;td align="left"&gt;X&lt;/td&gt;&lt;td class="auto-generated"&gt;&lt;br /&gt;&lt;/td&gt;&lt;td class="auto-generated"&gt;&lt;br /&gt;&lt;/td&gt;&lt;td align="left"&gt;X&lt;/td&gt;&lt;td align="left"&gt;X&lt;/td&gt;&lt;td align="left"&gt;X&lt;/td&gt;&lt;td class="auto-generated"&gt;&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align="left"&gt;&lt;code class="literal"&gt;Word64&lt;/code&gt;&lt;/td&gt;&lt;td align="left"&gt;X&lt;/td&gt;&lt;td align="left"&gt;X&lt;/td&gt;&lt;td class="auto-generated"&gt;&lt;br /&gt;&lt;/td&gt;&lt;td class="auto-generated"&gt;&lt;br /&gt;&lt;/td&gt;&lt;td align="left"&gt;X&lt;/td&gt;&lt;td align="left"&gt;X&lt;/td&gt;&lt;td align="left"&gt;X&lt;/td&gt;&lt;td class="auto-generated"&gt;&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="table"&gt;&lt;p class="title"&gt;&lt;b&gt;Table 6.4. Conversion Between Numeric Types&lt;/b&gt;&lt;/p&gt;&lt;div class="table-contents"&gt;&lt;table border="1"&gt;&lt;colgroup&gt;&lt;col&gt;&lt;col&gt;&lt;col&gt;&lt;col&gt;&lt;col&gt;&lt;/colgroup&gt;&lt;thead&gt;&lt;tr&gt;&lt;th rowspan="2"&gt;Source Type&lt;/th&gt;&lt;th colspan="4" align="center"&gt;Destination Type&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;th&gt;&lt;code class="literal"&gt;Double&lt;/code&gt;, &lt;code class="literal"&gt;Float&lt;/code&gt;&lt;/th&gt;&lt;th&gt;&lt;code class="literal"&gt;Int&lt;/code&gt;, &lt;code class="literal"&gt;Word&lt;/code&gt;&lt;/th&gt;&lt;th&gt;&lt;code class="literal"&gt;Integer&lt;/code&gt;&lt;/th&gt;&lt;th&gt;&lt;code class="literal"&gt;Rational&lt;/code&gt;&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;code class="literal"&gt;Double&lt;/code&gt;, &lt;code class="literal"&gt;Float&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;code class="literal"&gt;fromRational . toRational&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;code class="literal"&gt;truncate&lt;/code&gt; *&lt;/td&gt;&lt;td&gt;&lt;code class="literal"&gt;truncate&lt;/code&gt; *&lt;/td&gt;&lt;td&gt;&lt;code class="literal"&gt;toRational&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code class="literal"&gt;Int&lt;/code&gt;, &lt;code class="literal"&gt;Word&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;code class="literal"&gt;fromIntegral&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;code class="literal"&gt;fromIntegral&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;code class="literal"&gt;fromIntegral&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;code class="literal"&gt;fromIntegral&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code class="literal"&gt;Integer&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;code class="literal"&gt;fromIntegral&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;code class="literal"&gt;fromIntegral&lt;/code&gt;&lt;/td&gt;&lt;td&gt;N/A&lt;/td&gt;&lt;td&gt;&lt;code class="literal"&gt;fromIntegral&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code class="literal"&gt;Rational&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;code class="literal"&gt;fromRational&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;code class="literal"&gt;truncate&lt;/code&gt; *&lt;/td&gt;&lt;td&gt;&lt;code class="literal"&gt;truncate&lt;/code&gt; *&lt;/td&gt;&lt;td&gt;N/A&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6265706250887913030-4792419938269488885?l=rwsleep.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ReadWriteSleep/~4/STCNVtxvzto" height="1" width="1"/&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/January?a=8TamMboFEWU:pJXzJVQQ0FA:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/January?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/January?a=8TamMboFEWU:pJXzJVQQ0FA:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/January?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/January/~4/8TamMboFEWU" height="1" width="1"/&gt;</description>
         <author>Jan</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-6265706250887913030.post-4792419938269488885</guid>
         <pubDate>Sun, 21 Dec 2008 11:27:00 -0800</pubDate>
      <feedburner:origLink>http://feedproxy.google.com/~r/ReadWriteSleep/~3/STCNVtxvzto/haskell-numeric-types.html</feedburner:origLink></item>
      <item>
         <title>procedure/goto/if/case... What should we use?</title>
         <link>http://feedproxy.google.com/~r/January/~3/lj747Zg473I/proceduregotoifcase-what-should-we-use.html</link>
         <description>"Recently practitioners of programming discipline have advised us not to be afraid to use procedure calls, as the readability they afford is worth the inefficiency. This is like saying that cars with square wheels qare all right because transportation is worth a bumpy ride: we really ought instead to concentrate on improving our wheels."&lt;br /&gt;&lt;br /&gt;An interesting metaphor from Guy Lewis Steele in &lt;a rel="nofollow" target="_blank" href="http://repository.readscheme.org/ftp/papers/ai-lab-pubs/AIM-443.pdf"&gt;his paper&lt;/a&gt;. "as the A they afford is worth the B", I've seen such statements serveral times. It make me think that it's usually an execuse because ppl just don't want to spend time to really resolve a problem.&lt;br /&gt;&lt;br /&gt;Two insightful points from this paper:&lt;br /&gt;&lt;br /&gt;* Our difficulties in dealing with programming and programming languages stem in part from a confusion between the abstract notions of prgram organization and the concrete embodiment of these notions as programming language constructs. The important point is that for each important programming concept which we have found useful -- modularity, iteration, assignment, conditionals -- there may exist more than one programming language construct which can embody that concept in a reasonably natural manner. In understanding (a piece of) a program it is necessary to determine not only what construct is being used, but the concept it is intended to express.&lt;br /&gt;&lt;br /&gt;* We discovered that GOTO was often being used even in situations where more appropriate and expressive constructs were available, and that it was being used for all sorts of purposes we hadn't anticipated, and so we sought to eliminate unwanted concepts and programming styles by banning a construct.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6265706250887913030-4723784301946662857?l=rwsleep.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ReadWriteSleep/~4/YZaADlsECNY" height="1" width="1"/&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/January?a=lj747Zg473I:6c5DUdsP0EM:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/January?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/January?a=lj747Zg473I:6c5DUdsP0EM:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/January?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/January/~4/lj747Zg473I" height="1" width="1"/&gt;</description>
         <author>Jan</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-6265706250887913030.post-4723784301946662857</guid>
         <pubDate>Fri, 19 Dec 2008 01:02:00 -0800</pubDate>
      <feedburner:origLink>http://feedproxy.google.com/~r/ReadWriteSleep/~3/YZaADlsECNY/proceduregotoifcase-what-should-we-use.html</feedburner:origLink></item>
      <item>
         <title>What's need by tail-recursion optimization in funcational language?</title>
         <link>http://feedproxy.google.com/~r/January/~3/OaC8ZZWsoGA/whats-need-by-tail-recursion.html</link>
         <description>What's the common ideas needed by all high-level programming languages?&lt;br /&gt;&lt;br /&gt;* Transfer of control&lt;br /&gt; - conditional&lt;br /&gt; - unconditional&lt;br /&gt;* Environment operation&lt;br /&gt; - variable binding on function entry&lt;br /&gt; - declaration of local variable&lt;br /&gt;* Side effects&lt;br /&gt; - assignment&lt;br /&gt; - IO&lt;br /&gt;* Process synchronization&lt;br /&gt; - resource allocation&lt;br /&gt; - passing of information between processes&lt;br /&gt;&lt;br /&gt;The idea behind tail-recursion optimization in applicative language&lt;br /&gt;&lt;br /&gt;* function is goto with arguments. There's no need for return address for a function. We need save a return address on the stack when we begin to evaluate a form (function call) which is to provide an argument for another function, rather than when we invoke the function.&lt;br /&gt;* so, we pushes addtional control stack only when evaluate forms, for function application, we only need set up environments.&lt;br /&gt;* this is why we can't use the same way to optimize tail-recursion in imperative language - the return address for the caller function may not be the continuation address of the callee&lt;br /&gt;* lexical binding is necessary for lambda goto rule. we can't use goto to replace funcation call with dynamic binding.&lt;br /&gt;&lt;br /&gt;An interesting symmetry: control constructs determine constraints in time (sequencing) in a program, while environment operators determine constraints in space (textual extent, or scope).&lt;br /&gt;&lt;br /&gt;Ref. &lt;a rel="nofollow" target="_blank" href="http://library.readscheme.org/servlets/cite.ss?pattern=Ste-76b"&gt;Guy Lewis Steele, Jr.. "Lambda: The Ultimate Declarative". MIT AI Lab. AI Lab Memo AIM-379. November 1976.&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6265706250887913030-1782700517121623907?l=rwsleep.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ReadWriteSleep/~4/eos6k2SvvHU" height="1" width="1"/&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/January?a=OaC8ZZWsoGA:7GRb3q1wr5w:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/January?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/January?a=OaC8ZZWsoGA:7GRb3q1wr5w:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/January?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/January/~4/OaC8ZZWsoGA" height="1" width="1"/&gt;</description>
         <author>Jan</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-6265706250887913030.post-1782700517121623907</guid>
         <pubDate>Wed, 17 Dec 2008 09:57:00 -0800</pubDate>
      <feedburner:origLink>http://feedproxy.google.com/~r/ReadWriteSleep/~3/eos6k2SvvHU/whats-need-by-tail-recursion.html</feedburner:origLink></item>
      <item>
         <title>Super fast action with Rails Metal</title>
         <link>http://feedproxy.google.com/~r/January/~3/YEwdtZQXnpY/super-fast-action-with-rails-metal.html</link>
         <description>&lt;div&gt;&lt;a rel="nofollow" target="_blank" href="http://github.com/rails/rails/commit/8c3a54366435eebc2c8aa63b63e1349ce74a7b38"&gt;Josh commit a new feature into edge rails named Metal&lt;/a&gt;. With it ppl can use rack directly to serve request easily. Take a look at his example:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt; # app/metal/poller.rb&lt;br /&gt;class Poller &amp;lt;&amp;gt; "application/json"},&lt;br /&gt; Message.recent.to_json]&lt;br /&gt; else&lt;br /&gt; super&lt;br /&gt; end&lt;br /&gt;end&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;* There is a generator to help you get started&lt;br /&gt;`script/generate metal poller`&lt;br /&gt;&lt;br /&gt;* Also, metal bits can be ran standalone with rackup&lt;br /&gt;`rackup app/metal/poller.rb`&lt;/pre&gt;&lt;br /&gt;Not the request to 'http://your.app.com/poller' will be processed in rack, that's more faster than processing it in controller :)&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6265706250887913030-5806711000805892064?l=rwsleep.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ReadWriteSleep/~4/HODzMYcuzUw" height="1" width="1"/&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/January?a=YEwdtZQXnpY:c4FTmeC5eSM:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/January?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/January?a=YEwdtZQXnpY:c4FTmeC5eSM:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/January?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/January/~4/YEwdtZQXnpY" height="1" width="1"/&gt;</description>
         <author>Jan</author>
         <guid isPermaLink="false">tag:blogger.com,1999:blog-6265706250887913030.post-5806711000805892064</guid>
         <pubDate>Tue, 16 Dec 2008 10:11:00 -0800</pubDate>
      <feedburner:origLink>http://feedproxy.google.com/~r/ReadWriteSleep/~3/HODzMYcuzUw/super-fast-action-with-rails-metal.html</feedburner:origLink></item>
   </channel>
</rss><!-- fe2.pipes.re3.yahoo.com uncompressed Fri Jul 10 12:01:50 PDT 2009 -->
