#:g1: frontpage

 

リストを重複なしで並び順は保持したままマージする

Posted 2015-08-29 09:22:40 GMT

 パスの設定をするのに、こんなコードを見掛けました。

(defparameter *foo-path* (list "/a" "/a/b" "/a/b/c"))

(mapcar (lambda (x) (pushnew x *foo-path* :test #'string=)) '("/a" "/a/b" "/a/b/c/d")) ;=> (("/a/b/c/d" "/a" "/a/b" "/a/b/c") ("/a/b/c/d" "/a" "/a/b" "/a/b/c") ; ("/a/b/c/d" "/a" "/a/b" "/a/b/c"))

とりあえず、副作用が目的なので、mapcarよりはdolist(かmapc)で書くだろうということで、

(dolist (x '("/a" "/a/b" "/a/b/c/d") *foo-path*)
  (pushnew x *foo-path* :test #'string=))
;=>  ("/a/b/c/d" "/a" "/a/b" "/a/b/c")

(
※註: pushすると順番が逆転することになるので正しくは、

(dolist (x (reverse '("/a" "/a/b" "/a/b/c/d")) *foo-path*)
  (pushnew x *foo-path* :test #'string=))
;=>  ("/a/b/c/d" "/a" "/a/b" "/a/b/c")

です。もしくは最初から元リストを逆様に書いておくか。
)

こんな感じの方がすっきりするかなと思うのですが、このパタンってもっと上手く書けないものなのかなと考えてみました。

remove-duplicatesを使ってみた場合

(setq *foo-path*
      (remove-duplicates (list* "/a" "/a/b" "/a/b/c/d" *foo-path*)
                         :test #'string=))
;=>  ("/a/b/c/d" "/a" "/a/b" "/a/b/c")

どうもいまいちですね。

delete-duplicatesfを定義してみた場合

setq[*foo-path* ...]しているのが、すっきりしない原因ではないかということで、setfマクロを定義してみました。

(define-modify-macro delete-duplicatesf (&rest args) delete-duplicates)

(let ((*foo-path* (list* "/a" "/a/b" "/a/b/c/d" *foo-path*))) (delete-duplicatesf *foo-path* :test #'string=)) ;=> ("/a/b/c/d" "/a" "/a/b" "/a/b/c")

これだと一度変数に入れないといけないですね。いまいち。

set-differenceを使ってみた場合

こんな感じでしょうか。

(let ((x (set-difference '("/a" "/a/b" "/a/b/c/d") *foo-path* :test #'string=)))
  (append x *foo-path*))
;=>  ("/a/b/c/d" "/a" "/a/b" "/a/b/c")

どうもいまいちですね。

TAOの自己代入式で書いてみる

TAOには、自己代入式という便利な記法があるのですが、

これだと、こんな感じに書けます。

(!!delete-duplicates (list* "/a" "/a/b" "/a/b/c/d" !*foo-path*)
                     :test #'string=)
;=>  ("/a/b/c/d" "/a" "/a/b" "/a/b/c")

!!が付いた式は、式の結果を!が示した場所に代入するという構文です。

とはいえ、delete-duplicatesを使うというのはパスのリストを作るという意図からすると、ちょっと分かり難いですね。

まとめ

 TAOの自己代入式は割合に良い感じですが、結局dolist & pushnew が適当な落とし所なのか所かなという感じです。
何か良い書法はあるのでしょうか。


HTML generated by 3bmd in LispWorks 7.0.0

LISP技術動向に関する調査報告書 [平成元年]を読む その3

Posted 2015-08-22 15:22:18 GMT

 今回は、オブジェクト指向システムの調査から眺めます。

IV. オブジェクト指向システムの調査

オブジェクトサブグループの本年度の調査は、

  1. CLOS 3章の翻訳
  2. AAAI CLOSワークショップの報告

が主な所です。

CLOS 3章の翻訳 (X3J13 89-003 Dec. 1988)

CLOS 3章の翻訳は、X3J13 89-003 Dec. 1988の翻訳ということなのですが、これがネットを探しても全然見付かりません。
大体の所は、後のAMOPの5/6章の内容と同じなのですが、ensure-class-using-classensure-generic-function-using-classが別名のクラスを受け取った時にはchange-classしたり(ensure-class-using-classではforward-referenced-classでの挙動に残っているようですが…)、知らない関数があったりと微妙な違いはあります。

参考

CLOSワークショップの概要

もう一つは、1988-10-03/04にPARCで開催された、AAAI CLOS Workshopの報告です。
参加者は、75名で、日本人は5名程だったようです。

どうも出だしが、井田先生のbitの記事とそのまま同じようです。

  • bit Vol.21 No.2 1989: AAAI CLOSワークショップ | 井田昌之

LucidのJon L氏のエピソードがなかなか興味深いので引用してみます。

バンケットのエピソードで衝撃的であったのは、Jon L Whiteが非常に真面目な調子でC言語にLispはとって代わられ、Lispは死ぬといったことである。
これに大して同じテーブルにあって非常にショックを受ける者、怒る者、また、Lucidの経済的な事情からくる発言と皮肉る者があった。

これに対しては、「全般的にはなんでもLispでやるのだというのと同じく極端な考えで受け入れられないだろうという空気が支配的」だったそうです。

ちなみに、この後Lucidは、Jonl氏の予言的が当ってしまったのか何なのか、C++の開発環境である Energize 開発の方向に舵を切り沈没して行きます。

後のAAAI 米国視察団調査報告では、自己資本のFranzの話などもちらっと出てきますが、外部資本に振り回されるLucidというのがあったのでしょうか。
自分は、読んでないので詳細は知りませんが、Gabriel氏の「Patterns of Software: Tales from the Software Community」にでもその辺りは書いてあるのかも。

閑話休題、さて、概要に続いてプロシーディングの要約が掲載されています。

The Importance of being Meta / Kiczales

CLOSについての話ですが、Lispの提供するもっとも重要な機能は、問題に対して特殊化された言語をLispを用いて構築できることで、それは、DSLでもあるし言語拡張でもあるとし、これをオブジェクト指向システムにあてはめてみた場合、FlavorsとLoopsはこの機能を持たないことを挙げ、CLOSはこれを持つことを説明しています。

例えば、Flavors/LOOPSでは、標準的な実行ルールを特殊化したものに従うようなオブジェクト指向言語のプログラムの要素を定義するメカニズムは容易されていない、インスタンス変数へのアクセスのルールが特殊化されたようなクラスを定義してそのクラスを他の標準的なクラスと共に用いることはできない etc

CLOSはCommon Lispの拡張であり、Common Lisp自身をオブジェクト指向言語にするものであると説明。

MOPを、従来のLispが持つEVAL/マクロとその拡張手法で説明すると、Metaobjectを操作することは、EVALに相当し、Metaobjectの特殊化は、マクロでの拡張に相当する、としています。

他、ネットで論文が拾えたり拾えなかったりしますが、下記のようなものの概要が説明されています。

  • Translatin of kee object oriented programs into clos-xt
  • MICE: a modular intelligent constraint engine
  • TICLOS: a high performance implementation of clos for the explorer family
  • Some remarks on the common lisp object system
  • A-DISPATCH algorithm for CLOS Method Lookup and its Application to CAM-based Accelerator
  • Design for High Performance Dynamic Generic Dispatch In The Common Lisp Object System
  • Knowledge Representation Extensions to CLOS
  • Solo: a prtable clos window interface
  • Silica: a window system kernel
  • Description Language And Dispatch Mechanisms / John R. Rose

TICLOSの話などは、CLOS Perspectiveに掲載されているものと同じかなと思います。

V. ヒアリング調査・COMMON LISPシンポジウム報告

ヒアリング調査として隔月でLispベンダーからの報告会のまとめと、COMMON LISPシンポジウム報告がまとめられています。

ヒアリング調査

1. 1988-05-16 日本Symbolics / Ivoryの紹介など

当時新しく開発されたVLSIチップであるIvoryを搭載したMac Ivoryや、新しいワークステーションの紹介が主だったようです。
Mac Ivoryは当時150万円(Mac IIは抜き)だった様子。
Macも含めると、200万円コースでしょうか。

新しいワークステーションは、恐らく、XL1200かと思いますが、これは、1300万円とのこと。
カラーディスプレイを持つ3630は、980万円〜1200万円とのこと。

庶民には手が出ませんね。

2 1988-07-12 日本テキサス・インスツルメンツ / Micro Explorerの紹介など

テキサス・インスツルメンツも、Micro ExplorerというMac IIのNuBusに挿せるタイプのカードを販売していました。
デリバリー(ランタイム的なもの)と、開発向けがあり、デリバリーは348万円、開発向け(エディタ/コンパイラあり)は、530万円だったようです。 Micro Explorerは、TIと Appleの初の共同レーベルとのこと。
仕組みとしては、LispとMacはRPCで通信します。
性能は、LispマシンのExplorer IIの60%性能程度だったとのこと。

3. 1988-09-09 NEC / Lime の紹介

NECは、第五世代プロジェクトでPrologマシンの CHI-II というのを作っていましたが、これをLispに応用したもののようです。

UtiLispを高速に実行するためのものだったようですが、日本のLispマシンは割とハードウェアに力を入れていて、米国のように開発環境が充実したのは、TAO/ELIS位だったように思われます。

4. 1988-09-09 CSK / Lucid Common Lisp 3.0の紹介

当時最新だったLucid Common Lisp 3.0が紹介されています。

  • コンパイラのモードに、プロダクションモードと開発モードがあること
  • ウィンドウツールキット
  • オブジェクト指向システム: Flavors、PCL、CLOSにも対応予定
  • エディタ: Lisp処理系に多重接続可能なEmacs風のエディタ(Helix)
  • マルチタスキング: スタックグループ
  • FFI
  • EGC(Ephemeral GC)
  • エラーハンドラ(pitman error hander採用)
  • その他、Advanced User's Guide、Wizards Documentについて

将来的なものとして、

  • Lumen (defsystemのようなもの)
  • distill!(アプリケーション出荷においてのツリーシェーカー等のユーティリティ)

があったようです。

5. 1988-11-08 CLXとCLUE

これについては、川辺治之氏のbit Vol.21 No.7 1989: Common Lisp最前線(2)─CLUE─Common Lispユーザ・インタフェース環境 に詳しく書かれているかなと思いました。
CLUEは、CLXと一緒に配布されていたウィンドウツールキットで、当時TIが力を入れていたようです。

6. 1988-11-08 リファレンスカウント方式によるGCについて

XeroxのLispマシンでのリファレンスカウント方式によるGCについて詳細が説明されたようです。

付録 AAAI 米国視察団調査報告

1988-08-17/29まで米国調査団を派遣し、AAAI '88に参加したり、Lispベンダーを訪問したり、Lisp界のキーパースンと面談したりの報告です。
主に井田先生の報告のようですが、bitにでも掲載されていそうな雰囲気です。
そんなにLispっぽくはないような。まあ付録なんですが。

まとめ

 1988/9年の2年に渡って出版されたLISP技術動向に関する調査報告書ですが、なかなか面白いものでした。
これらの知見が2000年代位まで維持されていたらLispに対するイメージもちょっとは違ったものになっていたかもしれないなあと思ったりはします。


HTML generated by 3bmd in SBCL 1.2.14

LISP技術動向に関する調査報告書 [平成元年]を読む その2

Posted 2015-08-21 15:56:30 GMT

 前回に続き、LISP技術動向に関する調査報告書 [平成元年]を眺めて行きます。

今回は、III. 応用技術動向WGの活動 からです。

III. 応用技術動向WGの活動

応用技術動向WGの本年度の活動報告は、Common LispとCの記述性の比較が主なところだったようです。
前年度のアンケートの結果として、Lispは記述性が高い、書き易いというものだったのが本当なのか検証してみよう、というもの。

以下、具体的な比較となりますが、報告の内容は、

  • 1989年: bit Vol.21 No.8 Common Lisp最前線(3) ─Lisp対C / 湯浦克彦
  • 1990年: Interface 1990 2月号 特集: リスト処理の応用とLispの技法: Lispによる開発の現状 / 湯浦克彦

にまとめられた記事の大元という感じで、これらの記事を読めば大体分かります。
むしろまとめられた記事の方が、湯浦氏の個人的意見が反映されていて面白いような気もします。

LISP - C 記述性比較実験の概要

  1. Common LispをCに書き直して比較
  2. 中立のFortran等のプログラムをCommon Lisp、Cに書き直して比較
  3. Unixのシステムツールを書いてCommon LispとCで書いて比較

という感じです。
数グループのテストがありますが、Cの経験はちょっとあるけれど、Lispの経験は0の人達だったり、Lispの経験はあるけれど、Cは書いたことがなかったり、プログラミングの経験はあまりない人達に研修をうけてもらって書いてもらう、等々、割合に変化に富んでいるようです。

例題による実験の結果と考察

まずは、Gabrielベンチで有名なお題をCに書き直して比較というものです。

Common LispをCへ移植

  1. boyer
  2. destructive, traverse, derivative
  3. dderiv
  4. div2
  5. fft, puzzle triangle

大体、Common Lispの元のプログラムと比べると、3〜10倍の長さになっています。
結論としては、Cで記号処理をやろうとすると、lispを実装するのと大差なくなってしまうという話で、なんだかんだでCでも書けるのでCは柔軟だ、でも面倒というところ。

次に、Winston著の LISP 2版が元ネタで、プロトタイプ用言語としての比較です。

縦型木探索プログラム

LISPで書くと自然と拡張性があるのですが、Cのバージョンだと問題に対して具体的なので拡張性はそれ程でもなく、C→Lispの移植だと、そのLisp版は多分拡張性がないものになってくるんじゃないかというようなことが感想として書いてあります。

ファイル比較プログラム(diff)

Pascalで書いたものをUtiLispに直して、更にCommon Lispに移植したものと、PascalからCに移植し、どうなるかを比較してみたものです。
Pascallで168行、UtiLisp 90行、CL 76行、C 168行ということですが、元のプログラムがリスト操作のようなことをしているのでLispだと簡単に書けたようです。

πの計算プログラム

マチンの公式を使って、小数部を4桁ずつの整数の配列で出力するものです。
Fortranのプログラム(103行)をCommon Lisp、Cへ移植したもの。
Common Lispにはbignumがありますが、あえて利用しなかった場合、115行、使うと28行、Cは125行という結果でした。

システム機能プログラム

lisp向きではないものをということで選ばれたテーマのようです。

  1. string-to-num (文字列“1234”を5-12進法で読む)
  2. putd (数を文字列として10進表示)
  3. print-env(環境変数を表示)
  4. gettar(tarをuntarする)

Common LispもCも大体似たようなものになったようです。

漢字コード変換プログラム

JISをSJISに変換するというもの。

これも、Common LispもCも大体似たようなものになったようです。

実験のまとめ

まとめとして、記述量はCommon Lispになると大抵減るが、Cの3割は宣言系のもので、これが不要のCommon Lispは有利という結論のようです。

また、見やすさ、書きやすさについては、Cも柔軟なのでライブラリを揃えればCommon Lispでやるようなことも書けるだろう、という結論。
書きやすさについては、配列の処理についてはCの方が有利に思われるとのことですが、Lispは宣言不要な所が良いということです。

開発についての感想としては、Lispは、関数単位で実行できるのが良い所で、Cだと実行やテストに治具の作成が必要になったりして面倒。
しかし、逆にCは速く、開発環境なしで直接実行できるので、起動が速くメモリが少ない環境では有利だろう、ということです。

今後の課題

今後の課題として、

  1. 典型的なlispプログラミングの紹介
  2. Lisp固有機能をより生かしたプログラム例の紹介
  3. LispおよびCの併用法と実例の紹介
  4. 遅くないlispプログラムとそのノウハウの紹介

辺りが挙げられています。

湯浦氏の記事にも具体例が紹介されていますが、Common Lispでのデータ型の選択や、型宣言等でのチューニングが主なところのようです。
こういうチューニングができるということや、ノウハウを知らないからLispは遅いと思われるのだ、という話みたいですが、どうも25年前も現状もそんなに変わらない気がします。

まとめ

Lisp vs Cというのも、かなり昔から真面目に行われていたんだなあという感想ですが、現在は、25年前の状況から大して進んでないというか、むしろLispの迷信めいた話が復活している所をみると退化しちゃってる感さえあります。
一体何が原因なのでしょう。
なんにしろ、こういう比較も時代に合せてアップデートして広められて行く必要があるのかなと思ったりです。


HTML generated by 3bmd in SBCL 1.2.14

LISP技術動向に関する調査報告書 [平成元年]を読む その1

Posted 2015-08-19 14:55:23 GMT

 先日、二回に渡りLISP技術動向に関する調査報告書 [昭和63年] を眺めてみましたが、平成元年版も閲覧できたので内容を眺めてみたいと思います。

平成元年版(以下JEIDA-1989)も、昭和63年版(以下、JEIDA-1988)と同じような構成ですが、ページ数が293から188へと減っています。
とはいえ、翻訳が減り、活動や調査報告の内容は増えているので、ある意味こちらの方が中身は濃いようです。

  • I. 調査の概要
  • II. 技術動向WGの活動
  • III. 応用技術動向WGの活動
  • IV. オブジェクト指向システムの調査
  • V. ヒアリング調査・COMMON LISPシンポジウム報告
  • 付録 AAAI 米国視察団調査報告

I. 調査の概要

 この調査書を作成した、JEIDA Common Lisp Committeeの概要等の説明です。前年度と同じく、23社 48名が参加とのこと。
隔月一回の定例委員会を開いていたのと、1988-06-06には、「Common Lisp シンポジウム」を開催し、有償で95名の参加者があったそうです。
当時fj.lang.lispに流れたメールによると、

        Common Lispシンポジューム

電子協Lisp技術専門委員会の活動とCommon Lispの最新 の動きを解説する。

主催 日本電子工業振興協会 日時 昭和63年6月6日(月)午前9時30分~午後4時30分 会場 機械振興会館 地下3階 研修2号室

定員 130名 聴講料 会員会社 4000円  一般 6000円 テキスト 「LISP技術動向に関する調査報告書」 会員 4000円  一般 6000円 「Common Lispシンポジュームプロシーディング」 1000円 (「LISP技術動向に関する調査報告書」 を買った人は無料) プログラム 9:30~10:30 Common Lisp概要 井田昌之 青山学院大学 10:30~11:30 オブジェクト指向機能CLOSについて 大久保清貴 (株)PFU 11:30~12:30 例外処理機能の標準案について 加藤英樹 (株)富士通研究所 12:30~13:30 昼食 13:30~14:30 Loopマクロの標準案について 川合進  日本DEC(株) 14:30~15:30 日本語処理のための機能拡張案について 元吉文男 電総研 15:30~16:30 アンケートによるLisp言語の現状について 湯浦克彦 (株)日立製作所

のような感じだったようです。
このシンポジウムでのアンケート結果が今回の調査書に掲載されています。

また、1988-08-17/08-29で米国調査団を派遣し、AAAI '88への参加、Lisp企業の訪問、米国Lispのキーパースンとの面談等が実施されたとのこと。

幹事会は、富士通、日立、日本電気、NTT、PFU、東芝、日本ユニシス、富士ゼロックス、日本DEC、からとのことです。

II. 技術動向WGの活動

技術動向WGの今回の報告は、処理系の日本語化対応についてて、具体的には、文字列、シンボルで日本語が扱えるかどうか、という所です。

UTF-8の採用が定番になる以前では(10年位前)、char-code-limitが65536以上か以下かで日本語対応をざっくり推し量るようなこともありましたが、どうも1989年は、それよりちょっと進んでいたようなので、日本語対応は、処理系がUTF-8化するまで少し退化していたような気もします。

  1. Lucid Common Lisp
  2. DG Common Lisp
  3. 日本語VAX LISP 2.2
  4. TAO
  5. VOS3 LISP、HI-UX LISP
  6. NCL (日本語Common Lisp環境) (TI Explorer)
  7. Xerox Common Lisp(Lyric)
  8. 富士通 LISP V10

文字のエンコーディングは、SJIS、EUCが多いようですが、日立のVOS3 LISPなどはメインフレームの処理系だけに、EBCDICだったり、Unixプラットフォーム以外は独自の体系が多いようです。
日本企業の取り組みとしては、日本語が扱えないというのは論外に近いので、そこそこ対応していたんだなという感じではあります。

日本語の文字列のlengthがどうなるか、等々、割合最近まであった問題ですが、あまり細々書いても有益でなさそうなので省きます。

まとめ

Common Lispシンポジウムの話は全然耳にしたことがないのですが、95名の参加者となると結構大きな規模だったようです。
今からすると、Common Lispにもこんな熱い時代もあったのかという所ですね。

次回は、III. 応用技術動向WGの活動 から続きます。


HTML generated by 3bmd in SBCL 1.2.14

マクロの複雑性に起因するエラーの処理

Posted 2015-08-15 12:28:03 GMT

 以前、CLが採用しているような古典マクロだと、複雑になった場合、抽象化のほつれによりデバッグが困難になる、というような話を耳にしたのですが、その時の自分が最初に考えたのは、LOOPのことでした。
割合に複雑なマクロですが、LOOPが原因でデバッグ時に悩んだ記憶もありません。

確かに古典マクロのシステムは古臭く、改善点は沢山あると思いますが、実際使ってる立場からすると、問題の指摘も頭でっかちな理論上だけの話に感じ、もやもやしていました。
もちろん、運用でどうにかするより、理論上美しくユーザーの意図から乖離することなく使い易いものが進化すべき道だとは思っています。

さて、そんなLOOPですが、先日X3J13の資料を眺めた際にLOOPがマクロに起因するエラーについても結構細かく規定しているのをみつけました。

ユーザーが頓珍漢なエラーメッセージに困らないようにという配慮な訳ですが、ある程度複雑なマクロの場合、こういう対処が必須かなとは思います。
それなりに配慮があったので困らなかったのかもしれません。とはいえ、ここまで考えたマクロというのは、そんなに無いかもしれませんが。

まとめ

 古典マクロもただ口を開けてゴミのようなエラーを垂れ流していた訳ではないということが云いたかった訳です。
とはいえ、新進気鋭のマクロシステムのエラーメッセージに、なるほどこれは適切で素晴らしいと感嘆した経験もないんですが。
まあ、システムがどうのというより、ユーザビリティは、常に考えるべきことではありますね。


HTML generated by 3bmd in LispWorks 7.0.0

LispWorks 7購入への道(4) ─ 試用期間の終わりとアンケート回答

Posted 2015-08-15 10:58:10 GMT

 LispWorks購入への道としてつらつらと試用版の体験記的なものを書いてみていましたが、結局記事は3つしか書きませんでした。
もっと書こうと思っていたのですが…。

試用期間の終わりとアンケート

試用版の終了間近になるとLispWorksからアンケートが送られてきます。
内容は、

  1. LispWorksの良かった所は?
  2. 良くなかった所は? 改善点は?
  3. 追加して欲しい機能は?
  4. 購入しようと思いますか? それはいつ位に?

という所です。

自分の回答は、以下のような感じです。

LispWorksの良かった所は?

とても良い処理系/IDEだと思いました。

良くなかった所は? 改善点は?

  • Linuxだと uim-xim の入力がたまにおかしい。LispWorks 6はこんなことはなかった。
  • 新しいLispWorks 7のファイルエンコーディングの検出の仕組みは、たまに検出に失敗する。
    明示的に、-*- coding: utf-8 -*-にすればOK。しかし、これは面倒。
    また、LispWorks 6までの

(defun utf-8-file-encoding (pathname ef-spec buffer length)
  (declare (ignore pathname buffer length))
  (system:merge-ef-specs ef-spec :utf-8))

(setq system:*file-encoding-detection-algorithm* (substitute 'utf-8-file-encoding 'system:locale-file-encoding system:*file-encoding-detection-algorithm*))

のような対処もデコードエラーになる。(※なお詳しくは追ってません。)

  • シェルコンソールが文字化けする。(UTF-8には対応してないらしい。もしかして設定がある?)
  • おまけで付いてくるエディタのソースが最新版でない。それとも私に何か見落しがある?
    添付のソースと実物は結構違うみたいなので、参考にするには微妙。

追加して欲しい機能は?

さらなる国際化

購入しようと思いますか? それはいつ位に?

購入の方向で考えています。今月中位に。

まとめ

LispWorks 7 は激烈に欲しい!という訳ではありませんが、最近、無職期間が終わって働き始めたので買おうかなと思っています。
CAPIは良い感じで、簡単にGUIツールが作れるので、この点を重視する人にはとてもお勧めです。


HTML generated by 3bmd in LispWorks 7.0.0

グリーンスパンの第10法則に1-9番目は存在しない

Posted 2015-08-13 12:45:52 GMT

Greenspun's tenth rule of programming

Any sufficiently complicated C or Fortran program contains an ad hoc,
   informally-specified, bug-ridden, slow implementation of half of Common Lisp.

 「グリーンスパンの第10法則」というけれど、適当に法則っぽく憶えやすい番号をふってみただけなので、第1-9法則は存在しないらしい。

Wikipediaにも載る程有名になっていて独り歩きしてしまっている感もあり。

上記のネタばらしの記事にもあるけれど、グリーンスパン氏の履歴を眺めると、大規模なソフトウェア開発に積極的に携わってきたらしく、そんな中で出てきた言葉らしい。


HTML generated by 3bmd in LispWorks 7.0.0

locative活用 その1

Posted 2015-08-12 13:09:40 GMT

 locativeは、ポインタのようなもので、C++の参照に近いものです。
Lisp machine Lispのような専用機上の処理系で導入されましたが、汎用機もターゲットにしたCommon Lispでは取り入れられませんでした。
そんなlocativeの活用事例を発見する度に適当に何か書いてみようかなと思います。

リストに要素を追加していくパタン

 リストに要素を追加していくパタンでは、要素をpushしていてnreverseというのが良く知られていますが、リストの先頭を記憶しておき、末尾のセルを押えつつ更新していくという方法があります。
やや複雑な為か、LISPの入門書にpush+nreverseは解説のあっても、この方法の解説はまずありませんが、LOOP:COLLECT節のようなものの実装は、こっちの方が大抵速いので、まず間違いなくこの方式で書かれています。 というか、寧ろ、push+nreverseが処理系内部で使われていることはあまりありません。
INTERLISPには、リストの末尾を押えておくtconcという関数があり、この方式もtconcと呼ばれたりもしています。
まあ、破壊的変更の技法なので、今後廃れていく技法ではあるでしょう。

具体的にはこんな風に書きます。

(do* ((x '(0 1 2 3 4) (cdr x))
      (ans (list nil))
      (tem ans))
     ((endp x) (cdr ans))
  (setf (cdr tem)
        (setq tem (list (* 2 (car x))))))
;=> (0 2 4 6 8)

(setf (cdr tem) (setq tem (list ...)))の箇所は、Common Lispの評価規則等が前提になっていて技巧的です。
暇潰しにでもこれで機能する理屈を考えてみてください。

locfで書く

上記が、locfを使うと、こんな感じに書けます。

(do* ((x '(0 1 2 3 4) (cdr x))
      (ans (list))
      (ansloc (locf ans) (cdr ansloc)))
     ((endp x) ans)
  (setf (cdr ansloc) 
        (list (* 2 (car x)))))
;=> (0 2 4 6 8)

Common Lispの感覚だと、(list)NILなのでは?と思う所ですが、Lisp machine Lispだと色々あって、NILのlocativeは要素0のリストのlocativeになるので問題なしです。
つまりNILと書いてしまってもOKですが、あえてこう書いてみました。
どうも当り前のことを書いている気になりますが、NILのlocativeは固定ではない、ということです。

そして、このリストのlocativeをlocfでanslocに保存します。
locativeのcdrかcarは、内容のリストそのものになるので、cdrの内容を差し替えて、cdrを送って行けばOKです。
最後は、(cdr ans)などとせずに、ansそのままを返します。

まとめ

locfのお蔭で、リスト全体を摑む方法がある、というだけで、nthcdrでいうと、-1の位置が参照できるようなものなのですが、こんな使い方もあったのか、と思ったので書いてみました。


HTML generated by 3bmd in LispWorks 7.0.0

LISP技術動向に関する調査報告書 [昭和63年]を読む その2

Posted 2015-08-12 07:51:37 GMT

前回の落穂拾いです。 「IV. オブジェクト指向システムの調査」と、「V. LOOPマクロの拡張案について(概要・背景)」について、翻訳元の文献の詳細が不明だったのですが、再度詳しく確認してみました。

IV. オブジェクト指向システムの調査

内容を X3J13 88-002Rと比較しつつ眺めてみると、defclassに、:constructorや、:accessor-prefixなどというオプションがあったりするのと、defgeneric-optionsというもので総称関数の設定をしている所が大きく違います。
そのものズバリな文献がないかとウェブを検索してみましたが、どうも該当する資料はない様子。
しかし、:accessor-prefixなどの記述がある文献としては、The Common Lisp Object System: An Overviewがありました。
これの引用文献に、X3J13 87-002 という文献が登場してくるので、報告書では、X3J13 88-002Rの前のX3J13 87-002 を翻訳したのではないかなと想像しています。

ちなみに、この中でdefclass:accessor-prefixは、こんな感じに使えます。

(defclass x-y-position (position)
  ((x :initform 0)
   (y :initform 0))
  (:accessor-prefix position-))

どうやら、defstruct:conc-nameみたいなものみたいです。

X3J13 87-002 については、saildart.org に残骸らしきものがあるので、頑張れば再構成できるのかも。

ちょっとしんどそうですが。

V. LOOPマクロの拡張案について(概要・背景)

LOOPマクロの拡張案について(概要・背景) の翻訳元文献ですが、こちらはウェブを探してみた所、意外にもLiquid CLのマニュアルがX3J13の文献をそのまま使っているらしいことが判明しました。
結構古い文献なので、Liquid CLの前のLucid CL時代から引き継いできたものかもしれません。

そうなると、当初は、Lisp machine LispのLOOPをそのまま入れようとしていたのかなと思います。
拡張案となっていますが、CLtL1では議論で揉めたので単純ループとして導入されたものであって、LOOP自体は、最初からこの文献で述べられている拡張機能は全部持っています。

まとめ

X3J13 87-002 が見付からないのが、ちょっと残念ですが、大体のものはウェブで見付けられるというのは素晴らしい時代ですね。

LISP技術動向に関する調査報告書 [平成元年] も図書館にリクエストしてみましたので、届いたらこちらも眺めてみようと思っています。


HTML generated by 3bmd in LispWorks 7.0.0

LISP技術動向に関する調査報告書 [昭和63年]を読む

Posted 2015-08-08 18:01:14 GMT

 以前、LISP関係の文献を漁っていたら、LISP技術動向に関する調査報告書 (昭和63年) / 日本電子工業振興協会 編というのを発見しました。
当時は、日本電子工業振興協会(JEIDA)ですが、現在の電子情報技術産業協会(JEITA)にあたります。

LISP技術専門委員会というものがあったということは知っていましたが、報告書が存在することは知りませんでした。

どうやら入手困難な資料なので、図書館の図書館間貸出しサービスを利用して、閲覧することにしてみましたが、結局、国会図書館にしか所蔵されていないようです。

この報告書は、5章から成り、内容は下記の通りです。

  • I. 調査の概要
  • II. エラー処理とschemeの技術調査 (技術動向WG)
  • III. LISP応用技術WGの活動 (LISP応用技術WG)
  • IV. オブジェクト指向システムの調査 (オブジェクトSG)
  • V. LOOPマクロの拡張案について(概要・背景)

以下、章ごとに詳しく眺めてみます。

I. 調査の概要

LISP技術専門委員会について

LISP技術専門委員会は、1985年から始まって、1987年には、20社から43名が委員として活動していたようです。
幹事として参加していた会社は、

  • 富士通
  • 日立製作所
  • 日本電気
  • 日本電信電話(現NTT)
  • PFU
  • 東芝
  • 電子技術総合技究所
  • 日本ユニバック
  • 富士ゼロックス
  • 日本DEC

という所ですが、結構有名所が集まっていたようです。

LISP技術専門委員会は、さらにワーキンググループに分かれていて、

  • LISP技術動向WG
  • LISP応用技術WG
  • オブジェクトSG(subgroup)

とあったようです。
海外向の呼称は、JEIDA Common Lisp Committee ということだったようですが、LISP全般を扱っている所からすると若干不思議ではありますが、発足のきっかけがCommon Lispだったというのはあるかもしれません。

1984年から1986年までのLISP技術専門委員会の経緯と活動内容ですが、

  • 1984年

    • 予備ミーティング Lispの需要の高まりにより委員会の必要性を確認
  • 1985年

    • Common Lispの理解
    • 処理系作成方法について
    • 既存処理系の調査
    • 米国Common Lispコミュニティとの連絡、交流(海外訪問調査)
    • Common Lispの応用調査(アンケートの実施)
    • WG: サブセットWG、オブジェクトWG
  • 1986年 (マイコン技術専門委員会傘下に)

    • Common Lisp/CORE
    • Xerox Common Lispに注目しアルゴリズムの検討、オブジェクト機能の応用例、応用方法の検討
    • Common Lispに対する漢字機能拡張に関する具体的検討
    • Common Lisp電子メール討論の要旨翻訳
    • WG: サブセットWG、オブジェクトWG、漢字WG、Bulletin Board WG

と書いてあります。
海外のCommon Lisp文献で出てくる所だと、Common Lispのサブセットの提案と、多言語対応のためのexternal-format辺りがJEIDA発のようです。
Bulletin Board WGというのは、井田昌之先生が報告をまとめたりしていますが、メーリングリストを中心とした仕様策定の追い掛けだと思われます。

参考:

II. エラー処理とschemeの技術調査 (技術動向WG)

エラー処理とschemeの技術調査の章は、Kent PitmanのExceptional Situations In Lisp(1987)の翻訳と、Schemeの調査としてR3RS仕様の全訳が掲載されています。

例外処理技術の動向

Kent Pitman(kmp)氏のExceptional Situations In Lispはウェブでも公開されているのですが、この本に収録のX3J13の1987年版というのが探しても見当たりません。

Exceptional Situations In Lispは、1990年版と、1985年版が見付かりますが、収録のものは大まかな線では同一ですが、コード例なども多く、また仕様策定の議論についての愚痴のようなものも書いてあり、なかなか面白いものになっています。

現行のCommon Lispのコンディションシステムと大きく違うのは、condition-case等、Zetalisp系の構文の影響を残している所と、大まかには、signalerと、handlerと、proceed optionという構成になっている所です。
これが後にhandler系とrestart系に整理された様子。

kmp氏の愚痴の内容ですが、コンディションのメッセージ出力の関数にprint-と付けたら、print系の変数(*print-case*等)に影響されないのにprint-っておかしい等々の文句が出たことがあったので、report-にして予想される類似の議論を予め回避した、という感じのものですが、report-ってなんじゃい、という話になったようです。

Schemeの調査

Schemeの調査と題されていますが、丸ごとR3RSの翻訳の翻訳です。
R7RSからR4RSはウェブで翻訳が入手できるようですが、R3RSも翻訳はあったんだなあという感じです。

参照:

III. LISP応用技術WGの活動 (LISP応用技術WG)

 この報告書で一番興味深いというか、歴史的価値が高そうなところです。
当時のLispユーザーにアンケートを実施した結果報告ですが、日本の1988年の状況はインターネット経由では殆ど入手できないので非常に貴重だと思います。

まず、前年度(1986年) に実施したアンケートの説明があります。

昭和62年度(1986年)は、

  1. 応用プログラムのヒアリング
  2. Common Lisp普及のための諸機能の議論
  3. 他言語との比較(生産性、性能)
  4. lispに関するアンケートの実施

の項目のアンケートを実施したとのこと。

1987年は、これを踏まえて、

  1. 開発プログラムおよび開発チームの規模
  2. プロトタイピング用言語としての利用状況
  3. 他言語との比較および併用法
  4. プログラミング環境の現状と今後の期待

を実施したそうです。
135グループに実施し、128回答があったとのこと。

アンケートでのLISPユーザーの内訳

グループの内訳ですが、

グループの内訳

  • 大学 10%
  • 国立研究所 2.3%
  • 企業RD 25.8%
  • 企業dev 39.1%
  • 無記名 22.8%

とのことです。前回実施は、大学がかなり多かった所から企業での利用が多くなったということです。

LISPの使用経験

LISPの使用経験は、十分にあるが、64回答、あるが61回答、ないが2回答とのことで、アンケートはLISP経験者に対して実施されたことが分かる、と解説されています。

LISPの使用動機

LISPの使用動機ですが、 LISPの使用動機

  • 仕事 86.9%
  • 趣味 11%

とのことで、ほとんど仕事で触っているとの回答だったようです。

担当職務

仕事の内容は、

担当職務

  • アプリケーション開発: 73
  • 処理系開発: 36
  • Lispハードウェア開発: 4
  • AIツール開発: 39
  • Lispツール販売: 5

というところでアプリ開発が多かったようです。
Lispハードウェア開発って、どこだか丸わかりな気もしますが(NTT)

利用分野

利用分野は、当時流行のエキスパートシステム開発が断トツのようです。
解説によると、前回調査に比べてエキスパートシステムの伸び具合が目覚しいとのこと。

利用分野

  • エキスパートシステム: 59
  • AIロボット: 2
  • 自然言語処理: 15
  • 知的マン=マシンインターフェイス: 26

所属プロジェクトのpの人数とLISPプログラマの比

所属プロジェクトのプログラマの人数

所属プロジェクトのpの人数とLISPプログラマの比ですが、まず、所属プロジェクト全体のプログラマの人数は4〜10人位の所が多いようです。

所属プロジェクトのプログラマの人数

  • 1人: 12
  • 2〜3人: 29
  • 4〜10人: 51
  • 11〜50人: 21
  • 51〜100人: 0
  • 101人以上: 0

LISPプログラマの割合

次に、全体のうちLispプログラマの割合。
Lispを使うようなプロジェクトでは、8割以上がLispプログラマという場合が多かったようです。

LISPプログラマの割合

  • 0〜20%: 8
  • 40%: 13
  • 60%: 15
  • 80%: 8
  • 81%〜100%: 55

プログラムの規模とLISPが占める割合、併用している言語

規模

結構大き目なプロジェクトが多かったようで、101kステップ以上の規模が最多となっています。

規模

  • 5k: 4
  • 5-10k: 9
  • 10-20k: 8
  • 20-50k: 19
  • 50-100k: 24
  • 101k以上 41

単位:ステップ

LISP比

プロジェクト全体でLISPが占める割合ですが、80-100%というのが多いようです。
80-100%の53件のうち36件が100%ということなのでLISPのみという所も多かった様子。

LISP比

  • 0-20%: 4
  • 20-40%: 5
  • 40-60%: 21
  • 60-80%: 19
  • 80-100%: 53

※(80-100%は100%が36)

併用言語

LISP以外の言語との併用についてですが、Cが多め。Fortranというのが時代を感じます。

併用言語

  • C: 47
  • アセンブリ: 17
  • Fortran: 13
  • Prolog: 4
  • BLISS: 2
  • KEE: 2
  • マイクロプログラム: 2

併用言語を使うのはなぜか

併用言語を使う理由ですが、OS/マシン依存のため、というのが一番多いようです。
これは今でも変わらないかもしれません。
個人的趣味という回答が光ります。

併用言語を使うのはなぜか

  • LISPで記述不能(システムコール、グラフィックス、ターミナル制御、I/O制御、等): 40
  • 速度: 17
  • 既存swの利用: 11
  • 他言語の高記述性(Prolog等): 4
  • メモリ効率: 3
  • 個人的趣味: 3
  • 可搬性: 1

開発目的

開発目的では、調査研究とプロトタイピングが多くなっています。調査研究の割には規模が大きいというのが特徴との解説があります。
確かにそうですね。

開発目的

  • 調査研究: 65
  • プロトタイピング: 66
  • 社内ユース: 27
  • 商品化: 36
  • その他: 8

LISPを他の言語に書き換える必要性はあるか

LISPを他の言語に書き換える必要性についてですが、4割位は考えたことがあるという感じだったみたいです。

LISPを他の言語に書き換える必要性はあるか

  • あり: 40.6
  • なし: 59.4

書き換えを検討する言語

書き換えにはCが検討されることが多かった様子。

書き換えを検討する言語

  • C: 40
  • Fortran: 2

書き換えを検討する理由

書き換えの理由は、まあ大体Cの特長とされているようなことですね。

書き換えを検討する理由

  • 速度: 32
  • 移植性: 10
  • メモリ効率: 6

実際にLISPから書き換えた経験

それで実際に書き換えたことはあるかということですが、なしが8割ということで、書き換えてないんじゃんとツッコミたくなる結果です。

実際にLISPから書き換えた経験

  • あり: 17.4
  • なし: 82.6

書き換える予定はあるか

しかし、書き換える予定は、3割位は考えているようです。

書き換える予定はあるか

  • あり: 28.4
  • なし: 71.6

LISPの利用動機

LISPを利用しようと考えた動機ですが、大体LISPの長所が述べられています。

LISPの利用動機

  • 柔軟性: 43
  • 生産性: 39
  • 環境: 19
  • 応答性: 3
  • 移植性: 1
  • その他: 22

LISPの開発環境上の問題

開発環境についてですが、これは当時のマシン性能を反映しているようです。

LISPの開発環境上の問題

  • 遅い: 32
  • 処理系が大きい: 22
  • GCの存在: 13
  • ドキュメント化の難しさ: 6
  • デバッグ性の悪さ: 6
  • その他: 39

利用環境

Lispマシンの利用も2割程はあった様子。

利用環境

  • 汎用機: 38.5
  • 専用機: 20.5
  • WS: 26.5
  • PC: 13.7

汎用機の内訳

汎用機というとIBM 360のようなものを想像してしまうのですが、VAXも含まれています。

汎用機の内訳

  • VAX: 56
  • HITAC M: 10
  • FACOM M: 9
  • ACOS: 3
  • PFA: 3
  • DEC 2060: 2
  • UX 700: 1
  • PDP-10: 1

専用機の内訳

Lispマシンでは、Symbolicsと並んでXeroxの1121 AIWも多かったようです。
当時利用していた方の話では、Symbolicsより安価だった様子。
また、TI ExplorerもSymbolics並に導入されていたというのも意外です。
日本で最低2台はLMI Lambdaが稼動していたというのも発見。

専用機の内訳

  • Symbolics: 12
  • 1121 AIW: 12
  • TI Explorer: 9
  • ELIS: 7
  • EVLIS: 3
  • Lambda: 2
  • AI VAX Station: 1
  • 1100 SIP: 1
  • Synapse: 1

ワークステーションの内訳

1988年といえば、ワークステーションが普及してきた頃だと思いますが、やはりSUNが強いようです。
SonyのNEWSも名前があります。
Tektronix 4400シリーズはAllegro CLの最初のプラットフォームだったり、Smalltalkでは名機とされていますが、日本では殆ど耳にすることがないなと思っていました。 このデータを眺める限り、このマシンはそんなに人気が無かったのでしょうか。

ワークステーションの内訳

  • SUN: 32
  • Appolo: 4
  • SX-9100: 4
  • HP9000: 4
  • Sony NEWS: 3
  • USTATION: 3
  • IF-1000: 2
  • Tektronix 4405: 2

PCの内訳

PCは国民機と言われたPC-98が多いようです。
稼動していた処理系はなんだったのでしょう。

PCの内訳

  • PC-9801: 16
  • FM-: 8
  • J-3100: 3
  • Mac: 2

利用している処理系

利用している処理系は、全部で243回答あったようですが、KCLが断トツの一位です。
こんなに人気があるとは思いませんでしたが、日本でのこの人気の割には熱心に開発/改良を加えていたのは、米国の人達だったりするのがちょっと謎です。
KCLに対する日本人開発者の改良の成果は公開されなかったということでしょうか。 VAX LISPも意外にユーザーが多い。

前回はFranz Lispがトップだったらしいですが、KCLが稼動するプラットフォームが増えた為か大躍進したようです。

利用している処理系 243回答

  • KCL: 42
  • Franz Lisp: 26
  • Common Lisp(処理系不明): 24
  • VAX LISP: 23
  • UtiLisp: 11
  • Interlisp-D: 11
  • GC Lisp: 11
  • Zetalisp: 8
  • TAO: 7
  • VOS3 LISP: 7
  • MuLisp: 6
  • Symbolics CL: 6
  • Sun CL: 5
  • Staff Lisp: 4
  • LISP 3.9: 3
  • LISP V10: 3
  • MACLISP: 3
  • その他: 24

利用しているエディタ

開発環境で利用しているエディタです。

汎用エディタ

意外にもviが最多。Franz Lispの利用者が多かった、ということでしょうか。
まあ、Emacs系を足すとviを越えますが…。

汎用エディタ

  • vi: 40
  • Emacs: 28
  • ASPEN: 7
  • GNU Emacs: 6
  • ZEN: 6
  • PFD: 5
  • RED: 4
  • Zmacs: 3
  • FINAL: 3

LISP向きエディタ

LISP向きエディタという括りが微妙ですが、ほぼEmacsです。

LISP向きエディタ

  • EMACS: 11
  • Zmacs: 11
  • CMACS: 4
  • VAX LISP editor: 2

構造エディタ

Emacs系が構造エディタかは微妙なところです。USEは、UtiLispのエディタだったと思いますが、DEdit、SEdit、USE位が本物の構造エディタかなと思います。

構造エディタ

  • DEdit: 7
  • Zmacs: 5
  • USE: 4
  • SEdit: 4
  • VAX LISP editor: 2

開発環境で良く利用している機能

まず、支援機能として括弧対応表示、インデントを思い付くというのがどうも(小並感)を感じますが、当時はこんな感じだったのでしょうか。

  • 括弧対応表示
  • インデント
  • 構造化編集
  • 評価 (eval/compile/debug)

開発環境の満足度

開発環境の満足度

  • 満足: 75
  • 不満: 45

デバッギング ユーティリティ

デバッギング ユーティリティでは、ステッパ/トレーサが好まれていたようです。

デバッギング ユーティリティ

  • ステッパ: 49
  • トレーサ: 93
  • デバッガ: 65
  • break: 62
  • インスペクタ: 33
  • クロスリファレンサー: 10

グラフィック機能

当時、グラフィック機能は結構重視されていたようです。

グラフィック機能

  • 不可: 19
  • ウィンドウシステムあり: 41
  • 図形表示可能: 72
  • 図形入力可能: 37
  • その他: 10

グラフィック機能の満足度

グラフィック機能の満足度

  • 満足: 38
  • 不満: 58

日本語環境

日本語環境はそこそこがんばっていたらしいことが分かりますが、対応していない環境もそれなりにあったようです。

日本語環境

  • 無: 19
  • 可: 84
  • 入力可: 78
  • 文字列操作可: 85

Common Lisp 処理系

Common Lisp処理系でもKCLが断トツ。KS301はTI ExplorerなのでTI CLは7なのではないかと思ったりします。
また、Sun CLもLucid CLのOEMです。
立命館CLというのが気になります。

CL処理系

  • KCL: 42
  • VAX LISP: 19
  • Symbolics CL: 11
  • Sun CL: 9
  • VOS3 LISP: 7
  • GC Lisp: 7
  • Xerox CL: 6
  • TAO: 6
  • TI CL: 5
  • HP CL: 4
  • 富士通LISP V10: 4
  • KS301: 2
  • ICLisp: 2
  • APPOLO: 2
  • Excl: 2
  • Hokkaido CL: 1
  • KonoCL: 1
  • Ritsumeikan CL: 1
  • Lucid CL: 1
  • EusLisp: 1
  • CLISP: 1
  • Synapse Lisp: 1

IV. オブジェクト指向システムの調査 (オブジェクトSG)

Common Lisp Object System Specification 1 & 2

 Common Lisp Object System Specification 1、2の全訳ということなのですが、 共立の「Common Lisp オブジェクトシステム」に掲載のX3J13 88-002Rの1、2は、1988-06-15の版なのでこちらはちょっと古いもののようです。
元になった版の詳細が掲載されていないので、どこがどう違うか確かめてみたいとは思います。

PCLにみるインプリメンテーション技法

これは、共立の「Common Lisp オブジェクトシステム」の中の記事である、「Portable CommonLoops(PCL)での実現技術」の記事そのままだと思います。

V. LOOPマクロの拡張案について(概要・背景)

X3J13のCommon Lisp Iteration Subgroupによる繰り返し機構(拡張LOOP)の提案の翻訳です。
これも翻訳元の資料の詳細がないのですが、CLtL2と比べてみると、CLtL2 26.4の記述では「利用者による拡張性は、DEFLOOPや、DEFINE-LOOP-METHODという拡張が候補として挙がっているだけ」となっている箇所が、この文献では、具体的に構文の説明と使い方が長々と解説されています。
このことからDEFLOOPや、DEFINE-LOOP-METHODでのLOOPのユーザー拡張機構は、CLtL2の時点で検討中というよりは、既に見送りになっていたという気もします。
なかなか興味深い。

まとめ

 1988年の報告書は、アンケート以外は、ほぼ翻訳という感じですが、興味深い話題が多いです。
アンケートが面白い所かなと思いますが、1988年当時はCommon Lisp界隈も結構盛り上がってたんだなあという印象です。

未だにLispは、実験的な言語でおもちゃ、実用言語ではない、ということを云う人はちらほらいるのですが、そういうことを云っていたのは、恐らく1980年代前半位までの話で、この調査報告書の存在から分かるように、1980年代後半には本格的な利用がされていたことが分かります。
とはいえ、その後AIの冬などの影響によりLispは盛り下がってしまう訳で、なんとも歯切れは悪いのですが。

調査報告書には1989年版もあるので、これも閲覧してみたいと思っています。


HTML generated by 3bmd in LispWorks 7.0.0

Older entries (1966 remaining)