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画像

2015年10月22日木曜日

Viscera Cleanup Detail 攻略 : センサー反応 そのほかtips

少しだけ:Viscera Cleanup Detailとは

怪物に襲われたゴミ処理場、何かの生物に襲われた?医療設備、何かあったらしい宇宙ステーションなどのさまざまな惨劇の舞台を清掃するゲームである。

Visceraとは臓物の意

ぶちまけられた血、反撃の後のと思われる銃痕、薬莢に銃、何よりバラバラになった人体と臓物、たおされた怪物の一部などなどのグロ要素
そこに馬鹿みたいに散りばめられた菓子の袋や紙コップ、中華料理のテイクアウト箱、缶。などの、なんで片付けねぇんだクソ、、と思わされる要素に満ち溢れた素敵なゲームである。

この記事はプレイしたことがある人を対象に書いている。ゲームの様子などはぜひ実況者さんのプレイを参照されたし。

センサーに反応するもの

センサーには二種類あることはプレイされた方であればご存知のことと思う。だが、何に反応するかは、割とわからなくなりがちであるので、まとめた。

緑のセンサー:物体反応

  • 薬莢
  • 銃痕、プラズマ銃的な攻撃の跡
  • 煤汚れ(プラズマ溶接銃や火薬ドラム破壊などで出る火の跡)
  • 菓子袋、紙コップなどゴミ
  • バケツ
  • 壊れたランタン

青のセンサー:生体反応

  • 肉片、臓物、未知の生物
  • 血液
  • バケツ

覚えておきたい

  • バケツは両方に反応
  • 銃痕、煤汚れは物体扱い
  • ドラム缶、何かの箱?ブロック?コンテナ?は清掃対象外
  • ステージごとに清掃対象外の物体は案外ある。みどりの植物体とか。

その他Tips

  • zero gravity のエレベーターは重力On時に稼働する
  • 無重力状態では、汚れたバケツをぶちまけても周りは汚れない!
    • ありがたいが、将来変更されても不思議ではない
  • バケツは水入りでも2段まで安定して重ねて運べる
    • 3つ以上はうまくいかないことが多いのでやらない
    • (追記)Shiftで歩いているときは3段安定らしい。
      • 私は3段持って走ると、段差を超えたときに大体吹っ飛ぶ。
  • 一番の敵は物理エンジンである。間違いない。
    • 特に薬莢はゴミ箱の中身をぶちまける原因になりやすい。
      薬莢を含むゴミ箱には、臓物をできるだけ入れないのがよい

ゲームについてのその他のこと

リアルタイム2時間を平気で食いつぶしてゆくゲーム。

ゲームにおける効率化の追求とミスをしない手際のよさの育成がされる(プレイヤーの。)

綺麗になった部屋を見てなんか満たされる感覚を味わえる

イラついたらプラズマ溶接銃で溶かしまくろう!

2015年10月14日水曜日

StackEditを使ってBloggerに記事を投稿する際に注意することのメモ

注意事項一覧

  • 記事名は原則としてファイル名
    • 後述の YAML Formatter を用いることでつけることが可能
  • タグはつけられない
    • 後述の YAML Formatter を用いることでつけることが可能
  • 投稿のID (PostID) は、記事編集ページのURLの中に含まれている
    • 記事を編集で開き、URLを確認する
    • 記事一覧ページで記事編集ページへのリンクURLを確認する
  • アップロード後に編集、そのあとに再アップロードすると、、、
    • タイトルは元に戻る
    • タグは元に戻る
    • 記事内容はアップロードしたものに戻される
    • とにかく全部元に戻るので、Stackedit の中で完結するようにしないといけない
  • 箇条書きは「前」と「後」の両方に空行がないとダメ
    • 「前」に空行がない場合は箇条書きと認識されない
    • 「後」に空調がない場合、箇条書きの一部とみなされ、組み入れられる

YAML Formatter によるメタ情報の記載方法

StackEditがBloggerにアップロードする場合、YAML Formatter によるメタ情報の埋め込みに対応している。記事テキストの冒頭に、次のようにメタ情報を記載する。

---
title: 記事タイトル
tags: タグ1,tag2,タグ3
---

利用可能と説明されているタグは

  • title : 記事公開用タイトル
  • tags : 記事のタグ, カンマで区切る
  • published : (未確認)
    • false で非公開状態でアップロード?
    • (追記) 2015-11-07 : false で下書き状態でアップロード。
  • date : (未確認)
    • 公開日設定をできそう
    • 公開予約もできる?

情報は2015-11-09現在。

スタイルや記事の書き方に関連する事項 (2015-11-09追記)

  • 記事タイトルと見出しレベル1を同じにしたら、同じ文章が大きく二つ並んで見苦しい
    • 見出しレベル1:#一つ, ===による区切り
    • Markdown の記事スタイルとして、見出しレベル1の要素を記事タイトルとして使う方法はとれない
  • 現在自分の 使用する Bloggerスタイルテンプレートは、見出しレベル2より、レベル3のほうが大きい。
    つまり、テンプレート次第では、見た目に影響が出てしまう。使用に注意が必要
    • できるだけ記事の論理性に一致するテンプレートを使いたいところ
    • h1 が一番目立つ、h2 が次、h3はそれより小さい、、、
    • スタイルシートのカスタマイズも手ではある

Written with StackEdit.

2015年9月26日土曜日

CommonLisp の標準機能における繰り返し処理の一覧

参考

Common Lisp Quick Reference

Land of Lisp (書籍) : 日本語訳10章にある Loopマクロ周期表が役に立つ

使用方法については次を参照。
- Lisp入門サイト(そのうちまとめる)
- Hyperspec
- 逆引きCommonLisp の 制御構造のページ

一覧

どれぐらい役割や使い方が簡単に理解でき かの順に並べている

  • dotimes, dolist
  • map系関数 : mapcar, mapc, etc…
  • xx-if, xx-if-not 系関数 : remove-if-not, substitute-if
  • loop (永久ループ)
  • do
  • loop (複雑なマクロ)
  • tagbody と go を用いたループ

これは、、、なかった

  • foreach, each : dolist, loop
  • for : 上記のうちからデータ構造に合ったものを選ぶ
  • foreach-range : OnLisp にある mapa-b など参照
  • while : do, loop で実装, 有志のマクロなども参照

補足

  • 少なくとも上を覚えておくと、ProjectEuler, HackerRank etc… などの回答系サイトでは困らない
  • 同じことを繰り返した結果、面倒になって、OnLispに載っていたマクロを使いだすこと請け合い
  • GoogleによるCL Coding Standard で半推奨的な位置にあるためか、loopマクロをよく見かける。
  • REPLのエラー表示でマクロ展開形にtagbodyが出てくることがある。マクロは自由である。
  • 実際のコードを見てどれが繰り返し処理かを見抜くことは,,,私には少なくとも難しい。
    • APIやデータ構造の把握が先に必要。
  • 書き漏れがあったらまた記事更新する
    • もっと伝わる書き方がわかったら記事更新する

書籍のご案内

Written with StackEdit.

2015年9月13日日曜日

BloggerにMarkdownで記事を書きたいんです

Blogger に Markdownで記事を書きたいんです!!楽なんです!

大切なことなので2回書いた。

StackEdit がその欲求を かなり 満たしてくれる。

特にソースが書きやすい。Blogger のソースコード対応は実際残念

(defun tarai (x y z)
  (if (< x y)
      y
      (tarai (tarai (1- x) y z)
             (tarai (1- y) z x)
             (tarai (1- z) x y))))

うまくいったらごかっさい!

覚書。

  • いきなり公開状態になるようである。要注意。
    • (追記:2015-11-10) YAML Formatter で published: falseを指定することで非公開でアップロード可能
  • タグは当然(?)つかない。つけ方あるかも。
  • 一度アップロードして、タグ付けして、再アップロードはタグに影響なし。
    • (追記:2015-09-26) タグ消えてた。YAML Formatter でつけるのが吉
    • (追記:2015-11-10) YAML Formatter でつければ付け替えも容易
  • 冷静に考えると、新しい記事としてアップロードされるわけではないのだな
    • (追記:2015-09-26) Bloggerの投稿済みページ管理からPostID を見つけ出して指定できる
    • (追記:2015-11-10) StackEdit 経由であれば自動的にID を認識して上書きしてくれる
  • なぜはてなにしなかったのかと今は思う
  • Dropbox との相互syncとあわせると記事管理がはかどる、、、ことを期待
  • markdownで改行すると、アップロードでも改行される。これは少し期待と異なるが許容範囲。

注意点をまとめた記事を書いた。

Written with StackEdit.

2015年8月26日水曜日

ASDF にかかわる右往左往

かかずにはいられない

ASDFに対する先入観がゆえに迷う

ASDFについてかつて聞いたことがあった、yum や apt-get のようなものと思っていた
そのことを知っていたがゆえに迷った。yumや apt-getで取得したプログラムがどこにおかれているか、普通は知らないようなもので、いったいどこにあるのか、ちょっと調べただけでは出てこなかった。

なお、正確には asdf-install が実際 yum や apt-get のような役割を果たしていた
現在はQuicklisp がその役割を担っている。

Quicklispは認証つきHTTP Proxy を超えられなかった。

Quicklisp 自体は Proxyなしの環境で動作することを確認した。手軽ですばらしい。

認証付のProxyについては?無理である。公式にも(今は)出来ないと書いてある。

じゃあ作ってやるぜ!と一瞬思ったが、
誰が使うんだろう?とか、自分なんかに、とか、
とりあえずやらない方向の感情が渦巻いたのでとどまった。

そんなことよりライブラリが動いてほしかった。

公式の説明にすべて書いてあった

  • ~/common-lisp フォルダ内にライブラリをフォルダごと置く
  • フォルダ名と 中にある .asd の名前が同じになるようにする
  • 大体のライブラリは .asd が提供されている
  • 自分で作ったライブラリでも同じようにできる
と書いてある。英語で。英語で。そしてすべてそのとおりにすることで結果的に動いたのであった。

公式の情報に気づいた時点で、古いasdf-install の日本語の情報にはあたったあとであり、Quicklisp は Proxyなしで普通に使う方法がわかっていたこともあってASDF についての調査がほぼ意地になっておりWindowsでは微妙に違うね、とかASDF 3.1.5 以降では、とかXDG_DATA_PATH とかわからないキーワードに引っかかってみたりなんとなくそうらしいところにフォルダをおいてみたりQuicklispのフォルダにおいてみたり環境変数を見てみたりパスを確かめる関数を探してみたりして片っ端から失敗して結果完全に頭に血が上っており要するに

本当にそうだと気づくまでに2日かかった。

SBCLの認識するホームディレクトリを確認する方法

次のコードを実行することでわかることを知った。
(truename "~")
もっとも、実行結果で偶然わかるのであって、処理自体はエラーになる。
わからないが用は足せる。というやつである。

Lispの情報の大半は英語である!

和訳情報もあるし、日本語で有用な情報を発信される方はこれが結構多い。
そして2chのLisp関連スレは意外なことに機能しているし、
困らないんじゃないか!と思ったが、これがこまる。
2chコワイ。そもそも何を聞いたらよいかわからないという。

丁寧な解説は基本的に英語であるというのは身もふたもない事実なので、
冷静に英語を読んだほうが良い結果になりやすい。と今回の件では思った。