clojure recur

clojure是函数是编程语言,本身没有循环的语法。要实现类似循环的效果,需要用递归来实现。比如计算从1加到n的和这样一个函数:

(defn addup
    ([limit] (addup limit 0 0))
    ([limit current sum]
        (if (< limit current)
            sum
            (addup limit (+ 1 current) (+ current sum)))))

调用

(addup 10)

可以得到55

但是调用

(addup 50000)

不出意外,出现了StackOverflowException, 这是递归典型的错误。

为此,需要进行优化。尾递归优化是指如果递归满足一定条件,编译器可以将递归展开,避免出现栈溢出的问题。这里的条件,就是递归的最后一次调用是否是其本身,比如上面的代码,最后一次操作仍然是addup,即满足尾递归的条件,而如果同样的代码写成:

(defn addup2
    ([limit] (addup2 limit 0))
    ([limit current]
        (if (< limit current)
            0
            (+ current (addup2 limit (+ current 1))))))

最后一个操作是+,不满足尾递归循环,无法进行优化。

clojure默认不进行尾递归优化,需要使用关键字recur来保证优化,把第一段代码写成:

(defn addup
    ([limit] (addup limit 0 0))
    ([limit current sum]
        (if (< limit current)
            sum
            (recur limit (+ 1 current) (+ current sum)))))

社区的解释是,如果程序员在无法进行尾递归优化的代码中使用recur会发生报错,这样有助于他们发现代码中潜在的缺陷。

在第二段代码中使用recur,会得到异常:

java.lang.UnsupportedOperationException: Can only recur from tail position

此外,clojure提供loop函数简化书写:

(defn addup3
    ([limit]
    (loop [current 0 sum 0]
        (if (< limit current)
            sum
            (recur (+ current 1) (+ current sum))))))

这种写法同样可以应用尾递归优化而不会导致栈溢出。

The post is brought to you by lekhonee v0

fixing "libmozjs" missing when using mongodb on Ubuntu lucid

Problem
When running mongod/mongo/mongos, you got message like this:
mongod: error while loading shared libraries: libmozjs.so: cannot open shared object file: No such file or directory

Solution
Make sure you have xulrunner-dev installed:
sudo apt-get install xulrunner-dev

then find libmozjs on your filesystem:
sudo locate libmozjs

in lucid, it’s supposed to locate at:
/usr/lib/xulrunner-1.9.2.6/libmozjs.so

(and some other directories, such as firefox / thunderbird / seamonkey)

Just create a symbol link:
sudo ln -s /usr/lib/xulrunner-1.9.2.6/libmozjs.so /usr/lib/

try to restart mongodb:
sudo service mongodb start

take a look at process list:
ps aux | grep mongo

it works.

The post is brought to you by lekhonee v0.7

Update

  1. 搬家了,搬了一条街,从马路这边搬到马路那边。从二楼搬到四楼,告别了潮湿发霉的小屋,换了新环境迎接工作第二年。本来想搬出这个玉兰香苑,但是看了一圈不是太远就是太贵。都说现在是不炒房价改炒房租了,别的不知道,反正我原来那屋房租就涨了200,而且我搬出去那天就租出去了。
  2. 妈妈来上海,晚上可以一起玩桌游。妈妈对卡卡松还挺感兴趣的,我们一开始玩基础版,然后加河流扩展、旅馆教堂扩展。卡卡松绝对是家庭娱乐的好工具,各位常年在外的童鞋休假回家可以带一个和父母一起玩,调节气氛,增进和谐,居家旅行,必备良方。
  3. 周五盛大创新院,人间网介绍mongodb实践。人间网的用户不多,数据量不大,mongodb用来存储timeline里的status id,至今有不到900M的数据和900M的索引。交流活动持续一个小时,最火爆的环节是Q&A。人间网用mongodb的经验也不是非常丰富,很多问题也解释不清楚,最后多亏了我们组一位上海程序员界的新星救场,除了解决了四面八方有意义无意义的问题以外,也引来了全场的叹为观止,以至于都有人说这是SDO的人嘛。其实不完全是,其实人家才大三。
  4. 工作一年了,下周安静下来总结一下吧。

The post is brought to you by lekhonee v0.7

Exaile-doubanfm-plugin 0.0.2

Exaile doubanfm plugin 0.0.2 预览版,目标是在Linux桌面提供豆瓣电台的完整体验。

目前插件只能运行在Exaile 0.3.1版本上。

0.0.2增加了豆瓣电台专用的视图:
screenshot_001

相比第一版通过rating来实现豆瓣电台喜欢、跳过和删除的功能,在专用视图上有专门的按钮来操作。

其他细节更新:

  • 当剩余曲目超过15首时不再增加播放列表
  • 当播放到最后一首歌曲取新播放列表时增加重试机制
  • 修正libdbfm跳过曲目bug一个

安装:
打开Exaile Preference,Plugin页,点击按钮Install Plugin,选择doubanfm.exz即可。如果存在问题,可以执行以下命令:
mv doubanfm.exz douban.tar.gz
tar xf doubanfm.tar.gz
mv doubanfm ~/.local/share/exaile/plugins/

转到doubanfm设置页面,填写用户名密码重启Exaile。
screenshot_002

打开File菜单,选择豆瓣电台频道
screenshot_001

选择曲目就可以开始播放了,选择视图中豆瓣电台视图可以切换到豆瓣电台视图。

项目地址:
http://github.com/sunng87/exaile-doubanfm-plugin

下载:
http://github.com/sunng87/exaile-doubanfm-plugin/downloads

另外,doubancovers插件也有一个针对豆瓣电台的更新可以快速获取豆瓣电台音乐的封面:
http://bitbucket.org/sunng/exailedoubancovers/downloads?highlight=9265

The post is brought to you by lekhonee v0.7

exaile豆瓣电台插件(exaile-doubanfm-plugin)

豆瓣电台一直是flash客户端,嵌入浏览器,出于对flash的厌恶,本人开发了这个exaile插件,让广大linux同学在exaile里享受豆瓣电台一目了然桌面集成和全部豆瓣电台功能。

exaile-doubanfm-plugin features:

  • 登录豆瓣,获取豆瓣电台播放列表
  • 持续下载电台播放列表,实现不重复的持续播放
  • 标记/取消“喜爱”、标记“回收站”、跳过
  • 显示歌曲信息

screenshot_001

screenshot_002

screenshot_002

项目地址:
http://github.com/sunng87/exaile-doubanfm-plugin

下载页:
http://github.com/sunng87/exaile-doubanfm-plugin/downloads

使用:

  1. 激活插件,填写用户名密码
  2. 重启exaile
  3. 文件菜单,open douban.fm,选择频道
  4. 点击播放开始
  5. 将rating设置为5 标记喜欢
  6. rating设置2 豆瓣标准跳过
  7. rating设置1 豆瓣删除

The post is brought to you by lekhonee v0.7