Chicken Schemeを使ってネイティブアプリ開発

Schemeの話

今回はCommon Lispから離れて、Schemeのお話です。
Schemeとは、Lisp方言*1の一つで現代ではCommon Lispと並ぶ二大巨頭です。*2

今回はSchemeの処理系の一つ、「Chicken Scheme」を紹介します。

Chicken Schemeとの出会い

私自身、このChicken Schemeが初めて開発目的で使用したLisp処理系になります。
今回、あえてChicken Schemeの話をするのは開発のメイン環境をChickenに戻そうと考えているからです。

Common Lispの強力な言語仕様は魅力的ですので、webサーバ開発や私的利用ツールの開発にはこれ以上ないほど強力なのですが、一つ欠点がありました。

それは、無償の処理系で充分に実用的なサイズのネイティブアプリケーションを作成できないということです。
Common Lispの場合、スタンドアローンな実行形式はCommon Lisp環境のコアダンプになるので、どうしてもサイズ肥大化してしまいます。
実行速度・開発効率を兼ね備えていたのは確かですが、この欠点のため「エンドユーザ向けのネイティブアプリケーション開発」目的では、Common Lispは使用が難しいと判断しました。

そこで、この開発目的に合致した処理系Chicken Schemeに再び戻ることにしました。

Chicken Scheme

Chicken Schemeは実用性を重視したScheme処理系です。
http://www.call-cc.org/

Chicken Schemeの主な特徴は次のようなものです。

  • C言語トランスレート式のコンパイラ
  • C言語との高い親和性
  • 高い可搬性
  • 実用性を重視した豊富な処理系拡張
  • eggsによる拡張ライブラリの提供

ほとんどの環境でシステム開発言語としてC言語やその派生言語が利用されている現代では、実用的な用途に使用するには無くてはならない機能です。

数値計算や解析目的、私的利用ツール作成ではあまり必要としない特性ですが、エンドユーザ向けのアプリケーション開発の場合、無くてはならない特徴です。

C言語トランスレート方式

Chicken Schemeインタプリタはもちろんコンパイラを兼ね備えています。
コンパイラC言語トランスレート方式です。
Chickenは、Schemeのプログラム*3を一旦Cのソースコードに変換し、ホスト環境のC言語コンパイラを利用してネイティブプログラムにコンパイルします。

この性質が現実的なプログラム開発する上で非常に有利に働きます。

  • 現在の主要なターゲットはC言語をサポートしているので、可搬性が高い
  • ネイティブのライブラリを容易にリンクできる
  • C言語の充分に枯れた処理系による最適化の恩恵を受けられる
  • Chicken自体もスタティックライブラリがあり、容易にアプリケーションに組み込むことができる

C言語との高い親和性

Chicken SchemeではC言語のスタック領域を利用するため、外部ライブラリの関数を比較的少ないオーバーヘッドで呼び出すことができます。
またCFFIを処理系がサポートしているため、C言語向けのライブラリを作成することが容易に可能です。

OpenGLを使う

Chicken Schemeをインストールしてしまえば、すぐにOpenGL, GLUTを利用してアプリケーション開発を始めることができます。

Extensionのインストール

まずOpenGLGLUTのextensionをインストールします。
chicken-install -s opengl glut
Chicken Schemeにはchicken-installというeggs拡張ライブラリをインストールするツールがあるので、すぐに拡張ライブラリを準備することができます。

シンプルなGLUTコード

小さなGLUTを呼び出すコードを用意します。

(require-extension gl glut)

(glut:CreateWindow "sample")
(glut:DisplayFunc
  (lambda ()
    (gl:Clear gl:COLOR_BUFFER_BIT)
    (gl:Flush)))
(glut:MainLoop)

注意すべきな点は、Chicken Schemeは標準でcase-sesitiveであることです。
これはChicken Schemeの大きな欠点の一つですが*4case-sensitiveであるC言語に合わせることでライブラリの移植が容易になるための妥協と思われます。

終わりに

C言語の経験があるプログラマには非常に馴染みやすいScheme処理系です。
今後は記事のメインはChicken Schemeになっていきます。(Common Lispはしばらくお休みです)

*1:Lisp系の言語のことをLisp方言と言います。

*2:他にもClojure, Arcなど現代でも使用されるLisp方言はあります。

*3:Lispではソースコードとプログラムがread<->printによって変換されるため、ソースコードとプログラムデータを明確に区別して意識します。

*4:Symbolをファストクラスオブジェクトとして扱うLispではcase-sensitiveは混乱を招きやすく、古くから伝統的にcase-insesitiveであった。