電動ひやむぎ

2012-12-04

神という名の言語

このエントリーをはてなブックマークに追加

(このエントリは Lisp Advent Calendar 2012 4日目の記事です。)

Advent Calendarの参加登録のときには「Common Lispで、何かを。」とか言っておきながら、全然違うものを書きます。

神(SHEN)という名のプログラミング言語が存在します。QiというLisp方言の進化系らしいです。ロゴが非常にイカしています。名前も非常にイカしています。パターンマッチだとか 統合されたPrologだとか静的型だとか、いろいろ特徴があるようなのですが ロゴと名前が非常にイカしています。

(注意:先に宣言しておきますが、書いてる本人は Shenをほとんど使ったことがなく、Shenのステキ機能が全然引き出せていません。このエントリは、タイトルを見た時点でほとんど終わっています)

SBCLとかClojureとかJavaScript上で動作します。僕はWindows SBCL版しか試したことがないので、JavaScript版やClojure版がどんな感じなのか不明ですが、いろいろな環境で試すことが出来て楽しそう。この辺りからダウンロード出来るので、試したい人は是非試しましょう。

たらい回しをしてみる

(define tarai  
  X Y Z -> Y where (<= X Y)  
  X Y Z -> (tarai (tarai (- X 1) Y Z)  
                  (tarai (- Y 1) Z X)  
                  (tarai (- Z 1) X Y))) 

みんな大好き、竹内関数です。

defineで関数定義、関数名に続く 先頭大文字のシンボル達が引数(仮引数)であり -> の後が 関数本体になります。引数は XYZの3つで、本体は 2種類存在します。

第2引数(Y)が 第1引数(X)以上の場合((<= X Y))には最初の本体である Yが評価され、そうではない場合には tarai関数を再帰的に呼ぶ本体が評価されます。ちなみに普通な感じで

(define tarai X Y Z ->  
  (if (<= X Y)  
      Y  
      (tarai (tarai (- X 1) Y Z)  
             (tarai (- Y 1) Z X)  
             (tarai (- Z 1) X Y)))) 

と書くことも出来ます。このような簡単な内容だと、普通に書くほうが楽な気もします。

その他の関数を書いてみる

階乗を求める関数は、こんな感じで非常に分かりやすい!

(define fact  
  0 -> 1  
  X -> (* X (fact (- X 1)))) 

リストを引数として取り、要素を 全部printする関数はこんな感じ。たぶん、もっと上手い書き方があると思いますけど。ちなみに Shenでは []がListです。空のリストの場合は、空のリストを返します。要素のあるリストの場合は、リストの先頭(CAR)が Xに、残りの要素(CDR)が Yに。後は printして、new lineを出力して、CDRに対して再帰。

(define print-list  
  [] -> []  
  [X | Y] -> (do (print X)  
                 (nl 1)  
                 (print-list Y))) 

Shenって結局どうなの?

実用性がどうとか、僕にはまだ言えないです。よく分かっていません。

ただ、非常に意欲的なLisp方言だと思います。ユーザ数が少ないのでライブラリの充実度とか考えると厳しいですが、それは新しい言語ならばどれでも似たようなものですよね。そもそもLisp族自体が現代ではマイナー言語な雰囲気なので、超マイナーなShenは暖かく見守ってあげて欲しいです。そして、使って、フィードバックして、ライブラリ書いて、育てて欲しいです。

何より、ロゴと名前が非常にイカす。