LISPUSER

Qi - Lisp for 21 CenturyLisp isn't a language, it's a building material.

(Top Page) (Lisp Memo)

公式ページhttp://www.lambdassociates.org/
最新バージョンQi II 1.0

Japanese Translation (翻訳)

Twelve FAQs on Qi II

This is a Japanese translation of Twelve FAQs on Qi II (c) Mark Tarver

1. Qi II って何?

2008年11月に導入され、Common Lisp によって実装された言語です。 Qi II は効率的で型安全な Lisp プログラムを生成し、そのプログラムはいかなるマシン上でも動作させることができます。 Qi II は私が2005年4月に導入したQi Iをさらに進化させたものです。

2. Lisp じゃなくて Qi で書く事の利点は何?

たくさん:

  • Qi II は CAR / CDR を強制しない。かわりに、パターンマッチを使う事ができる。典型的な Qi プログラムは Lisp プログラムと比較して非空白文字が40%程度になる。
  • Qi II はオプショナルな静的型チェックを備えている。実際のアプリケーションで、「神さま、プログラムが型エラーでクラッシュしませんように…」と祈る必要がなくなる。
  • Qi II はラムダ計算と一貫性がある。Common Lisp で部分適用のような概念が利用できる。
  • Qi II はとても速いコードを生成する。

3. もし Qi を選んだら、Lisp をあきらめなきゃならないの?

そんなことは絶対にありません。 実際、あなたは Qi II と Lisp の関数を一つのファイルに混ぜて書いたり、ロードしたりする事もできます。 Qi II コードの中で Lisp 関数をつかうことには何の問題もありません。 Lisp で書いた関数に対して Qi II の型宣言を追加して、型システムに取り込むことも可能です。

4. ML や Haskell に比べて Qi で書く事の利点は?

Qi II は Lisp の上で動作します。 それは、つまり Qi II は ML や Haskell にない Lisp の特徴 – マクロ、EVAL、ハッシュテーブル、プロパティリスト、メタプログラミングなど – を受け継いているということです。 Qi II にとっては静的型付けはオプショナルです。もし型チェックが邪魔な場合には、それを使う必要はありません。 あなたが型チェックしたい部分のコードだけを選択的にチェックできのです。 Qi II の型宣言はシークエント記法をつかっていますが、これは ML や Haskell が使っているものよりも柔軟で、もっと強力なものです。 理由は プレゼンテーション を見てください。

5. Qi II を覚えるのは難しい?

Lisp プログラマなら Qi II のコア部分を覚えるのは 15 分程度で済みます。きっと、得られるものには価値があると思います。

6. Qi II のドキュメントってどんなものがあるの?

たくさんあります。オンラインドキュメントのページを参照してください。

また、ケーススタディもあります。

7. Qi II はフリーなの?

そうです。Qi II は教育目的と個人利用にはフリーです。 本 (Functional Programming in Qi 2nd edition) に附属の商用ラインセスを使えば、クローズドソースなアプリケーションを作成する事もできます。

8. Qi II がサポートしているプラットフォームは?

Qi は CLISP, CMUCL, SBCL, LispWorks, Allegro Common Lisp で動作します。 CLISP は想定されるプラットフォームのほとんどすべてで動作するえしょう。

9. Qi II は Lisp よりも遅いの?

いいえ。Qi はほとんどの手書された Lisp コードよりも高速に動作します。

10. 何か Qi II で書かれたものってある?

もちろん! まず Qi II 自身が Qi II で書かれています。 いつくかのライブラリ、Qi-PrologQi-YACC といったものが Qi もしくは Qi と Lisp によって書かれています。

11. Qi I と Qi II の違いは何?

ここを参照してください。

12. Qi で困ったことがあったら助けを得ることができる?

大丈夫、Google に 150 人以上が登録しているユーザーグループがあります。

Qi II - What's New?

This is a Japanese translation of What's New? (c) Mark Tarver

Qi I プログラムはほとんど問題なく Qi II でも動作させることができます。しかし、次に示すようにかなり多くの改良点があります:

  • 一からの完全な Qi の再実装
  • 新しいライセンス
  • 型安全なオンデマンド遅延評価
  • プログラマブルな構文の改良
  • 型情報をつかった4段階可変速コンパイラ
  • Common Lisp との統合の改良
  • LispWorks での動作
  • 共通関数の多引数化
  • Prolog との接続の強化
  • シークエントへの埋め込みのためのルールクロージャ (Rule closures for embedding sequent reasoning into Qi functions)
  • 依存型の扱いの改良
  • 型安全なクラスシステムラリブラリ (FPQi第二版に附属)
  • 完全なドキュメント 'Functional Programming in Qi (second edition)'

完全な再実装

Qi II は Qi の完全な再実装です。 すべてのコードは Qi YACC 7.0 をつかって大規模に書き直されました。 いくつかの古い機能は再設計され、古いコードはリファクタリングされています。 Qi YACC を使う事により、 Qi のソースコードは 160K から 100K のディスクサイズに小さくなりました。 この新しいシステムは小さくなっただけではなく、古いものよりさらに強力なものとなり、メンテナンスも容易になっています。 Qi II におけるすべての読み込み/表示ルーチン (read-print) は Qi YACC によって動いています。

新しいライセンス

Qi のもっとも不人気な特徴は GPL ライセンスだっため、廃止されました。 (訳注: GPL だとクローズソースの商用につかえない、というクレームがいっぱいきていた。メーリングリストでの議論を参照) 明確なデュアルライセンスを採用します。一つはオープンソースと個人利用と教育目的の使用における自由です。 それともう一つ、本を買う事でクローズドソースな製品を作成できる商用ライセンスの権利が与えられます(ただし Qi のオープンソースについては尊重してください)。 ここにソフトウェアについてくる個人利用向けのライセンスは以下のとおり:

This software is licensed only for personal and educational use and not for the production of commercial software. Modifications to this program are allowed but the resulting source must be annotated to indicate the nature of and the author of these changes. Any modified source is bound by this licence and must remain available as open source under the same conditions it was supplied and with this licence at the top.

This software is supplied AS IS without any warranty. In no way shall; Mark Tarver or Lambda Associates be held liable for any damages resulting from the use of this program. The terms of these conditions remain binding unless the individual holds a valid license to use Qi commercially. This license is found in the final page of 'Functional Programming in Qi'. In that event the terms of that license apply to the license holder.

こちらは、本についてくる商用ライセンスです:

License

The following license gives you a personal non-transferable right to produce closed source commercial Qi applications. It is activated by writing your name into the space provided. It remains valid as long as the license remains attached to an authorised copy of 'Functional Programming in Qi'. Note that xeroxed or electronically duplicated copies of this license are not valid. The license is personal to one individual person and is not transferable. I, the undersigned

_____________________________________________________

being the owner of this copy of 'Functional Programming in Qi' understand that I am free to produce commercial applications with the Qi programming system, to distribute them in source or binary form, and to charge monies for them as I see fit and in concordance with the laws of the land subject to the following conditions.

  1. Neither the names of Lambda Associates or

Mark Tarver may be used to endorse or promote products built using Qi software without specific prior written permission from Mark Tarver.

  1. That this commercial license does not

extend to Qi source code itself which must remain free for educational and personal use and in open source whether modified by me or not.

  1. That possession of this license does not

confer on Mark Tarver or Lambda Associates any special contractual obligation towards me.

  1. That in no event shall Mark Tarver OR

Lambda Associates be liable for any direct, indirect, incidental, special, exemplary or consequential damages (including but not limited to procurement of substitute goods or services, loss of use, data, or profits; or business interruption), however caused and on any theory of liability, whether in contract, strict liability or tort (including negligence) arising in any way out of the use of Qi, even if advised of the possibility of such damage.

遅延評価

Haskellはその遅延評価サポートを宣伝していますが、たしかに遅延評価が有効ケースがたまにあります。 CLプログラマは長い間、遅延評価をクロージャを通して管理してきましたが、Qi II は型安全な遅延評価を自由に使える能力を備えています。

プログラマブルな構文の改良

Qi II はユーザーが read-print ルーチンに直接作用する構文糖衣関数 (sugar function)を作る事を可能としています。 read-print ルーチンを使えば独自の構文を開発する事だけでなく、国際化版の Qi を作る事も可能です。 それらの関数は任意の順序で動作させることができ、お互いのレイヤーを被せる事ができます。 ちょうど CL におけるリーダーマクロが行うのと同じような動作をします。

4段可変速コンパイラ Merlin

Merlin コンパイラは Qi で実装された新しいコンパイラです。 0 (最適化なし) から 3 (最速のコード) までの四段階の速度設定が可能となっています。 最速設定の場合にはコードの重複パターンを縮約し、コンパイラへの指示を Lisp コードに挿入し、 遅くて汎用的な判定を高速な型安全な判定に置き替えます(例えば EQUAL を CHAR-EQUAL へ置きかえる、といった具合)。

Common Lisp との統合の改良

Qi とは異なり、Qi II は大文字小文字の区別を除いた標準の CL リードテーブルを維持します。 従って、 ; などの標準的な解釈は維持されます。 , : ; などは Qi のリーダーにはシンボルとして読み込まれるようになっています。 Qi II は「Qi コード中に埋め込まれた CL マクロ呼び出し」をどう扱かうかをユーザーがプログラムできるようにしています。

LispWorks での動作

Qi II は、既存の Qi のプラットフォーム CLisp, SBCL, Allegro, CMUCL に加えて新しく LispWorks でも動作するようになりました。

共通関数の多引数化

Qi II では、バター付きのパンのように一般的な構築子は多引数化されています。 従って (/. X Y X) は (l (l Y X)) の短縮形として許されており、 また、タプルの構築子 (@p 1 2 3) も (@p 1 (@p 2 3)) (例えば <1,2,3> )、 (append [1 2 3] [4 5 6] [7 8 9]), (and true false true), (or true false true) などもすべて合法です。

Prolog との接続の強化

Qi II は Edinburgh 構文 (M レベル構文) もしくは S 式 (S レベル構文) で記述された Prolog プログラムを許しています。 Qi II Prolog はホーン節の tail 部分への関数呼び出しの埋め込みを許しており、また Qi もしくは CL から Prolog を呼び出す prolog? マクロを備えています。

ルールクロージャ

Qi I とは異なり、 Qi II は関数内にシークエントのルールを埋め込むこと許しており、これはクロージャとして評価されます。 ルールクロージャは型チェックされ、かつルールの外側になる変数のレキシカルな束縛を参照することができます。 この機構は計算論理を学ぶ学生が、労せずしてすべての記述の複雑な論理システムを簡単にコード化することを可能にします。 こんなルール

let PTerm/X (replace-by X Term P)
PTerm/X, (all X P) >> Q;
____________________
(all X P) >> Q;

は量子化された仮定が新しい前提として例示化される事を許可します。 このルールは関数へ埋め込む事が可能であり、ちょうど all-left と呼ばれる Qi II の関数と同じ仕事をおこいます。 ルールはシークエントのリストからなる問題に適用されるルール関数としてクロージャに変換されます。

(define all-left
{term --> [sequent] --> [sequent]}
Term S -> ((rule let PTerm/X (replace-by X Term P)
PTerm/X, (all X P) >> Q;
____________________
(all X P) >> Q;) S))

FPQi では、この強力な手法の説明に 100 ページほどをあてています。

依存型の扱いの改良

Qi II は関数内の変数と型定義内の変数の間の依存関係を認識し、簡単に依存性のある型を扱うことができるようなっています。 これによって、ある型へとエンコードされた二つの数値を引数にとり、 二つの数値を足した数値を返すような関数を型システムが解釈できるようになっています。 正しい定義は次の通り:

(datatype num 

if (number? N)   
_____________
N : (num N); 

  M : (num M); N : (num N); 
  _________________________ 
  (+ M N) : (num (M + N));) 

(define add 
  {(num M) --> (num N) --> (num (M + N))} 
   M N -> (+ M N)) 

型安全なクラスシステム

私にとって CLOS はそれほど興味を引くものではなかったため、 'Functional Programming in Qi (second edition)' の中で どのように型安全な多重継承を備たクラスシステムを構築するかに一つの章をあてました。 このクラスシステムは Qi II の一部ではありませんが、自由に利用可能であり、Qi IIの配布物に附属しています。 詳細な説明は FQPi の 12 章でおこなわれており、プログラマ – CLOS と共に働くためにコードを適合させたがっているかもしれない人を含む – が簡単に調整できるようになっています。

完全なドキュメント 'Functional Programming in Qi (second edition)'

FPQi (second edition) はシステム全体を詳細にドキュメント化しており、二つの新しい章と、ルールクロージャアプローチに関連した 100 ページを超える書き直しを含んでいます。 それは最初の、そして現在唯一の言語の設計原理をまとめた最も信頼のおける解説書です。 この本は Qi のコンパイル技術における、いままで未発表だった、あるいは他では得られない題材を含んでいます。 本を買って商用ライセンスを手に入れてください!あるいは、ライセンスを買って本を無料で手に入れると考えて下さい。 ;)

Mark

訳: onjo@lispuser.net

その他記事

Qi 紹介

Lisp との統合

Qi は独自言語ですが、Lisp でもあります。コードは Qi によって Lisp にコンパイルされ、Lisp 処理系によって実行されます。 結果はユーザーから見て透過的です。組込み命令 ps で生成されたコードを確認する事ができます。

(145-) (define add
         X Y -> (+ X Y))
add

(146-) (ps add)

(DEFUN add (V2755 V2756) (+ V2755 V2756))[]

Lisp の関数を呼び出す事もできます。 Qi では大文字の関数名で CL の標準関数にアクセスできます。 Qi は大文字小文字を区別しますので、同名の関数でも大文字小文字の区別に注意してください。 それさえ気をつければ、例えば Lisp で慣れ親しんだ DISASSEMBLE を捨てる必要もありません。

(147-) (DISASSEMBLE add)


Disassembly of function add
2 required arguments
0 optional arguments
No rest parameter
No keyword parameters
4 byte-code instructions:
0     (LOAD&PUSH 2)
1     (LOAD&PUSH 2)
2     (CALLSR 2 55)                       ; +
5     (SKIP&RET 3)
[]

後方の心配がなくなったところで、Qi の機能を紹介しましょう。

パターンマッチ

Qi を使うことによって簡単に享受できる利点としてパターンマッチがあります。 リスト処理において、大量の if/cond/case を省略できます。例を挙げましょう。

ガード節

Qi のパターンマッチには「ガード節」と呼ばれる条件が使えます。 これは分岐する前にパターンを検査して、結果の真偽で分岐を決定できます。

カリー化

(define series
  From To -> ((series* From) To))

(define series*
  X X X -> true
  F T F -> ((series* (1+ F)) T)
  _ _ _ -> false)

組込みのバックトラックサポート

Qi には組込みのバックトラッキングサポートがあります。 例として、先程作成した series 関数をつかい 3, 4, 5 という数列を 探索する処理を書いてみましょう。

入力:  [1, 3, 4, 1, 5, 2, 3, 4, 5]
探索したい数列: 3, 4, 5

入力を左から右に辿りつつ、処理を勧めていきます。 次のような処理を実施したいとします。

step1:  1
step2:  3 (3)
step2-1:  4 (3,4)
step2-2:  1 -> fail (ここでバックトラックする!)
step3:  4
step4:  5
step5:  2
step6-1:  3 (3)
step6-2:  4 (3,4)
step6-3:  5 (3,4,5) -> true!!

このような処理を Qi では非常にシンプルに書けるようになっています。 組込みオペレータ <- を使う事で、探索が失敗した場合に復帰できるようになっているのです。

(define find-series
  Series Lst -> (find-series* Series Series Lst))

(define find-series*
  true _ _ -> true
  false _ _ -> false
  Series Orig [X | XS] <- (fail-if (= false) (find-series* (Series X) Orig XS))
  Series Orig [X | XS] -> (find-series* Orig Orig XS)
  _ _ _ -> false)

この機能の詳細については Function Programming in Qi の Chapter. 5 で説明されています。

型チェック