2014年5月30日金曜日

cl-coroutine: a coroutine library for Common Lisp


CL-COROUTINE is a coroutine library for Common Lisp. It uses CL-CONT continuations library in its implementation.


https://github.com/takagi/cl-coroutine

;; define a coroutine using DEFCOROUTINE macro 
(defcoroutine example (whom) 
  (format t "First greeting to: ~A~%" whom) 
  (yield 1) 
  (format t "Second greeting to: ~A~%" whom) 
  (yield 2) 
  (format t "Third greeting to: ~A~%" whom) 
  (coexit 3) 
  (format t "No greeting to: ~A~%" whom) 
  (yield 4)) 
=> EXAMPLE 

;; make a coroutine object 
(setf coroutine (make-coroutine 'example)) 
=> a coroutine object 

;; funcall it 
(funcall coroutine "Smith") 
>> First greeting to: Smith 
=> 1 

I want your feedback. Thanks.

 

SBCL (Steel Bank Common Lisp) のビルドプロセス

SBCL のビルドプロセスの外観


Common Lisp の実装の1つである SBCL (Steel Bank Common Lisp) のビルドプロセスは、Allegro Common Lisp や LispWorks といった、イメージベースでそれ自身の上でのみビルド可能な Common Lisp 実装とは異なり、SBCL 以外の Common Lisp 実装の上でもビルドできます。それを実現するために、SBCL のビルドプロセスでは、様々なテクニックが使われています。

このエントリでは、SBCL のビルドプロセスを順を追って説明します。

host-1 ビルドステージ


まず、ホスト上にクロスコンパイラを読み込みます。SBCL のソースコードをホストコンパイラでコンパイルしロードすることで、ホスト上にクロスコンパイラを展開します。

続いて、後のステージのための前処理として、sb!fasl:genesis の読み込みと、C ヘッダファイルの出力を行います。sb!fasl:genesis は、genesis-2 ビルドステージで、'cold core' を生成するために使われます。C ヘッダファイルは、続く target-1 ビルドステージで、SBCL の実行形式を構築するのに使われます。

target-1 ビルドステージ


target-1 ビルドステージでは、大きく2つの処理が行われます。1つは、SBCL 実行形式の構築です。host-1 ビルドステージで生成された C ヘッダファイルと、その他の C ソースファイルおよびアセンブリファイルから、SBCL の実行形式を構築します。ただし、この実行形式は、この時点ではまだ動作しません。OS サービスへのインターフェイスやガベージコレクタを提供するものの、次ステージ以降で生成されるターゲットメモリイメージを含まないためです。

もう1つの処理は、ターゲットの一部として使用される Lisp ソースコードの生成です。この Lisp ソースコードは、小さな C プログラムをコンパイルおよび実行することで生成され、システム依存の定数と型に関する情報を提供します。

host-2 ビルドステージ


このステージでは、SBCL 用のオブジェクトファイル (FASL ファイル) が生成されます。オブジェクトファイルは、クロスコンパイラ版の compile-file を用いて、SBCL ソースコードを再度コンパイルすることで得られます。このとき、SBCL ソースコードの他に、host-1 ビルドステージで生成した Lisp ソースコードを併せて用いることで、クロスコンパイラ上の定数定義を、システム環境に応じたものに更新します。

genesis-2 ビルドステージ


続いて、genesis-2 ビルドステージに入ります。ここでは、host-1 で読み込んだ sb!vm:genesis を用いて、FASL ファイルのロードとメモリイメージの保存をシミュレートします。sb!vm:genesis が必要となる理由は、ホストコンパイラの load 関数では、SBCL の FASL 形式をロードできず、また、SBCL のターゲットイメージがまだ存在しないことからその load 関数を使うこともできないためです。

ここで行う処理は、次のように進みます。まず、特定の順序で擬似的に FASL ファイルをロードし、メモリイメージを展開します。次に、ターゲットのメモリ領域をバイト配列とみなし、FASL ファイルをロードしたときに起こるであろう処理をシミュレートします。この方法で実行できない処理は、ターゲットイメージの初期化関数が実行されるまで遅延されます。すべての FASL ファイルがこの方法で処理された後、メモリ領域を SBCL 実行形式が期待する形式でファイルに保存します。これで 'cold core' が生成されました。

最後に、'cold core' をメモリイメージとして、SBCL 実行形式を起動します ('cold init')。遅延されていたトップレベル・フォームの処理などは、このタイミングで実行されます。'cold init'は、助けになる Lisp デバッガが存在しないことから最もデバッグしづらいため、現在の SBCL のビルドプロセスにおいて、もっとも脆弱な箇所といえます。

target-2 ビルドステージ


SBCL のビルドプロセスの最終ステージが、target-2 ビルドステージです。まず、パッケージを最終的な名前に変更し、sb! プレフィックスを、sb- プレフィックスとします。次に、SBCL に特殊化されたバージョンの Portable Common Loops (PCL) をコンパイルし、ロードします。最後に、そうしてできた新しいメモリイメージを、output/sbcl.core として保存します。

これで、ビルドプロセスが完了しました。

まとめ


このエントリでは、SBCL のビルドプロセスを順を追って説明しました。SBCL のアプローチにもメリット・デメリットはありますが、このような仕組みでセルフ・ブートストラッピングを実現しているというのは、興味深いところです。

参考


SBCL - a Sanely-Bootstrappable Common Lisp
http://www.doc.gold.ac.uk/~mas01cr/papers/s32008/sbcl.pdf
 

2014年5月20日火曜日

Cl-reexport: symbol reexporting library for common lisp


Cl-reexport is a library to reexport symbols which are external symbols in other packages. It is valuable when virtually construct package hierarchy on Common Lisp standard's flat package system. 

https://github.com/takagi/cl-reexport 

ASDF 3 has similar one-package-per-file facility. The structural difference between them is: 


* Virtual hierarchy packages in this context have one system definition and several packages constituting a hierarchical structure. 

* ASDF 3's one-package-per-file style has hierarchical system definitions and hierarchical packages, which are corresponding each other. 

Since ASDF 3's one-package-per-file style has not been de facto standard yet, there may be some cases where cl-reexport is useful. 

Currently requesting to Quicklisp to register. 

I want your feedback.