<p>鄙人的 <a href=“http://github.com/infinte/eisa”>Eisa</a> 虽说目前还很原始,但是基本上已经可以用了。基于 Necessaria 包管理器摆平客户端,Node 摆平服务器,你就可以结合 Eisa 语言的优点和无数已有的 JavaScript 类库,轮子不用造了,人参更美满了……</p> <br/> <br/><p>本文直接ネタ<a href=“http://cnodejs.org/blog/?p=1730”>小问的文章</a>,源码都是照抄来的,并换成了等价的 Eisa 形式。我省略了包导入的部分。</p> <br/> <br/><div class=“section”><h2>Backbone?很简单</h2><pre><span class=“comment”>// Eisa version by Belleve Invis</span> <br/> <br/><span class=“comment”>// Note that chained(f) returns a function.</span> <br/><span class=“comment”>// syntax:</span> <br/><span class=“comment”>// def f(x) = expression</span> <br/><span class=“comment”>// def f(x): statements end</span> <br/><span class=“keyword”>def</span> <span class=“identifier”>chained</span><span class=“punctor”>(</span><span class=“identifier”>f</span><span class=“punctor”>)</span> <span class=“operator”>=</span> <span class=“keyword function”>function</span><span class=“punctor”>:</span> <br/> <span class=“identifier”>f</span><span class=“punctor”>.</span><span class=“identifier”>apply</span> <span class=“keyword”>this</span><span class=“punctor”>,</span> <span class=“keyword”>arguments</span> <br/> <span class=“keyword flowctrl”>return</span> <span class=“keyword”>this</span> <br/><span class=“keyword”>end</span> <br/> <br/><span class=“comment”>// Model of Backbone</span> <br/><span class=“keyword”>def</span> <span class=“identifier”>Person</span> <span class=“operator”>=</span> <span class=“identifier”>Backbone</span><span class=“punctor”>.</span><span class=“identifier”>model</span><span class=“punctor”>.</span><span class=“identifier”>extent</span> <span class=“punctor”>{</span> <br/> <span class=“identifier”>sayHello</span><span class=“punctor”>:</span> <span class=“identifier”>chained</span> <span class=“punctor”>{</span> <span class=“identifier”>alert</span> <span class=“string literal”>“Hey, I’m “</span> <span class=“operator”>+</span> <span class=“operator”>@</span><span class=“identifier”>get</span><span class=“punctor”>(</span><span class=“string literal”>‘name’</span><span class=“punctor”>)</span> <span class=“operator”>+</span> <span class=“string literal”>”.”</span> <span class=“punctor”>}</span><span class=“punctor”>,</span> <br/> <span class=“identifier”>setName</span><span class=“punctor”>:</span> <span class=“identifier”>chained</span> <span class=“punctor”>{</span><span class=“operator”>|</span><span class=“identifier”>name</span><span class=“operator”>|</span> <br/> <span class=“operator”>@</span><span class=“identifier”>set</span> <span class=“punctor”>{</span><span class=“string literal”>‘name’</span><span class=“punctor”>:</span> <span class=“identifier”>name</span><span class=“punctor”>}</span> <br/> <span class=“identifier”>alert</span> <span class=“string literal”>“My name is “</span> <span class=“operator”>+</span> <span class=“operator”>@</span><span class=“identifier”>get</span><span class=“punctor”>(</span><span class=“string literal”>‘name’</span><span class=“punctor”>)</span> <span class=“operator”>+</span> <span class=“string literal”>”.”</span> <br/> <span class=“punctor”>}</span> <br/><span class=“punctor”>}</span> <br/> <br/><span class=“keyword”>var</span> <span class=“identifier”>Will</span> <span class=“operator”>=</span> <span class=“identifier”>Person</span><span class=“punctor”>.</span><span class=“identifier”>new</span><span class=“punctor”>(</span><span class=“punctor”>)</span> <br/><span class=“identifier”>Will</span> <span class=“operator”>|</span><span class=“punctor”>.</span><span class=“identifier”>setName</span> <span class=“string literal”>‘Will Wen Gunn’</span> <br/> <span class=“operator”>|</span><span class=“punctor”>.</span><span class=“identifier”>sayHello</span> <br/></pre></div><div class=“section”><h2>Mustache —— 做异步很简单啊!</h2><p>由于 Eisa 自带异步库和阻塞原语,所以就不用朴灵兄的 EventProxy 啦,直接上!</p> <br/><pre><span class=“comment”>// 注意:async 库是浏览器专用的</span> <br/><span class=“comment”>// 源码在 src/lib/async.js</span> <br/> <br/><span class=“keyword”>do</span> <span class=“identifier”>async</span><span class=“punctor”>.</span><span class=“identifier”>async</span> <span class=“punctor”>{</span> <br/> <span class=“keyword”>def</span> <span class=“identifier”>results</span> <span class=“operator”>=</span> <span class=“identifier”>async</span><span class=“punctor”>.</span><span class=“identifier”>join</span><span class=“punctor”>!</span> <span class=“punctor”>{</span> <br/> <span class=“identifier”>data</span><span class=“punctor”>:</span> <span class=“punctor”>{</span><span class=“operator”>|</span><span class=“identifier”>resend</span><span class=“operator”>|</span> <span class=“identifier”>$</span><span class=“punctor”>.</span><span class=“identifier”>getJSON</span><span class=“punctor”>(</span><span class=“identifier”>location</span><span class=“punctor”>.</span><span class=“identifier”>origin</span> <span class=“operator”>+</span> <span class=“string literal”>’/persons’</span><span class=“punctor”>,</span> <span class=“identifier”>resend</span><span class=“punctor”>)</span> <span class=“punctor”>}</span><span class=“punctor”>,</span> <br/> <span class=“identifier”>template</span><span class=“punctor”>:</span> <span class=“punctor”>{</span><span class=“operator”>|</span><span class=“identifier”>resend</span><span class=“operator”>|</span> <span class=“identifier”>$</span><span class=“punctor”>.</span><span class=“identifier”>get</span><span class=“punctor”>(</span><span class=“identifier”>location</span><span class=“punctor”>.</span><span class=“identifier”>origin</span> <span class=“operator”>+</span> <span class=“string literal”>’/tmpls/persons.html’</span><span class=“punctor”>,</span> <span class=“identifier”>resend</span><span class=“punctor”>)</span> <span class=“punctor”>}</span> <br/> <span class=“punctor”>}</span><span class=“punctor”>;</span> <br/> <span class=“identifier”>$</span><span class=“punctor”>(</span><span class=“string literal”>‘body’</span><span class=“punctor”>)</span><span class=“punctor”>.</span><span class=“identifier”>append</span> <span class=“identifier”>Mustache</span><span class=“punctor”>.</span><span class=“identifier”>to_html</span><span class=“punctor”>(</span><span class=“identifier”>results</span><span class=“punctor”>.</span><span class=“identifier”>template</span><span class=“punctor”>,</span> <span class=“identifier”>results</span><span class=“punctor”>.</span><span class=“identifier”>data</span><span class=“punctor”>)</span> <br/><span class=“punctor”>}</span> <br/></pre><p>相比 EventProxy,这里流程既简单又清楚。<pre><code>async.async</pre></code> 会处理包含异步调用(这里是 <pre><code>async.join</pre></code>,看那个感叹号)的代码块(这玩意叫阻塞原语),把它变成使用类似自动机的机构。<pre><code>async.join</pre></code> 会平行地启动多个任务并且聚合它们,结果会合成为一个对象“返回”。</p> <br/></div><div class=“section”><h2>Web.js 的 router</h2><pre><span class=“keyword”>def</span> <span class=“identifier”>urlRouter</span> <span class=“operator”>=</span> <span class=“punctor”>{</span> <br/> <span class=“string literal”>’^(\d{4})/(\d{2})/(\d{2})/(.*).jpg’</span><span class=“punctor”>:</span> <span class=“string literal”>’$1-$2-$3-$4.jpg’</span><span class=“punctor”>,</span> <br/> <span class=“string literal”>‘google’</span><span class=“punctor”>:</span> <span class=“string literal”>‘http://www.google.com’</span><span class=“punctor”>,</span> <br/> <span class=“string literal”>‘iwillwen’</span><span class=“punctor”>:</span> <span class=“string literal”>‘http://www.iwillwen.com’</span> <br/><span class=“punctor”>}</span> <br/><span class=“keyword”>def</span> <span class=“identifier”>getRouter</span> <span class=“operator”>=</span> <span class=“punctor”>{</span> <br/> <span class=“string literal”>’^getsomthing’</span><span class=“punctor”>:</span> <span class=“keyword function”>function</span><span class=“punctor”>(</span><span class=“identifier”>req</span><span class=“punctor”>,</span> <span class=“identifier”>res</span><span class=“punctor”>,</span> <span class=“identifier”>qs</span><span class=“punctor”>)</span><span class=“punctor”>:</span> <br/> <span class=“identifier”>res</span><span class=“punctor”>.</span><span class=“identifier”>sendJSON</span> <span class=“identifier”>qs</span> <br/> <span class=“keyword”>end</span><span class=“punctor”>,</span> <br/> <span class=“string literal”>’^car’</span><span class=“punctor”>:</span> <span class=“keyword function”>function</span><span class=“punctor”>(</span><span class=“identifier”>req</span><span class=“punctor”>,</span> <span class=“identifier”>res</span><span class=“punctor”>,</span> <span class=“identifier”>qs</span><span class=“punctor”>)</span><span class=“punctor”>:</span> <br/> <span class=“keyword flowctrl”>case</span> <span class=“identifier”>qs</span><span class=“punctor”>.</span><span class=“identifier”>action</span><span class=“punctor”>:</span> <br/> <span class=“keyword flowctrl”>when</span> <span class=“string literal”>‘foo’</span><span class=“punctor”>:</span> <span class=“identifier”>res</span><span class=“punctor”>.</span><span class=“identifier”>send</span> <span class=“string literal”>‘Your action is foo’</span> <br/> <span class=“keyword flowctrl”>when</span> <span class=“string literal”>‘bar’</span><span class=“punctor”>:</span> <span class=“identifier”>res</span><span class=“punctor”>.</span><span class=“identifier”>send</span> <span class=“string literal”>‘Your action is bar’</span> <br/> <span class=“keyword”>end</span> <br/> <span class=“keyword”>end</span> <br/><span class=“punctor”>}</span> <br/><span class=“keyword”>def</span> <span class=“identifier”>postRouter</span> <span class=“operator”>=</span> <span class=“punctor”>{</span> <br/> <span class=“string literal”>’^postsomthing’</span><span class=“punctor”>:</span> <span class=“keyword function”>function</span><span class=“punctor”>(</span><span class=“identifier”>req</span><span class=“punctor”>,</span> <span class=“identifier”>res</span><span class=“punctor”>,</span> <span class=“identifier”>data</span><span class=“punctor”>)</span><span class=“punctor”>:</span> <br/> <span class=“identifier”>res</span><span class=“punctor”>.</span><span class=“identifier”>sendJSON</span> <span class=“identifier”>qs</span> <br/> <span class=“keyword”>end</span><span class=“punctor”>,</span> <br/> <span class=“string literal”>’^car’</span><span class=“punctor”>:</span> <span class=“keyword function”>function</span><span class=“punctor”>(</span><span class=“identifier”>req</span><span class=“punctor”>,</span> <span class=“identifier”>res</span><span class=“punctor”>,</span> <span class=“identifier”>data</span><span class=“punctor”>)</span><span class=“punctor”>:</span> <br/> <span class=“keyword flowctrl”>case</span> <span class=“identifier”>data</span><span class=“punctor”>.</span><span class=“identifier”>action</span><span class=“punctor”>:</span> <br/> <span class=“keyword flowctrl”>when</span> <span class=“string literal”>‘foo’</span><span class=“punctor”>:</span> <span class=“identifier”>res</span><span class=“punctor”>.</span><span class=“identifier”>send</span> <span class=“string literal”>‘Your action is foo’</span> <br/> <span class=“keyword flowctrl”>when</span> <span class=“string literal”>‘bar’</span><span class=“punctor”>:</span> <span class=“identifier”>res</span><span class=“punctor”>.</span><span class=“identifier”>send</span> <span class=“string literal”>‘Your action is bar’</span> <br/> <span class=“keyword”>end</span> <br/> <span class=“keyword”>end</span> <br/><span class=“punctor”>}</span> <br/> <br/><span class=“identifier”>web</span><span class=“punctor”>.</span><span class=“identifier”>run</span> <span class=“identifier”>urlRouter</span><span class=“punctor”>,</span> <span class=“number literal”>80</span> <br/> <span class=“operator”>|</span><span class=“punctor”>.</span><span class=“identifier”>get</span> <span class=“identifier”>getRouter</span> <br/> <span class=“operator”>|</span><span class=“punctor”>.</span><span class=“identifier”>post</span> <span class=“identifier”>postRouter</span><span class=“punctor”>;</span> <br/> <br/><span class=“identifier”>console</span><span class=“punctor”>.</span><span class=“identifier”>log</span> <span class=“string literal”>‘The app is running on http://localhost’</span> <br/> <br/></pre><p>从案例可以看出,第一,因为 Eisa 有真正的常量,原先很多用 var 的“常量”如今有了名分;第二,Eisa 的函数可以省略括弧,进一步减少冗余的字符数;第三,Eisa 的多路分支没有贯穿(fall through),语义更加明确。</p> <br/> <br/><p>各位可以去 <a href=“http://github.com/infinte/eisa”>http://github.com/infinte/eisa</a> 来围观我的项目。</p>
我对语言无所谓,不过确实懒得学一门为了语言而语言的语言。