Code 2011

成功人士是不写总结的,所以我来写个总结。

今年的coding从ABAP开始,这个很多人现在不知道以后也不用知道最好永远也不要知道的语言和他的平台,是一个脱胎于Pascal,在发展过程里又杂糅了SQL和C++的怪物,最后几乎变成了满屏幕关键字。再加上缺乏文档,实在是一段不堪回首的记忆。

3月份开始,我又重新开始了一个python项目叫做jip,他兼容maven,可以与virtualenv和setuptools集成,帮助你解决jython项目的java依赖,简化jython项目的发布,提高工作效率。这个小工具倾注了我不少时间,如果你某一天要和jython打交道的话,可以试试看。

今年还尝试了coffeescript,它恰到好处地消除了javascript里一些ugly的部分,大大提高了编码速度。我用它改写了网站首页的js

6月份我又重拾起1年前的javascript库heatcanvas,和lbt05协作完善了程序。通过HTML5的Web worker API改善了渲染canvas时的用户体验,增加了对Google Maps,OpenLayers,Baidu Map以及Leaflet的支持。这个项目的介绍被顶到hackernews的首页,这是一种前所未有的感觉。

7月份开始迎来了一个重大的转折。断断续续学习了一年半的clojure,终于开始写第一个库,reddit.clj,用clojure封装reddit网站的API。通过这个入口算是真正走进了clojure的世界,七月底reddit.clj基本完成之后我开始写他的第一个应用,rageviewer。这是个clojure的web项目,借着这个契机又接触了compojure和ring。而且写rageviewer的时候恰逢clojurescript公开,一不做二不休,于是这个项目就成了一个full stack的clojure项目:前后端都是clojure。最后rageviewer部署在当时刚刚开始邀请测试的cloudfoundry上。

8月参加了在上海的cn-clojure列表第一次聚会后,我开始用clojure克隆一个已有的并不复杂的程序,当时选择了beanstalkd,一个轻量级的task queue。这个项目取名为clojalk。最后它成功地支持了beanstalkd协议的所有命令,支持了通过Write-ahead log做持久化和恢复。这个项目用到了aleph,见识了一把clojure思维下的网络编程。

另外我还帮clojure-control写了一个leiningen的插件,现在这个插件已经合并到clojure-control项目里了。clojure能有这么快的发展,leiningen作为构建工具也有很大的帮助。就好比上半年做jip时,感受到jython的小世界里就没有一个好的方案来同时解决java和python的项目管理问题,而且人们也不重视这个问题。

年底还有一个clojure RPC框架的诞生,这个项目叫做slacker。项目还没有到总结的时候,我的org file列表上还有一长串的TODO。

总得来说,我觉得今年学习clojure的这个过程很有借鉴价值。对于一个新语言新平台新生态系统,如何入门并且getting real。你可以从一个功能简单的库开始,比如包装一个网站的API,或者(对于clojure来说),包装一个已有的java的库。在完成之后,利用这个库,写一个web应用,进而去了解这个平台上的web开发。再下一步,可以去克隆一个其他平台上的项目,规模不要太大。如此循序渐进,学习的效果很不错。另外,无论做了什么,只要是有用的,就应该说出来,这不仅是自我鼓励,有时候也能找到志同道合的朋友一起参与。

最后除了clojure之外,今年还接着gnome-shell的发布和更新,接触了gnome-shell的gjs扩展开发。又是一个不堪回首的平台,也许是还没有finalize吧,没有任何文档,而且一个平台上的库连变量拼写的风格都不一样!我是不会再浪费时间了,当然,以后的这个豆瓣电台的control还是会继续跟着gnome-shell的发布一直维护的。

除了上面提到的,今年还尝了一些groovy,common-lisp,甚至octave,不管怎么说都算是一个big year了。但愿明年能把这种状态保持下去,享受这种愉悦。

使用Enlive作为模板引擎

在所有的clojure web开发例子里,对模板的介绍都很少。很多的简单例子都是以hiccup作为页面生成的手段。hiccup是个clojure的html DSL,例子里用这样的DSL生成页面确实很酷,可是他是real world吗,当然不是。

好在clojure世界里早就有了enlive,它不仅是一个通过css selector解析html的库,本身也可以作为模板引擎应用在web开发中。我不知道这种通过css selector的方式是否是enlive首创,不过他实在是非常新颖独特,而且平滑了页面设计和程序的集成。

例如这样一个模板 index.html:

<div id="cc">Sample Text</div>

在clojure程序中,使用enlive的deftemplate

(deftemplate index "index.html"
  [ctx]
  [:div#cc] (content (:data ctx)))

在控制器里,可以很MVC地渲染页面

(index {:data "rendered text"})

除了content用于渲染文本,还有html-content可以渲染含html标签的内容,以及set-attr用来修改页面元素的属性。

和传统的模板引擎相比,最大的不同是enlive里没有嵌入模板的直观的控制流,没有循环和条件判断,但是并非不可实现。

循环输出一组list

页面 list.html

<ul id="the-list">
<li class="list-item"></li>
</ul>

定义一个enlive的snippet

(defsnippet item-model "page.html" [:.list-item]
  [ctx]
  [:.list-item] (content (:data ctx)))

在页面模板里

(deftemplate list-page "list.html"
  [ctx]
  [:ul#the-list] (content (map item-model (:some-list ctx))))

这样在页面里列表项会被循环输出,而在页面设计时这里可以放任意个li,并且直接交给后台作为模板。

条件判断

页面,设计时显示所有的内容 msg.html

<span id="msg">只在一定条件下显示</span>

在模板中通过clojure的if进行判断

(deftemplate msg "msg.html"
  [ctx]
  [:span#msg] (if (:show ctx) identity (html-content "")))

解决了这两个问题,基本上用enlive作为模板引擎就没有障碍了。不过enlive也有一点小问题,其一可能是性能的问题,方便的selector显然要比传统的模板语言消耗更多的CPU。另外,在开发过程里,页面文件在服务器启动后不能热加载,修改页面必须重启ring才能看到。也许有时间的话,可以给它加一个reload选项。

Roar for mootools 1.4

早在天下大势还处在分久必合的时候,那时候mootools还有不少简单实用的小库,比如我今天搜索”mootools notification”就找到这个08年的库叫做Roar。不过遗憾的是从那以后,这个库就再也没有更新过了。

Mootools本身也沉寂了很久,这个项目恐怕也要思考自己未来的发展方向了。今年9月Mootools迈进了1.4,API上有一些变化。现在的下载页也能看到with/without backward compatibility的版本分开下载。为了用上Roar,我尝试了这两个版本发现都不能使用。最后downgrade到1.2可以确定Roar本身在当时是没有什么问题。

这么多年对mootools痴心不改,所以顺手维护了一下Roar,现在可以在1.4 without compatibility的发布下运行了。主要是几个小修改,大多是一些多年deprecated函数被正式删除:

  • Type常量,原先的String.type,Object.type现在统一到一个Type对象下,变成Type.isString和Type.isObject
  • $empty 常量被删除了,现在直接用function()或Function.from()代替
  • $pick 方法被Array.pick取代,参数现在也必须接受数组类型了
  • $merge 方法被Object.merge取代
  • $type 被typeOf取代
  • 函数对象的create方法被删除了,现在可以用函数对象的bind方法替代
  • Browser.Engine 被删除了,需要用其他Browser的API替代

修改后的Roar,放在这个gist里,测试过可以在firefox和chromium上健康使用。IE没有做测试。这个08年的库,眼看四年过去了,用起来依然不错。

作为mootools的铁杆,我还是会一直专一地坚守下去的。(于是,我也已经变成了多年前那些我眼中为旧事物顽抗到底的老家伙了)

TF101 101

上周末决定不再忍耐,又入了一个大件:华硕的平板,变形金刚。TF101上市已经半年了,而且现在TF102号称四核的版本已经开始接受预订了,所以差不多也到了应该出手的时候了。因为我知道如果去等102的话,我还会像现在这样地去和103做比较。

选择这款的主要原因即他的键盘配置,平板加键盘的组合彻底把上网本推进深渊。对于我这种还算是制造内容比率比较高的人来说,有个强有力的输入设备是必要的。目前市面上有这种搭配的只有transformer和think的,而且think似乎又只有配图和说明,没见真正卖那款键盘的。更严重的是,当然,think太贵了。

接下来开始说问题:
第一关叫做充电。TF101在充电方面有严重的缺陷。当电池电量极低时,会出现无法充电的情况。明明接着电源,可是电量提示一直是0%。如此情况下我整整充了一天拔下电源依然无法开机。最后看了网上的说法,在充电自动开机后关机了半个小时终于起死回生。

第二个小问题,键盘底座的平板本身电源是分离的,二者各自充电。所以在前面〝整整充了一天〞之前还有整整充了一晚上键盘。早晨起来键盘电满了,平板没充进去。

系统出厂是Android 3.0,这个系统的伟大之处在于从他一启动开始,就开始不断有程序报出错退出,不断有应用停止响应。他简直都对不起这个版本号。直到后来充上电升级到3.2之后才可以用。但是,还是有浏览器突然僵死然后突然从眼前消失的场面。再有就是机捆绑的什么人人网,电子书,开心网什么的,让你想不root都不行。

再有andrid 3.x上应用可能本来就不多,随机捆的又是一个流氓市场,除了满眼的流氓软件和山寨以外,就是版已经过时的软件。可怜这挺好一机器都不知道该装点什么。要说TF101硬件已经很可以了,只是配上这么个系统,用范伟的话说,白瞎你这个人了。手放键盘上,真恨不得能打开个终端来挡住这个浅薄的外观。等有时间我一定要尝试在这台机器上装个正经系统。也算是对得起这硬件了。

一句话概括一下的话,硬件还好,软件拉倒。

Finished my machine learning courses

经过三个月的时间,终于看完了ml-class的所有视频课程,完成了所有review questions,提交了所有programming exercises.感觉不错,之前一直对数据挖掘相关的方面感兴趣,回想一下大学时候一些地统计分析甚至遥感图像数据处理的课都跟机器学习相关,但是毕竟不是这方面的课程,所以介绍的不是很系统。今年秋天斯坦福推出这个在线课程,机器学习作为其中之一真算是弥补了我们民间科学爱好者的遗憾了。

这个课程在有限的篇幅里涵盖了linear regression, logistic regression, ANN, SVM, PCA, K-Means, Anomaly Detection等等知识,基本上算是一个完整实用的导论。Andrew Ng教授的讲解也算是通俗易懂深入浅出,完全感觉不到什么门槛。

对于online course这种形式,今年秋天斯坦福的人工智能、数据库、机器学习也算是首开先河,目前这三门课程都已经结束,网上的反响非常强烈。好消息是明年Q1斯坦福还有更多数量更多方向的课程。今天MIT也宣布了明年的online course计划,他们也将加入提供在线课程的行列。而且,MIT的在线课程还会颁发一个名叫MITx的certification。开放式课程已经成为大势所趋,信息本应自由传播。

对于对机器学习感兴趣的朋友,除了ml-class.org上的资源,你还可以在academic earth上找到ANG教授的授课视频。这套视频涵盖的内容比ml-class上的更详细完整:
http://academicearth.org/courses/machine-learning

课程结束,我在ml-class上所有的编程作业都已经放在bitbucket上,如果有兴趣可以参考这些octave程序:
https://bitbucket.org/sunng/ml-class

明年一月斯坦福还会开放更多跟机器学习相关的课程,包括:

Thank you, Professor Ng and your team for this well-prepared, high-quality online course.