LispEx - 让 Lisp 支持并发编程 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
爱意满满的作品展示区。
kedebug
V2EX    分享创造

LispEx - 让 Lisp 支持并发编程

  •  7
     
  •   kedebug 2014-07-23 17:23:40 +08:00 6302 次点击
    这是一个创建于 4174 天前的主题,其中的信息可能已经有所发展或是发生改变。
    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
    第 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     Solana     2778 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 22ms UTC 02:25 PVG 10:25 LAX 18:25 JFK 21:25
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86