Introduction

ブログ内検索

  • このサイトの記事を検索 by Google

おすすめの一冊!

無料ブログはココログ

« 2009年9月 | トップページ | 2009年12月 »

2009年11月

2009-11-30

「いつふぉろ」リリース


★★★ 「いつふぉろ」は全面的にリニューアルしました (2010/Feb/14) ★★★

Twitter をやっていて、ふと、

  「このひとっていつからフォローしてるんだっけ?」

と疑問に思うコトってありませんか?



というわけで、自分がフォロー/リムーブすると DM で
お知らせしてくれる、という bot を作ってみました。

「いつふぉろ」(WhenYouFollow) というものです。


    ⇒ 「いつふぉろ」ホームページ



動作環境はサーバじゃなくて Seaoak の自宅 PC なので、
たぶん夜間しか動いていない bot ですが、まぁ、最悪、
1日1回のチェックでも十分実用的だと思ってます。
# xyzzy が使えるサーバなんてたぶんない・・・


Common Lisp の練習がてら作ったモノなので、
もしかすると誤動作しちゃうかもしれませんが、
対応はちゃんとするつもりなので、なにかあれば
Twitter 上で @seaoak2003 まで、またはこの記事に
コメントいただければと思います。

どうぞよろしくおねがいします。


p.s. 「いつふぉろ」と連携して Twitter の Web に日付を表示するグリモンも
   作っているので、そのうちリリースします。

2009-11-19

〔ぐりもん〕 AddFooterIntoTweet

ふぁぼったーの中の人が

    TwitterのWebでフッター設定できるグリモンが欲しい…

と、つぶやいていたので、ちょろっと書いてみました。



この GreaseMonkey スクリプトを Firefox にインストールすると、
Twitter のホームページの「つぶやき」のテキストボックスのすぐ下に、

    Footer: (not spceified)  [change]  [add]

という文字列が出現します。

ここで [change] をクリックするとプロンプトウインドウが出るので、
フッターとして指定したい文字列を入力します。
すると、上の文字列が書き換わり、同時に Firefox 内部に記憶されます
(ここで何も入力しないと設定がクリアされます)。

あとは [add] をクリックすれば、上のテキストボックスの末尾に
設定したフッター文字列がそのまま追加されます。

Firefox を落としたり PC を落としたりしても設定は記憶されているハズです。
# もし設定がリセットされてしまったらご連絡を・・・



  ■ DOWNLOAD ■

    addfooterintotweet.20091119a.user.js

    ※ HTML タグのエスケープが正しくできていなかったので差し替え
    addfooterintotweet.20091201a.user.js

    ※ フッター文字列の編集 (change) をキャンセルしたら変更しないように改良
    addfooterintotweet.20100203a.user.js

    ※ Google Chrome に対応(HTML5 の Local Storage を使うように変更)
    addfooterintotweet.20100203b.user.js

    ※不等号記号を含むフッター文字列を正しく扱えていなかったのを修正
    addfooterintotweet.20100204a.user.js

  最新版は userscripts.org にアップしてあります↓
  http://userscripts.org/scripts/show/66876

  ※ Firefox (GreaseMonkey) / Google Chrome / Opera で動作確認済み


ご要望やバグ報告などありましたら、この記事にコメントいただくか、
Twitter 上で @seaoak2003 までお願いします。

2009-11-14

*OBSOLETED*

スパコンとグリッド

昨夜から「事業仕分けで日の丸スパコンが落選か!?」という話が
話題になっているので、ちょっと支援しようかと思い立ちました。
# まぁ、時すでに遅しかもですが・・・


とりあえず第1回は小ネタです。


    -・-        -・-        -・-        -・-


たまに「グリッドじゃだめなの」という疑問を耳にすることがあります。
ふつうのスパコンは地理的にひとつの場所(計算機センターとか)に
多数の計算機を並べたものですが、グリッドというのはイントラネットや
インターネットで繋がった多数の計算機で分散処理しようという話ですね。

で、違いというと、均質性(スパコンは個々の計算機の性能のばらつきがあまりない
ので処理を分配しやすい)とか、信頼性(長時間連続で計算し続けても故障して
止まる確率が低い)とか、メモリバンド幅とか、まぁ、いろいろあるのですが、
一番の違いは計算機間の通信性能だと思います。多くのスパコンでは、
インターネット接続やオフィスの LAN みたいな低帯域/高遅延のネットワーク
ではなくて、InfiniBand などの(ほとんどスパコン専用の)広帯域/低遅延の
ネットワークを採用しています。具体的に言うと、ふつうのオフィスの LAN の帯域は
100Mbps~1Gbps くらいですが、InfiniBand だと 40Gbps とかになります
(ざっくり言って数十倍の通信速度がある)。まぁ、そのために一カ所にまとめて
設置しているというのもあるわけですが(なにしろ、ケーブルの長さ、つまり
ケーブルを電気信号が伝わる速度まで勘定に入れないといけない世界なのです)。

スパコンのランキングとして有名な Top500 ですが、その指標になっている
LINPACK というアプリケーションでは通信性能はあまり問題にならなかったりします
(だから LINPACK は実アプリ性能を反映していないとよく言われる)。しかし、
アプリケーションの中には実行時間の半分以上を通信に費やしているなんてモノも
あったりするのです。そんなアプリケーションをグリッドで動かそうとしても
ほとんど使い物になりません。

というわけで、解きたい問題によってはグリッドはとても強力なのですけど、
グリッドだけだといわゆるスパコンで解きたい問題の一部しか解けません。
まぁ、両方あると便利だけど、グリッドだけではスパコンの代替にならない
ということになります。

スパコンは必要!!

2009-11-05

else 節のインデント

あいかわらず「On Lisp」のサンプルコードを xyzzy で打ち込んでます。

もちろん xyzzy の lisp-mode を使っています。
オートインデントや括弧の対応付けがあって、とっても便利♪

ただ、if 文のインデントにちょっと違和感があったりします。

(defun find2 (fn lst) (if (null lst) nil (let ((val (funcall fn (car lst)))) (if val (values (car lst) val) (find2 fn (cdr lst))))))
else 節の頭が then 節とずれているのがちょっと気持ち悪いのです。 ちょろっとググってみたところ、 Emacs Lisp の if 文は else 節が暗黙の progn になっていて、 Emacs の lisp-mode はそのためにわざとインデントをずらしているらしい。 でも、xyzzy は Emacs Lisp じゃなくて Common Lisp の処理系で、 Common Lisp の if 文は else 節としてひとつの文しかとれないのです。 「On Lisp」のサンプルコードだと else 節の頭は then 節とそろっているので、 たぶん Common Lisp の人たちはインデントを揃えているハズ。 というわけで、xyzzy の lisp-mode (lispmode.l) を眺めてみると、 なにやら if 文を特別扱いしているっぽい行がありました。
(setf (get 'if 'lisp-indent-hook) 2)
lisp/lispmode.l の 40 行目です。 この行をコメントアウト(行頭にセミコロンを挿入)して、 byte-recompile-directory して、Ctrl+Shift を押しながら xyzzy を起動させると、見事にインデントがそろいました! 我ながらすばらしい♪ というわけで、ちょっと幸せになりましたー

2009-11-04

クォート付きリストの罠

マクロの魅力が知りたくて Common Lisp を勉強してます。

きっかけは「LET OVER LAMBDA」という本を買ったこと。
ポール・グレアム氏のコラム(「ハッカーと画家」)を読んで以来、
Lisp の知られざるパワーの源であるらしい「マクロ」の威力を
ぜひ知りたいと思っていたのですが、そのマクロのテクニックに関する本です。

しかし、この本、いわゆる「マクロ・ジェネレーティング・マクロ」の連続で、 Common Lisp に慣れていない身ではちんぷんかんぷん。 結局、4章で挫折しました・・・ -・- -・- -・- -・- Common Lisp の基礎はポール・グレアム氏の「ANSI Common Lisp」でおさらい したのですが、マクロに関してはごく基本的なことしか分からないまま。 というわけで、気を取り直して、今度は "On Lisp" にトライすることにしました!
せっかくなので、サンプルコードを xyzzy で打ち込んでみることに。 やっぱり手を動かすと理解が早い気がするのです。 で、まだマクロまでたどり着いていないのですが、 ユーティリティ関数のところでちょっとした罠にはまったので、 後学のためにもメモしておきます。 -・- -・- -・- -・- 図 4.2 (p.49) で "filter" という関数の定義が示されています。
(defun filter (fn lst) (let ((acc nil)) (dolist (x lst) (let ((val (funcall fn x))) (if val (push val acc)))) (nreverse acc)))
dolist でリストをなめながら途中経過を変数に蓄積して、 最後に結果を nreverse する、という定石コードになっています。 実行するとこんな感じ↓
> (filter #'evenp '(1 2 3 4 5)) (t t) > (filter #'oddp '(1 2 3 4 5)) (t t t) > (filter #'zerop '(1 2 3 4 5)) nil
これはこれでいいのですが、せっかくリストを一から作っているのに 最後に nreverse する手間がもったいない気がしてなりません。 # 単に Lisp に慣れていないだけかもしれませんが・・・ で、自分なりにコードを考えてみたのが次のコード↓
(defun my-filter-wrong (fn lst) (let ((acc '(nil))) (labels ((rec (lst tail) (if (null lst) (cdr acc) (let ((val (funcall fn (car lst)))) (cond (val (setf (cdr tail) (list val)) (rec (cdr lst) (cdr tail))) (t (rec (cdr lst) tail))))))) (rec lst acc))))
ところが、この関数を実行してみると、妙な挙動をします。
> (my-filter #'evenp '(1 2 3 4 5)) (t t) > (my-filter #'oddp '(1 2 3 4 5)) (t t t) > (my-filter #'zerop '(1 2 3 4 5)) (t t t)
zerop を指定すると nil が返るはずが、なぜか前回の結果が返ってきます。 変数 acc は let で作ったローカル変数のハズなのに、 なぜか状態が残ってしまっているようです。 しばらく悩んだのですが、この問題はまさに「On Lisp」の 3.3 章で 注意されていた罠でした。 正しいコードは以下の通り↓
(defun my-filter (fn lst) (let ((acc (list nil))) (labels ((rec (lst tail) (if (null lst) (cdr acc) (let ((val (funcall fn (car lst)))) (cond (val (setf (cdr tail) (list val)) (rec (cdr lst) (cdr tail))) (t (rec (cdr lst) tail))))))) (rec lst acc))))
つまり、let で代入している初期値が「クォート付きリスト」(p.38) なので、 その実体は関数定義時に生成されたインスタンスそのものになってしまい、 それに対する破壊的操作が「関数の内部状態」として残ってしまったのでした。 実は、元のコードは「関数がクォート付きリストを返すべきではない」という ルールを思いっきりやぶっているので、言ってみれば二重の意味でバグってます。 返値に破壊的操作を施すと関数の挙動が変わってしまいますし、 そもそも返値を引数にして評価するとエラーになってしまいます↓
> (let ((lst (my-filter-wrong #'evenp '(1 2 3 4 5)))) (my-filter-wrong #'zerop lst)) ★エラー★
これじゃ、参照透過性なんてあったもんじゃありません。 -・- -・- -・- -・- 今回の問題は Lisp 風のコードをC言語風(ポインタを直接扱うコード)に したのが直接の原因なので、そのうち Lisp な思考ができるようになれば 関係なくなるのかもしれませんが、「Common Lisp ってやっぱり難しいなぁ」 と改めて思ったのでしたー

« 2009年9月 | トップページ | 2009年12月 »