2015年11月7日土曜日

CommonLispでpackageとか名前空間とか コロン(:) について知ったこと

概要

  • Common Lisp の package について
    • 解説したリンクを集めた
    • package について説明を試みた
    • package について疑問に思ったことをまとめた

参照リンク集

CommonLispでの Packageとは?

  • Lispの関数名も変数名も シンボル として扱われることを納得しておく必要がある
    • 関数名、変数名、スペシャル関数名、マクロ名 etc
  • シンボルが 所属 する シンボルの管理単位
    • 一部の例外を除く(!)すべてのシンボルは パッケージに属している
    • 例外1:gensym で生成されたシンボルは どのパッケージにも属さない
    • 例外2:キーワード - キーワード(keyword)という 特別なパッケージに属している
  • Common Lisp の第一級オブジェクトである(後述)
  • CommonLisp が標準で持っている関数やマクロや変数(シンボル)は
    cl, common-lispという名前空間に属している
  • REPLで実行して一時的に作られた and/or
    特にパッケージを明示せず定義されたシンボルは
    cl-user, common-lisp-user という名前空間に属している
    • REPL のデフォルトの package である

シンボルは第一級オブジェクトである、とは?

なんでも定義・変更できる(?) Common Lisp の例にもれず、package も各種操作を受け付けるということ
  • パッケージ(という値)の定義、削除
  • パッケージの名前の定義、削除、変更、ニックネームの定義
    • やっぱりパッケージを表すシンボル なんだろうか。調べきっていない
  • パッケージの中身=シンボル、の追加、削除
  • パッケージの外側に公開(export)するシンボルの決定
  • 他パッケージに属するシンボルを自パッケージに包含する
  • 自他パッケージに属するシンボルを「隠す」「上書きする」
    • shadowing? ここがまだよくわかっていない、あるいは困るまで調べない
    • 関数のオーバーライドと呼ばれる機構に近いらしい
  • 現在のパッケージ を切り替える
  • 各種調査用関数

パッケージのシンボルに対するアクセス方法 … コロン(:) の意味

  • package-name:symbol-nameexport されているシンボルにアクセス
    • packageが読み込み済みである必要がある
    • ppcre:scan ql:quickload asdf:load-system など
    • あるライブラリが提供している関数を使うときはこの方法を使う
  • package-name::symbol-name で パッケージ内の任意のシンボルにアクセス
    • exportされていなくてもアクセス可能
    • private, friend, protected 、、、なんてものは存在しない、完全ノーガード
    • shadowingしたらどうなるんだろう?
    • この手段を使うのは冷静に考えて邪道

コロン(:) を使う特別なシンボル…キーワード について

  • :keyword のように、コロン(:)から始まるシンボルをキーワードという
    • 何もない名前空間を参照しているわけではなかった
  • キーワードは 評価するとシンボル自身を返す
    * :test
    
    :test
  • キーワードは、keywordパッケージに属する
    • という扱いらしい。

Common Lisp のソースを読んでいて浮かぶ疑問

  • defpackage ? in-package ? なにこれ?
    • defpackage のところに、パッケージ名が書かれています。
    • :export という項目があれば、それが公開されている 関数、変数の一覧です
    • in-package はそのあとに定義したシンボルをパッケージに所属させるための
      定型文ですので、自分でライブラリを書くのでなければ気にしなくてよいです
  • ライブラリの関数なんかは ライブラリ名 + : + 関数名、で呼べるんだね?
    • だいたいそうです。cl-ppcre:scan とか asdf:load-system とか。
    • ライブラリ名とパッケージ名が違う可能性があるので注意してください
    • ニックネームが提供されていることがかなり多いです。 cl-ppcreppcre でもOK。
  • (あるはずの関数・変数について)そんなものないって怒られるんですけど
    • asdf, quicklisp でライブラリの「処理の中身とシンボル定義」を読み込む必要があります。
      • 読み込んだ後から使えるようになります
    • 自分でパッケージを扱いだすと、もう少し複雑な「シンボルがない」状況に直面すると思います
  • defsystem, defgeneric, defmethod, def** ってちがうの?
    • defsystem はわりと関係あるんですが、、、わかってません。ひとまず ASDF に関連してます
    • defgeneric, defmethod は CLOS ですね。まだよくわかってません。
    • だいたい「**を定義するマクロ」だと思って間違いありません。

他言語から流れてきた人間として思う疑問

  • namespace, using (C++, C#, Java) とは違うの?
    • namespace はかなり package に近い、クラスや関数の所属先を決めている
    • 違いは CommonLisp では シンボルは、定義された瞬間のpackageに属する こと
    • in-package で定義される 現在のパッケージ に属する
    • シンボルをパッケージに所属させることを intern というが
      任意のパッケージを指定できる
    • using の代わりに、defpackage の :use や use-package関数を使う
  • require(ruby), import(python) とは違うの?
    • common lisp にも require はある、、、いろいろまずくて誰も使ってないけど
    • ライブラリをひとまとまりで読み込む標準の機能はない
    • それは quicklisp や asdf が手助けしてくれる
      • はよ言語標準にならんかな
    • 個別ファイルであれば load を使うことで可能
    • using の時に書いた defpackage の、、、などが、そのpackageにあるシンボルを
      パッケージ名省略して使います、という宣言になる

まとめ。他の言語がむしろ、一つの文に複数の機能を備えていると言えるのでは。

  • 名前空間の定義
  • (名前空間に属する機能の)プログラムやデータの一括読み込み機構
  • 関数名、変数名、クラス名について、名前空間の明示的な省略
そしてLisperはおもむろにマクロを定義するのであろう。

ひとこと

  • Common Lisp における package に調べだしたところ、
    それがなんであるかについてはイメージを持てたのだが、
    いざ説明を書こうとして説明が難しすぎてさじ投げた
    • 伝わる書き方というのが結局見えなくなった
    • 特に、他言語の例については、ある程度理解が進むとむしろ説明が難しい
    • 何がわかっていなかったかわからなくなる
    • 他言語の例は自分が知っている言語をさらしているだけのような気がする
  • 投げたさじを拾ってわかっていることだけまとめておいておくことにした
    • 伝わるように書くことをあきらめた
  • Quick Reference に載っている関数を一通り試したのだが、
    一部の関数が思ったように動いてくれない。使い方を勘違いしているのだろう。
Written with StackEdit.

StackEdit上の編集でXXを含む記事をBloggerに投稿する方法メモ

画像

Blogger はURLを指定して画像を記事に埋め込むことができる。StackEditはMarkdownの画像埋め込み機能を使ってそれを簡単に実現できる。
アップロードはどうせGoogleのサービスを使っているのだからGoogle+ がよいだろう。StackEdit のGUIに Google+の画像をImportしてくるというボタンもあるため、使いやすい。

アップロードテスト用の意味のない絵 タイトル
画像のをつける機能はないのである!

Markdownの記法としては

![<alt属性テキスト>](<ImageURL> "<title属性テキスト>")

Google+ の画像を使うときは、素直に StackEditの機能を使ったほうが良さそうである。URLが埋め込み専用のシンプルなものになっている。

アニメーションGIFもいける。

画像だからね。
ウゴツールで作成した特に意味のないGIF画像