Category: Lambda

24 posts

The Implementation of Scheme Hygienic macro

我在很早的时候曾经写过一篇叫做“Play with macro”的文章,介绍了 Common Lisp 式的 macro ,那是一个很基本但又很强大的工具,比较容易理解。相比之下,Scheme 的 macro 就不一样了,虽然我很早就知道 Scheme 的 macro 是一种叫做 Hygienic macro 的东西,但是直到最近才明白它是怎么一回事,因为我要实现这样一个系统。 Common Lisp 的 macro 其实就是一段 Common Lisp 代码——一段操控代码的代码。因为在 Lisp [...]

Multiton again, in Python

I have introduced Multiton in one of my previous blog post. Multiton is just like Singleton, except that there will be multiple instance when the init parameters are different. One example is the Lisp symbol: Different symbol object for different symbol name. Identical symbol object for identical [...]

Inside the {C++, Java, Lisp, Python, Ruby} Object Model

We just held a technical salon today named "template<language L> Inside the L Object Model". When I was looking at some code of Ruby, I found the object model is very different to a static language like C++. So I suggested the idea of discussing various object model of different [...]

Trampolined-style Programming

今天在 pyscheme 的代码里看到许多诸如 pogo.pogo 、pogo.land 、pogo.bounce 之类的调用,感觉特别奇怪,不过它的注释写得很详细,做这样的东西是为了解决 Python 没有尾递归优化的问题。 在有尾递归优化的语言里(Scheme 是最典型的一个例子,因为它甚至把尾递归作为语言的一个重要特性放在语言规范中了),如果一个函数的最后一个动作(除了 return)是调用另一个函数的话,就直接用那个函数的栈帧替换当前的栈帧,省去了 call and return 的麻烦,还避免了栈溢出,时间空间都有优势。 [...]

A Better method_missing

method_missing 是 Ruby 用于实现其动态性的一个重要成员。简而言之就是在调用一个对象的某个方法的时候发现这个方法不存在,于是会触发 method_missing ,进而做一些事情,比如转发这个方法,甚至根据需要定义那个方法让下次调用的时候不会产生 method_missing ,另外这也是制作 DSL 的一个重要工具。 下面是一个简单的 DSL 的例子:

We read Knuth so you don’t have to

来自 Python Cookbook (第 5 章:Searching and Sorting)的 Quote : We read Knuth so you don't have to. 所以在 Python 中,如果要排序,尽量使用内置的 sort 方法;如果要做搜索,尽量使用内置的 dictionary 工具,因为它们集中了 Knuth 先生的经典砖头里面的近 800 页的关于排序和搜索的详细讨论。当然,在 Ruby 中肯定也是差不多的。 ;)

混乱过的 C 语言 Hello World 程序

相信不少人都听说过国际 C 语言混乱大赛吧?里面有不少看起来千奇百怪的代码,但却都是完整的 C 程序并且不少是非常有用并且高效的程序。今天我在这里又看到几个混乱过的 Hello World 程序,例如: #define _________ } #define ________ putchar #define _______ main #define _(a) ________(a); #define ______ _______(){ #define __ ______ _(0x48)_(0x65)_(0x6C)_(0x6C) #define ___ [...]

Coroutines and Semi-Coroutines

Ruby 1.9 中引入了 Fiber 用于支持 Coroutine 。事实上 Fiber 并不是一个 Coroutine ,而是 Semi-Coroutine ,或者叫做 Asymmetric Coroutine 。因为它只能将执行权返回给调用者,而完整的 Coroutine 可以自由转移运行权。 Ruby 1.9 也提供了 Fiber::Core 用于支持“正宗”的 Coroutine 。关于 Semi-Coroutine 和 Coroutine 的等价性似乎有些争论。下面是一个 Fiber 的例子: fib = Fiber.new do x, y = 0, 1 loop do [...]

A 3rd-order Quine: Haskell -> Python -> Ruby

我曾经在我的 Wiki 笔记 中介绍过 Quine ,就是能打印自身的程序。今天在这里看到一个很厉害的 Quine : q a b c=putStrLn $ b ++ [toEnum 10,'q','('] ++ show b ++ [','] ++ show c ++ [','] ++ show a ++ [')'] main=q "q a b c=putStrLn $ b ++ [toEnum 10,'q','('] ++ show b ++ [','] ++ show c ++ [','] ++ show a ++ [')']" "def q(a,b,c):print [...]

RubyConf 2007 video 释出!

RubyConf 2007 演讲的全部视频最近由 Confreaks 公司公布(Creative Commons Attribution-ShareAlike license)出来,可以在这里在线观看或者下载 AVI 格式(H.264)的视频。 这么多牛人的怎么多精彩的演讲,真是令人激动啊!我把他们下载下来了,这样离线的时候也可以看。我还把他们传到了 88 CompLang 版的 FTP 上,校内的朋友们可以直接去那里下载。 :) 我虽然还没有来得及看所有的演讲,但是随便看了几个都是非常有趣的(当然,也是非常精彩的),我这里随便介绍一两个,相信你一定也会喜欢的! Hurting Code [...]

Ruby 1.9.0 is released

Ruby 1.9 在圣诞节如期发布啦! Hi, We are happy to announce of the release of the 1.9.0 the development release. You can fetch it from: ftp://ftp.ruby-lang.org/pub/ruby/1.9/ruby-1.9.0-0.tar.bz2 407cc7d0032e19eb12216c0ebc7f17b3 ftp://ftp.ruby-lang.org/pub/ruby/1.9/ruby-1.9.0-0.tar.gz [...]

Continuation + Y Combinator

我在介绍 Continuation 的文章中提到了一个 create_iterator 的实现,它接受一个函数名,内部去调用这个函数而实现 iterator 。最初我是想让它接受一个 block 的,但是后来却改成了函数名,正是在做二叉树的遍历时出了问题:二叉树遍历是一个经典的递归程序,而 block 没有名字,无法做递归,只好作罢。 不过在前一篇文章中我又介绍了 Y Combinator (其实我也是在一边学习的)正好可以用来做匿名递归,刚好可以把这两者结合在一起啦! 原来的 create_iterator 是这样的:

the Y Combinator

今天看到 A Use of the Y Combinator in Ruby 这篇文章,却被他的代码搞晕了,半天看不明白,于是只好另辟蹊径,不看他的代码,却自己来写一下,如果我写出来的代码和他一样,那自然就明白了,如果不一样,也好对比一番,相信也更容易理解了。 这里要解决的问题大致就是“匿名递归函数”的问题。递归函数大家都知道了,例如经典的阶乘函数: def fact(n) if n == 0 1 else n*fact(n-1) end end 匿名函数也没啥,在许多语言里,函数就和普通的值没有什么区别,不一定非要有一个名字,例如 lambda 就可以创建一个匿名函数: func = [...]

Write a Scheme Interpreter in Ruby(2): THE Interpreter

在上一篇文章中我们实现了对 scheme 代码的 parse 和 analyze 过程,并得到了一些可以直接 eval 的对象(String ,Symbol ,Number 和 Cons ),可是光凭这些并不足以让我们的解释器跑起来。这次我们要添加必要的代码,实现一个真正可运行的解释器。 在前面的代码中,我们已经实现了 scheme 中的几个基本对象的求值:作为 atom 的 String 、Symbol 和 Number 以及作为 list 的 Cons 都已具体实现了 eval 方法。事实上 atom 的求值已经不需要加什么其他代码了,但是 Cons 类却是耍了一个把戏,仔细看 Cons [...]

Write a Scheme Interpreter in Ruby(1): Parser & Analyser

也算是突然心血来潮吧,就想写一个 Scheme 的解释器,其实也是心血来潮了许多次了,只是一直都只是一个想法,最主要的原因还是因为自己对编译原理一无所知吧,也许明年上过编译原理课之后就好写了。不过这次真是心血来潮了,拦都拦不住,怕是等不到明年了。 不管写得出来写不出来,也都先试试吧!多次见石老师演示过 boost::spirit ,计算理论课上也学过了上下文无关文法,似乎还是知道个大概。于是我就开始找 Ruby 的 parser 库。 好像 parser 也有许多种,什么 Recursive Descent [...]

Multiton

Multiton 类似于 Singleton ,目的是要保证某种单一性。但是和 Singleton 的一个区别就是:Singleton 对于一个类只可能有一个对象,而 Multiton 则可能有多个对象,仅当用于构造的参数相同时,才保证唯一性。有许多地方都有这种模式的应用,例如 Lisp 或者 Ruby 里的 symbol ,同名的 symbol interned symbol 总是同一个对象。还有 Java 里的 String 也是这样的。 最近心血来潮在用 Ruby 做一个玩具级别的 Scheme 解释器,要表示 Scheme 里的 symbol 、number 和 string [...]

More on Continuation

我在前一篇文章中用构造二叉树的 iterator 的例子来介绍了一下 Continuation 。Jack 在评论中向我提了两个问题: many people know about the CPS transformation, and callcc as a means to get hold of the implicit continuation (”the rest of the computation”), but we often have a hard time using continuations: there’s a large gap between [...]

Continuation

Continuation 是什么?简而言之,就是代码执行状态,利用它可以把当前的执行状态保存起来,以供以后调用。Scheme 应当是最早支持完整的 Continuation 的语言了,事实上从理论上来说,任何支持 Closure 的语言都能手工实现 Continuation ,不过许多语言还是提供了现成的 Continuation 的支持,例如 Ruby 就有一个类似于 Scheme 的 call/cc(call-with-current-continuation) 的函数 callcc (因为“/”在 Ruby 里面不能作为变量名,所以最多只能做到这么像了 ;) )用于支持 [...]

memoize in Ruby

Common Lisp 的经典书《On Lisp》的 5.3 节叫做 Memoizing 。书中讲到了将函数调用的返回值缓存起来的一种技术。这本来是一种非常常见的技术,但是《On Lisp》让我看到了动态语言的精练之处,这样的一种技术被抽象成一个通用的函数,将任意一个函数传入 memoize ,就会得到一个经过包装的函数,并且它已经具备了缓存的能力: (defun memoize (fn) (let ((cache (make-hash-table :test #'equal))) #'(lambda (&rest args) (multiple-value-bind (val win) [...]

Ruby 里的元编程

关于元编程 Wikipedia 上关于元编程的定义说元编程就是将程序作为数据进行处理。“用程序来处理程序”,这就是“元”的来源了,这本身是一个容易产生混淆的地方,就像“用语言来描述语言”一样,数学上的许多悖论就来自于此呢。幸好我们用的编程语言比自然语言要简单许多,并且都有严格的定义规范,有兴趣的人可以尝试在自己喜欢的编程语言里面构造一下 “This statement is false” 这个经典悖论。 回到元编程,程序处理程序可以分为“处理其他程序”和“处理自己”,对于前者,有我们熟悉的 lex 和 lacc [...]

动态语言的尴尬

一提到动态语言,一般都会想到像 Python、Perl 以及 Ruby 之类的语言了,按照 Wikipedia 上的定义,动态语言是这样的: Dynamic programming language is a term used broadly in computer science to describe a class of high level programming languages that execute at runtime many common behaviors that other languages might perform during compilation, [...]

我以前的笔记

以前用 Emacs Muse 写了不少的笔记,自己觉得有些东西还是挺有用的,至少我自己也经常回去查阅,有些东西不记下来过一段时间还真忘记了。只是一直没有合适的地方挂出来给大家分享。虽然现在已经很少再添加新的东西了,不过既然有这个机会,我还是挂出来,免得白白写了些东西,只有我自己看到了。 :) 我把它放在了这里: http://pluskid.lifegoo.com/wiki/index.html

不愉快的 Qt 之旅

今天尝试用 Qt 来写一个小程序,从网上抓取一些东西,并解析一下保存到本地。很简单的功能,但是却写得非常不舒服。 大致看了一下 Qt 提供的库,似乎应有尽有了。一大堆 GUI Widget 可以构建丰富的界面,方便的 QHttp 可以用于下载 Web 页面,并使用 QRegExp 进行解析,还有 Qt 强大的 QTextCodec 可以在各种编码之间进行转换。并且 Qt 4 提供了 MCV 方式,让我能轻松地把事务和视图分开处理。一切都是那么完美,似乎是专门为我准备的一样。然而它们并不是为我准备的。 我相信使用 QHttp [...]

Play with macro

Lisp 的宏可谓是异常强大。我所接触过的宏大约算三种: 一种是 C 语言的宏,这几乎可以算是功能最弱但又用得最多的宏了。只做非常简单的语法分析,并进行文本替换。但是实际上这种简单的宏为 C/C++ 带来了许多额外的能力,不过从来这个东西好像也没有专门的文献以及教材详细讲解,大多是经验丰富的程序员们通过源代码互相传播关于宏的知识,而且许多方面在各个不同的编译器上的结果都是不一样的,所以一直以来宏也只有那部分非常常见的用法为大家所广泛接收并使用。事实上,如果你感兴趣,可以去看一看 boost.preprocessor ,你会了解到其实宏可以做很多很多的事情。 一种是 C++ [...]