V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
爱意满满的作品展示区。
kedebug
V2EX  ›  分享创造

LispEx - 让 Lisp 支持并发编程

  •  7
     
  •   kedebug ·
    kedebug · 2014-07-23 17:23:40 +08:00 · 5579 次点击
    这是一个创建于 3563 天前的主题,其中的信息可能已经有所发展或是发生改变。
    LispEx 是用 Go 语言编写的一款符合 R5RS 标准的 Lisp 解释器。

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

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

    开源地址: https://github.com/kedebug/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 实现了信号量:

    再来一段 select 语义示例:

    更多精彩代码演示请见: https://github.com/kedebug/LispEx
    第 1 条附言  ·  2014-07-23 21:22:32 +08:00
    第 2 条附言  ·  2014-07-25 10:52:03 +08:00
    LispEx 被 Hacker News 收录(2014/7/24 )
    https://news.ycombinator.com/item?id=8074334
    21 条回复    2014-07-25 11:38:46 +08:00
    kedebug
        1
    kedebug  
    OP
       2014-07-23 17:30:55 +08:00
    补充下:LispEx 已经被 Go Community Wiki 收录。https://code.google.com/p/go-wiki/wiki/Projects#Virtual_Machines_and_Languages
    WildCat
        2
    WildCat  
       2014-07-23 18:09:22 +08:00 via iPad
    王垠大神会爱上你的,下个情人节就不蛋疼了,233
    qiukun
        3
    qiukun  
       2014-07-23 18:09:44 +08:00
    ym 西南某高校
    lsmgeb89
        4
    lsmgeb89  
       2014-07-23 18:45:40 +08:00
    楼主是做 PL 的 master?
    kedebug
        5
    kedebug  
    OP
       2014-07-23 19:37:17 +08:00
    @lsmgeb89 业余时间凭兴趣研究下吧。硕士期间主要做一些旁路安全的研究工作。
    kedebug
        6
    kedebug  
    OP
       2014-07-23 19:39:30 +08:00
    @WildCat 呵呵,垠神太高冷
    haroldwu
        7
    haroldwu  
       2014-07-23 19:47:38 +08:00
    樓主菊苣,能問問你對 clojure 的看法嗎 www
    也是具併發能力的 lisp 方言
    canesten
        8
    canesten  
       2014-07-23 19:50:15 +08:00 via Android
    对大量括号过敏所以无法直视lisp代码
    祝楼主幸福
    qiukun
        9
    qiukun  
       2014-07-23 20:19:10 +08:00
    @haroldwu 有尾递归了吗?
    haroldwu
        10
    haroldwu  
       2014-07-23 20:41:15 +08:00
    @qiukun 好犀利的問題 (汗
    我記得是因為 JVM 的關係所以不支持
    snoopy
        11
    snoopy  
       2014-07-23 20:43:01 +08:00
    赞,最近也开始学编译原理。正在看norvig的(An ((Even Better) Lisp) Interpreter (in Python))

    @haroldwu 《程序员的呐喊》中把clojure划分为保守的语言,因为clojure真的很保守。

    @kedebug 看来要学Go了,哎。
    baocaixiong
        12
    baocaixiong  
       2014-07-23 20:46:25 +08:00
    haroldwu
        13
    haroldwu  
       2014-07-23 21:03:22 +08:00
    @snoopy 嗨,能請你簡述一下保守的意思嗎?書不好取得 :P
    snoopy
        14
    snoopy  
       2014-07-23 22:30:39 +08:00
    @haroldwu 对宏的使用持保守态度
    standin000
        15
    standin000  
       2014-07-23 22:33:35 +08:00
    纯函数编程天生支持并发吧。
    kedebug
        16
    kedebug  
    OP
       2014-07-24 10:10:30 +08:00
    @standin000 由于函数式语言不存在状态,计算结果也不依赖于状态,也就是说所有变量都是 immutable,所以类似于

    fun1(x) + fun2(y)

    如果机器有 2 个核心的话,可以实现并行计算。这点在过程式语言就很难办到,因为 fun2(y) 中的变量可能会依赖 fun1(x) 的计算结果。

    至于 Lisp/Scheme,R5RS 中并没有定义 thread, mutex 啊等一系列东西。而 LispEx 是达到语义级别的支持,这点是和 Go 语言类似的。
    kedebug
        17
    kedebug  
    OP
       2014-07-24 10:14:49 +08:00
    @snoopy Don't panic.
    standin000
        18
    standin000  
       2014-07-24 16:59:33 +08:00   ❤️ 1
    @kedebug 对啊,那需要在解释器上去实现语义并发么?另外用宏就可以实现语法糖的。
    kedebug
        19
    kedebug  
    OP
       2014-07-24 20:57:54 +08:00
    @standin000 多谢提醒 :)

    搜了下 http://stackoverflow.com/questions/9400410/common-lisp-parallel-programming

    确实 Common Lisp 确实有利用宏展开以及编译选项实现 Concurrency,感觉有点撇脚。

    https://github.com/sionescu/bordeaux-threads/blob/master/src/default-implementations.lisp
    http://www.lispworks.com/documentation/lw60/CLHS/Body/s_eval_w.htm

    作者也说了:“ Of course, due to the nature of CL, it would likely be possible to implement these features without resorting to creating a new compiler. ”

    不像 Haskell 中 GHC 对于并发/并行的天然支持,在 CL 标准以及我参照的 R5RS 标准中(过于古老),都没有定义线程/进程的概念。所以我觉得 Go 语言这种现代编程语言的一些 idioms 还是很有借鉴/学习意义的(虽然早就在 FP 界提出) :)
    qinix
        20
    qinix  
       2014-07-25 11:11:39 +08:00 via iPhone
    是否支持调用外部golib ?
    kedebug
        21
    kedebug  
    OP
       2014-07-25 11:38:46 +08:00
    @qinix 非常不错的想法。
    在 LispEx 的基础上,我想是很容易扩展的,你可以定义如下类似原语:

    (import "fmt")
    (fmt/println "hello world")

    但是还有个问题:Go 语言是不支持动态调用 package 的:

    http://stackoverflow.com/questions/8076034/how-to-import-package-by-path-from-string-in-go

    所以在实现的过程中,要稍微费点周折,比如自己在 fmt 外围封装一层变成自己的 fmt.go 然后加以引用。具体感兴趣可以自己尝试下。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   2868 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 15:31 · PVG 23:31 · LAX 08:31 · JFK 11:31
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.