プログラミング言語 Cyan の紹介
Cyan ってどんな言語?
●

プログラミング言語 Cyan
http://www.geocities.jp/takt0_h/cyan/
2008 年 U-20 プログラミングコンテストで受
賞

●

http://www.jipdec.or.jp/archives/project/procon/work/2
当時高校2年の学生が作成
国産言語
どんな言語
既存の普及した言語で例えるなら
●

Object 指向 CommonLisp

●

マクロ付 Ruby

●

プロトタイプオグジェクト指向 Ruby
こんなカンジで例えると最初の取っ掛かりを
つかみやすい言語です
基本的な文法
●

●

実際に文法を”ざらっと”見て行きましょう
コメント
# 「#」から行末がコメントです
データ構造

●

1 # 整数

●

"Hello,Cyan!!" # 文字列
基本的な構文
●
●

[1, 2, 3 ,4] # リスト
%{ "Mt. Fuji" => "Shizuoka", "Mt. Aso" =>
"Kumamoto" } # ハッシュ

{ say(“HELLO”); } # ブロック
^(x) { say(x); } #  ラムダ
LL 言語使いなら見慣れた書式に近いのが分か
る
基本的な構文
●

# 関数呼び出し
say "Hello,World!" # 括弧 () は省略可能
# if 文
if( false ){
say "true"
} else {
say "false`"
}
基本的な構文
# while 文
i=0
while(i<5) {
say i
i++
}
基本的な構文
# Python 風のインデントでも記述できます
while(i<10):
say i
i++
if( false ):
say "true"
else:
say "false`"
基本的な構文、メソッド定義
●

# Prototype オブジェクト指向で JS 使いの感
覚に訴える書式です
# Object を継承した Human を作成

●

Human = Object.child()
Human.walk = ^(self, dir){
say(self.name + " walked " + dir + ".")
}
基本的な構文
●

引数クラスと引数展開
say &(1, *[2, 3], *%{ 'a => 4 }, *&(5, :b 6)) #=>
&(1, 2, 3, 5, :a 4, :b 6)

●
●

●

「 * 」で配列を展開して受け取る
引数の末尾では {} を省略してハッシュを渡
せる
「 & 」は " 引数オブジェクト " の定義記号
JS と Ruby 両方の合わせ技なカンジです
Cyan の特徴1(マクロの存在)
●

ここまでは多分似たような機構を他の言語で
触れている
この言語、マクロがちゃんとあるのが特徴
マクロの基本構文
準クォート「 ` 」の中で「 ? 」付けた変数は
展開されてプログラム中に埋め込まれる
recv = 2
args = &({ say "meow" })
# 2.times({ say("meow") }) という式を表示
say `(?recv).times(?*args)
マクロの使い道
実際にはどういう場面で役に立つのか?
# 例: cyan 本体に組み込まれているアナ
フォリックマクロ
aif( 10 ){
say it # 10 が表示される
}
# これとだいたい等価
if( it = 10 ){
say it
}
マクロの解説
実際にはこんなカンジで定義されています
mac(aif)^(cond, then, &key else):
`if(it := ?cond, ?then, :else ?else)
マクロを使うと関数定義では出来ない構文の
拡張が可能
これが第一の特徴
Cyan の特徴 2 メソッド編
●

List に定義されているメソッドを見る
http://www.geocities.jp/takt0_h/cyan/doc/ref/objects/lis
中身 :
car()
self の car を返します。
cdr()
self の cdr を返します。
car と cdr しか定義されていない!!
List.cy 探訪
●

その他のメソッドの定義は、初期化ファイル
群の中の list.cy にある
# Ruby の Array#each 相当のメソッド
def(List.foreach)^(fn):
unless(.null?()):
fn(.car())
.cdr().foreach(fn)
List#foreach の実行
書いて試してみる
[1,2,3].foreach ^(i){ say i; } # 1 〜 3 を表示
動いた!
他にも List#map や List#fold 等も定義されて
います
ほとんどのメソッドが cyan 自体で記述され
ている
Object.cy の中身
●

他にも object.cy のファイル名があるので中
を見てみる
def(Object.init)^{}
def(Object.new)^(&args args):
obj := .child()
obj.init(*args)
obj
オブジェクトの定義そのものがマクロ
while マクロ探訪
# control.cy
mac(while)^(test, body):
`loop:
if(!?test): break()
begin(?body)
実は while 文自体マクロ、 for 文もマクロ
なので unless 文なども if から作成可能
Cyan 全体の総論
総論:
Cyan という言語は
必要最小限のオブジェクトと構文のみを
Cyan 本体で定義して、その他の構文やメ
ソッドは Cyan 自体で書いてしまうという戦
略を取っている。
これは Cyan の美しさでありパワー
Cyan の欠点
●

●

●

先ほど出したように List#foreach からして再
帰構文
再帰する度にスタックに状態を溜める→メモ
リにやさしくない
Cyan のパフォーマンスを計ってみ
る
●

http://tanakahisateru.hatenablog.jp/entry/20081226/123
Ruby に対して 1/650

●

Scheme に対して 1/2000

●

Python に対して 1/6500

●

Scala に至っては 1/26000!
再帰構文が多用されるアルゴリズムでは破滅
的な速度低下を引き起こす
Cyan の欠点2
●
●

●

●

コンソールが死ぬほど使えない
「←」キーを打っても、キャレットが移動し
ない ( それどころか“ read error:” になる )
同じくコンソールで「↑↓」を押しても履歴
を見ない
「 delete 」キーでキャレットが謎のワープを
する事がある
Cyan の欠点 3
●

If 文で謎のインデントを強いられる
if( false ):
say "true"
else: # else が1文字インデントしている
say "false`"
インデントしないと変数と勘違いして
「 error: unbound variable: else 」
正直我慢できる程度に慣れる事はあっても、
生涯に渡って好きにならない自信がある
欠点総論
●

構文の最適化やコンソールなど、普通に作れ
ば解決できるはずの箇所の実装が全くなされ
ていない
Cyan 総論 1
Cyan 自体が生み出した新規の概念などは見
当たらないが他の言語の強力な書式をバラン
スよくまとめてある
Lisp の様に、今記述している問題を、関数や
マクロに切り出して、”対象の本質とは何
か”を切り出す力強さを持っている
Cyan=( 思案 ) という言語の名前の由来の一つ
でもある
Cyan 総論 2
●

●

●

実行速度やツール面などの作りこみが足りて
いない、そのまま放置されている
本体は、末尾再帰の最適化、 compile メソッド
等の速度改善が必要
これに単体テストフレームワークや .Net ライ
ブラリの簡潔な呼び出しなどの周辺ライブラ
リの整備いる、足りないので産業界に受け入
れられなかった、一言で言うと”残念な美人”
最後に
●

●

国産ですし、可能性のある言語なのでもう少
し評価されていいと思ってプレゼンしました
作者さん、次の言語作るならそれはそれでい
いので、今度は産業界に受け入れられるだけ
のものを待っています!!
以上、ありがとうございました!!

プログラミング言語Cyanの紹介

Editor's Notes