<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>kedebug (kedebug)</title>
    <link>https://ruby-china.org/kedebug</link>
    <description></description>
    <language>en-us</language>
    <item>
      <title>LispEx - 让 Lisp 支持并发编程</title>
      <description>&lt;p&gt;LispEx 是用 Go 语言编写的一款符合 R5RS 标准的 Lisp 解释器。&lt;/p&gt;

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

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

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;遵守 KISS 原则，尽量把代码设计的简单，易懂。很多模块被很好的分离出来，想添加新的语义支持的话，只需要添加、修改个别文件的源代码。 &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;借鉴了王垠大神 Yin 语言的代码设计思路：任何一个 Node 都会被解释成 Value；Parser 被拆分成了 2 个阶段：包括预处理生成语法单元，然后 Parse 成语法树。顺着这个思路，代码会变得非常易读，当然在设计的时候针对这点是费了很多心思的，希望对一些后人能有借鉴意义。 &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;并发的词法分析器。这点 Rob Pike 在 &lt;a href="http://cuddle.googlecode.com/hg/talk/lex.html#title-slide" rel="nofollow" target="_blank"&gt;http://cuddle.googlecode.com/hg/talk/lex.html#title-slide&lt;/a&gt; 提到过。LispEx 把它实践了一遍。 &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Go liked 并发语义支持。下面一段代码演示了并发编程里面经典的 ping-pong 案例，并且借助 channel 实现了信号量：&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;; 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 (&amp;gt; n 0)
    (begin
      (display (&amp;lt;-chan ping-chan))
      (newline)
      (chan&amp;lt;- pong-chan 'pong)
      (ping (- n 1)))
    (chan&amp;lt;- sem 'exit-ping)))

(define (pong n)
  (if (&amp;gt; n 0)
    (begin
      (chan&amp;lt;- ping-chan 'ping)
      (display (&amp;lt;-chan pong-chan))
      (newline)
      (pong (- n 1)))
    (chan&amp;lt;- sem 'exit-pong)))

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

; implement semaphore with channel, waiting for ping-pong finishing
(&amp;lt;-chan sem) (newline)
(&amp;lt;-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
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;再来一段 select 语义示例：&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(define chan-1 (make-chan))
(define chan-2 (make-chan))

(go (chan&amp;lt;- chan-1 'hello-chan-1))
(go (chan&amp;lt;- chan-2 'hello-chan-2))

; sleep for 20 millisecond
(sleep 20)

(select
  ((&amp;lt;-chan chan-1))
  ((&amp;lt;-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

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;更多精彩代码演示请见： &lt;a href="https://github.com/kedebug/LispEx" rel="nofollow" target="_blank"&gt;https://github.com/kedebug/LispEx&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;PS:
LispEx 已经被 Go Community Wiki 和 Hacker News 收录:
&lt;a href="https://code.google.com/p/go-wiki/wiki/Projects#Virtual_Machines_and_Languages" rel="nofollow" target="_blank"&gt;https://code.google.com/p/go-wiki/wiki/Projects#Virtual_Machines_and_Languages&lt;/a&gt;
&lt;a href="https://news.ycombinator.com/item?id=8074334" rel="nofollow" target="_blank"&gt;https://news.ycombinator.com/item?id=8074334&lt;/a&gt;&lt;/p&gt;</description>
      <author>kedebug</author>
      <pubDate>Tue, 02 Sep 2014 20:30:14 +0800</pubDate>
      <link>https://ruby-china.org/topics/21351</link>
      <guid>https://ruby-china.org/topics/21351</guid>
    </item>
  </channel>
</rss>
