Fan's blog Rotating Header Image

Posts under ‘Language’

《Real World Haskell》读书笔记

这本书还是不错的,举了很多例子,学起来容易多了。 1). Lambda。书上讲的比较少,其实有个例子就很清楚。show me the code: Input: map (\x -> 3*x + x/4) [1,2,3,4] Output: [3.25,6.5,9.75,13.0] Input: foldr1 (\x y -> 2*x + y) [1,2,3,4] Output: 16 2. Multiple Return Value。指一个函数可以返回多个值。Haskell中使用Tuple,大小为2的tuple为pair,这比创建一个这些值的容器类更灵活,语法上更直观,比如result, ok = add(11, 22),这里ok可以用来指示程序运行是否有异常,在Go语言这种语法用来弥补C的不足。Haskell因为是静态类型的,所以这些Tuple都是有类型约束的;Go中则还可以对参数命名,这样函数的定义更加规范。 3. Pattern Matching. Twitter.

多语言开发

最近看Thoughworks的《软件开发沉思录》,《卓有成效的程序员》,还有一本老书:O’Reilly的《超越Java》。 这几本书都提出一个观点:Java已经老矣,是时候该用多语言来编程了,试试ruby, haskell这些语言吧。

实现DSL的几个例子

所谓DSL就是能描述语言的语言,一般某些领域都有自己的专有术语,用这些术语来交流比一般的通用的语言更流畅,比如象棋的“平五进八”,这种走棋的表达比自然语言更快,DSL就是把这种领域的语言翻译成“自然语言”的模型。一般有内部和外部之分,内部指领域语言嵌入在自然语言中用自然语言表达,相当于从“古文”中进化出“普通话”的过程;外部则指全新的语言,比如Java, C等,是一个全新的描述模型,创造起来比内部要复杂。举几个例子容易明白,下面几个是内部的DSL。 使用连贯接口 这是”The productive Programmer”中的例子,要描述的领域是“食谱”。比如“recipe.add 200.grams.of Flour”。 class Numeric def gram self end alias_method :grams, :gram end Ruby可以打开一个存在的类向其中添加方法,所以可以写出200.grams这种有点恶心的句子,而且ruby中方法可以不加括号(),光这点用Java实现就够呛。不过用method chain会使用很多点点点,有点像人没有进化完全而留下点阑尾… 下面这个例子来自”Programming Scala Tackle Multi-Core Complexity on the Java Virtual Machine”,要描述的领域为“时间”,比如“2 days ago”。 object App { def main(args : Array[String]) : Unit = { implicit def convertInt2DateHelper(number: Int) = new DateHelper(number) val ago = “ago” val [...]

我对CPS的理解

最近学习Haskell,我看的是Yet Another Haskell Tutorial,看到CPS,发现这本书写的很难懂,不知所云。后来看了wikibooks上面的文章,明白了一些。这里是一个总结,也还不错。 CPS到底是个啥?拿例子看比较容易。比较如下代码: add (square x) (square y) 和CAS style的: pythagoras’cps x y k = square’cps x $ \x’squared -> square’cps y $ \y’squared -> add’cps x’squared y’squared $ \sum’of’squares -> k sum’of’squares CPS有点像倒置过来的写法,而前者则是普通的堆栈的写法。那这样CPS有什么有优点呢? 在Java中类似的写法有stringBuffer.append(“A”).append(“B”).append(“C”),IO API中好像也有类似的方法。(在《The Productive Programmer》里面管这个叫做连贯接口 fluent interface…) 感觉有点类似管道(pipe),前面的square把结果(这里就是k)传到下一个function,这样一个个串联起来,而k起了连接的作 用。而像add( square(x), square(y))这种方式每个func相当独立(primitive),最后有一个组合(mash-up)的过程。 而这种方式才让“从某个点停止,然后继续执行”成为可能,因为这样没有堆栈。add( square(x), square(y))这种方式会生成临时变量,会有running context。而pipe某个节点的状态就是pipe的全部,是继续“流”下去所需的所有内容,这个function是可以“重入”的。这里“流”下去就是“延续”的意思。 这种状态保存其实很多地方都有,比如http session,比如进程上下文(进程也可以sleep后再重新载入,或者恢复),但是CPS则粒度更细,可以在代码级上的重新载入,“重入”精确到某行代码。而Spring web flow这种流程级的则是精确到了flow中的某个节点,比较代码级的天书一样的代码,流程级的引入进来还是比较好的一个折中。当然这样的话,跟CPS就关系不大了。 我很早前读过跨越边界: [...]