Go LispEx - 让 Lisp 支持并发编程

kedebug · 2014年09月02日 · 最后由 jimrokliu 回复于 2014年09月03日 · 8700 次阅读

LispEx 是用 Go 语言编写的一款符合 R5RS 标准的 Lisp 解释器。

有意思的地方是,在设计之初我就考虑是否能为其添加一些并发编程的语言特性,让这门古老的编程语言充满生机起来。

于是便选择了 Go 语言来实现它,耗时近 2 个月,Go 里面的一些特性如:goroutine, channel, select 等语义都在 LispEx 中有了支持。

  • 遵守 KISS 原则,尽量把代码设计的简单,易懂。很多模块被很好的分离出来,想添加新的语义支持的话,只需要添加、修改个别文件的源代码。

  • 借鉴了王垠大神 Yin 语言的代码设计思路:任何一个 Node 都会被解释成 Value;Parser 被拆分成了 2 个阶段:包括预处理生成语法单元,然后 Parse 成语法树。顺着这个思路,代码会变得非常易读,当然在设计的时候针对这点是费了很多心思的,希望对一些后人能有借鉴意义。

  • 并发的词法分析器。这点 Rob Pike 在 http://cuddle.googlecode.com/hg/talk/lex.html#title-slide 提到过。LispEx 把它实践了一遍。

  • Go liked 并发语义支持。下面一段代码演示了并发编程里面经典的 ping-pong 案例,并且借助 channel 实现了信号量:

; define channels
(define ping-chan (make-chan))
(define pong-chan (make-chan))
; define a buffered channel
(define sem (make-chan 2))

(define (ping n)
  (if (> n 0)
    (begin
      (display (<-chan ping-chan))
      (newline)
      (chan<- pong-chan 'pong)
      (ping (- n 1)))
    (chan<- sem 'exit-ping)))

(define (pong n)
  (if (> n 0)
    (begin
      (chan<- ping-chan 'ping)
      (display (<-chan pong-chan))
      (newline)
      (pong (- n 1)))
    (chan<- sem 'exit-pong)))

(go (ping 6))  ; start ping-routine
(go (pong 6))  ; start pong-routine

; implement semaphore with channel, waiting for ping-pong finishing
(<-chan sem) (newline)
(<-chan sem) (newline)

; should close channels if you don't need it
(close-chan sem)
(close-chan pong-chan)
(close-chan ping-chan)

; the output will be: ping pong ping pong ... exit-ping exit-pong

再来一段 select 语义示例:

(define chan-1 (make-chan))
(define chan-2 (make-chan))

(go (chan<- chan-1 'hello-chan-1))
(go (chan<- chan-2 'hello-chan-2))

; sleep for 20 millisecond
(sleep 20)

(select
  ((<-chan chan-1))
  ((<-chan chan-2))
  (default 'hello-default))

(close-chan chan-1)
(close-chan chan-2)

; the output will be randomized: hello-chan-1 or hello-chan-2

更多精彩代码演示请见: https://github.com/kedebug/LispEx

PS: LispEx 已经被 Go Community Wiki 和 Hacker News 收录: https://code.google.com/p/go-wiki/wiki/Projects#Virtual_Machines_and_Languages https://news.ycombinator.com/item?id=8074334

为什么不直接用 clojure 呢?

#1 楼 @rasefon 对 golang 更熟悉些,呵呵

性能如何? 有空跟 common lisp 的 https://github.com/sykopomp/chanl 对比一下

虽然很喜欢这个项目但是 Hacker News 都是各种人 Submit 上去的... Point 不够多啊

5 楼 已删除

这种项目就是玩玩,真要用就呵呵了

#6 楼 @yukihiro_matz 你发明的 Ruby 不也是玩玩的嘛~~

Lisp 太学术了,语言也需要满足阅读的需要,满屏的括弧只能自己玩玩。

10 楼 已删除
需要 登录 后方可回复, 如果你还没有账号请 注册新账号