いけがみを召喚するには、出現予定を参考にしてください。三週間前までにメールをくだされば、日程を追加するなどしてスケジュールに組み込むことができるかもしれません。勉強会や個人的な会合、中途採用面接などに応じます。日記に書かないことはこちら。
Carbon Emacs をフルスクリーンで使うをみて。via オレンジニュース.
いけがみは Terminal.app 上で Emacs を使います。というのは、GNU screen で copy & paste をしたいので。Terminal.app に限らず、Cocoa アプリケーションはフルスクリーン(メニューバーおよびウィンドウタイトルバーを隠して最大化)にすることができます。そのために使うのが、SIMBL と megazoomer 。
SIMBL は megazoomer の他にも面白いプラグインが開発されているのでぐぐるとよいでしょう。
追伸:ていうか、Emacs と GNU screen どっちが死にやすいかって話だな。Emacs に Abort と言われたときにゃ、ぐぎゃーっ。その点、screen は reattach できるもんな。zsh で ignore_eof しとけば ^D も怖くない。
これはこれでいいものだなあ。Net-Install がお手軽ですね。以下、tty な Emacs との住みわけの覚え書き。
(if window-system
(progn ()
(setq inhibit-startup-message t)
(toggle-scroll-bar nil)
(mac-toggle-max-window)
(add-hook 'window-setup-hook
(lambda () (tool-bar-mode)))
(switch-to-buffer "*scratch*")
))
Simple Extensible Records -- Quick Generic Tricks, Pt.1 という手法が開発されたというニュースを目にしました(from programming.reddit.com)。
GHC 6.8.2のData.Genericsと"Scrap your boilerplate" -- Generic programming in Haskellを理解されている方にはこれ以上の解説は不要だと思います。Simple Extensible Recordsは便利な手法なので、使いどころがあれば適用してはいかがでしょうか。
ここに私なりに理解したことをメモしておきます。間違いなどがあったらご指摘ください。
Haskell が持っている強力な機能は、1. 代数的データ型 2. パターンマッチ(パターン束縛) です。これ以外にも Haskell には強力な機能はありますが、今回はこの 2 つの機能に注目します。
代数的データ型の例を挙げます:
data Color = Red | Green | Blue
これは、型 Color として三原色を定義した例です。色は、赤、緑、青の 3 種類です(説明のため、簡単に 3 つに絞りました)。もう少し複雑な代数的データ型を見てみましょう:
type Length = Int type Radius = Length data Circle = Circle Color Radius
これは、型 Circle として色付きの円を定義した例です。円は、色 Color と半径 Radius = Int を用いて表されます。
さて、円から色を取り出すにはどうしたらよいでしょうか。方法はいくつもあります。もっとも単純なのは、関数を定義することです:
color :: Circle -> Color color (Circle c _) = c
しかし、関数を定義する代わりにもうすこし単純な方法が用意されています。それが、ラベル付きフィールドです。先ほどの Circle の定義を次のように書き換えます:
data Circle = Circle { color :: Color, radius :: Radius }
これにより、二つのメリットが生まれます。一つは、関数 color :: Circle -> Color が自動的に定義されることです。関数の定義は、上に述べた color :: Circle -> Color と同じものです。もう一つは、次のような書き方によって、フィールドラベルの更新が可能になることです:
one :: Circle
one = Circle Red 1
two :: Circle
two = one { radius = 2 } -- ==> two = Circle Red 2
次に型クラスについて、簡単に触れます。次のように、色のついた長方形を表す新しいデータ型を追加したくなったとしましょう:
type Height = Length type Width = Length data Rectangle = Rectangle Color Height Width
このとき、残念ながら、次のように書くことはできません:
data Circle = Circle { color :: Color, radius :: Radius }
data Rectangle = Rectangle { color :: Color, height :: Height, width :: Width }
なぜなら、color :: Circle -> Color と color :: Rectangle -> Color が衝突してしまうからです。この問題に対して、Haskell では type class という方法を提供しています:
class HasColor a where color :: a -> Color instance HasColor Circle where color (Circle c _) = c instance HsColor Rectangle where color (Rectangle c _ _) = c
これで、関数 color を Color にも Rectangle にも適用することができます。この方法は、2 つの関数 colorCircle :: Circle -> Color, colorRectangle -> Rectangle -> Color を準備するよりは簡潔です。
衝突しないラベル付きフィールドを定義するには、次のような方法をとるより仕方ありません:
data Circle = Circle { colorCircle :: Color, radius :: Radius }
data Rectangle = Rectangle { colorRect :: Color, height :: Height, width :: Width }
さて、もうひとつのややこしい問題を述べます。次のように、データ型が複雑になってきたとしましょう:
data Shape = SC Circle
| SR Rectangle
newtype BackgroundColor = BackgroundColor Color
data Text = Text Color BackgroundColor String
data Widgets = WS Shape
| WT Text
このとき、Widgets から Color を取り出すために、パターンマッチを使う方法を用いると次のようになります(方法は一通りではありませんが、最初に思いついたのはこれです):
instance Color Shape where color (SC c) = color c color (SR r) = color r instance Color Text where color Text c _ _ = c instance Color Widgets where color (WS s) = color s color (WT t) = color t
データ構造が階層的に複雑になるにつれて、type class と instance の記述が複雑になります。これが第二の問題です。
以上の二つの問題をまとめます。代数的データ型はデータの定義を階層的に定義できて、その結果、関数定義のパターンマッチによる条件分岐が可能になります。これは強力な機能です。しかし、「同じ性質を持つ」という情報を書き下したい場合(今回の例でいえば color :: a -> Color)、その定義は綺麗とは言い難いです。オブジェクト指向言語ならば、color メソッドを各クラスに定義することで、共通のインターフェースを提供できるのに比べると、その点で Haskell は見劣りしてしまいます。
Simple Extensible Records は GHC 拡張機能の DeriveDataTypeable と "Scrap your boilerplate" -- Generic programming in Haskell を組みあわせて、この問題を解決します。方法は、以下の通り:
{#- LANGUAGE DeriveDataTypeable #-}
import Data.Generics
import Control.Monad
import Data.Maybe
greplace :: (Data a, Typeable b) => a -> b -> Maybe a
greplace x y = once (const Nothing `extM` (const (Just y))) x
where
once :: MonadPlus m => GenericM m -> GenericM m
once f z = f z `mplus` gmapMo (once f) z
gfind :: (Data a, Typeable b) => a -> Maybe b
gfind = something (const Nothing `extQ` Just)
class Data a => HasColor a where getColor :: a -> Color getColor = fromJust . gfind setColor :: a -> Color -> a setColor = (fromJust .) . greplace
instance HasColor A instance HasColor B ...
"Simple Extensible Records" が提案している手法は、この問題を解決する lightweight な方法です。ただし、その実装は Data.Generics という"黒魔術"を使っています。なにが黒魔術かというと、内部で cast:: (Typeable a, Typeable b) => a -> Maybe b という関数を用いていることです。これは動的な型安全を保証する関数です。また、パターンマッチを使って地道にプログラムを書くことに比べると若干の速度の低下を招きます。そのへんの詳細は "Scrap your boilerplate" -- Generic programming in Haskell の論文を参照してください。また、関数 greplace は関数 once を用いているので、最初にマッチしたものを返し、その他は捨ててしまいます。関数 gfind も最初にマッチしたものを返し、その他は捨ててしまいます。そのことを忘れてうかつに使うとはまること間違いなしです。
今回用いた具体例に対する完全に動作するコードは以下の通りです:
{-# LANGUAGE DeriveDataTypeable #-}
import Data.Generics
import Control.Monad
import Data.Maybe
greplace :: (Data a, Typeable b) => a -> b -> Maybe a
greplace x y = once (const Nothing `extM` (const (Just y))) x
where
once :: MonadPlus m => GenericM m -> GenericM m
once f z = f z `mplus` gmapMo (once f) z
gfind :: (Data a, Typeable b) => a -> Maybe b
gfind = something (const Nothing `extQ` Just)
data Color = Red | Green | Blue
deriving(Data, Show, Typeable)
class Data a => HasColor a where
getColor :: a -> Color
getColor = fromJust . gfind
setColor :: a -> Color -> a
setColor = (fromJust .) . greplace
type Length = Int
type Radius = Length
data Circle = Circle Color Radius
deriving(Data, Show, Typeable)
type Height = Length
type Width = Length
data Rectangle = Rectangle Color Height Width
deriving(Data, Show, Typeable)
data Shape = SC Circle
| SR Rectangle
deriving(Data, Show, Typeable)
newtype BackgroundColor = BackgroundColor Color
deriving(Data, Show, Typeable)
data Text = Text Color BackgroundColor String
deriving(Data, Show, Typeable)
data Widgets = WS Shape
| WT Text
deriving(Data, Show, Typeable)
data TwoWidgets = Two Widgets Widgets
deriving(Data, Show, Typeable)
-- instance HasColor ...
instance HasColor Rectangle
instance HasColor Widgets
instance HasColor TwoWidgets
widget :: Widgets -- a rectangle widget
widget = WS (SR (Rectangle Red 10 20))
two :: TwoWidgets
two = Two (WS (SR (Rectangle Red 10 20))) (WS (SR (Rectangle Blue 30 40)))
{-
*TestData> getColor widget
Red
it :: Color
*TestData> setColor widget Blue
WS (SR (Rectangle Blue 10 20))
it :: Widgets
*TestData> getColor two
Red -- <-- 後ろの Blue などは無視される、というのは greplace (once) のせい
it :: Color
*TestData> setColor two Green
Two (WS (SR (Rectangle Green 10 20))) (WS (SR (Rectangle Blue 30 40))) -- <-- 後ろの Blue は無視される、というのは gfind のせい
it :: Two
-}
蛇足ながら付け加えると、setter や getter を定義する方法は一通りだけではありません。"Simple Extensible Records" ではなく、Haskell として普通に定義すれば、「無視される」といった弊害は起こり得ません。あくまで、記述の面倒さとのトレードオフであるとお考えください。最後に Jeff に。Scrap Your Boilerplate の手法を紹介してくれてありがとう。
現状の iconv-0.4 は libiconv が glibc に入っていること前提で作られているので、MacOSX だとこけます。iconv.cabal のコメントに書いてあるように、extra-libraries: iconv を iconv.cabal に追加しましょう。
失敗すると、こうなる: % ghci -package iconv GHCi, version 6.8.2: http://www.haskell.org/ghc/ :? for help Loading package base ... linking ... done. Loading package array-0.1.0.0 ... linking ... done. Loading package bytestring-0.9.0.1 ... linking ... done. ghc-6.8.2: /usr/local/stow/haskell-iconv-0.4/lib/iconv-0.4/ghc-6.8.2/HSiconv-0.4.o: unknown symbol `_libiconv_close' Loading package iconv-0.4 ... linking ... ghc-6.8.2: unable to load package `iconv-0.4' %
dcoutts に直接 IRC で報告したので、iconv-0.4.0.2 以降では直ってるはずである。iconv-0.4.0.1 では、ghc-options: に -fvia-C をつけること。すばやく対応してくれた dcoutts に感謝。
glibc 2.2.x を持っていないプラットホームなら、GNU libiconv を導入しなければならないというのが、問題の本質である。今時、GHC を使う環境で、かつ glibc based でないのは、MacOSX と FreeBSD, NetBSD くらいだろうか。最近の *BSD は触っていないのでよくわからないのだが。
毎週土曜日は、普段は「組み合わせ最適化と多変数多項式環の世界@同志社理工」なのだが、連休中の連日の SWF hack と五月病に負けて、京田辺に行くのは断念(遠いから)。代わりに、近くの蛍ヶ池に遊びにいくことにした。連休前に読んだ oriented matroid のまとめを共同研究者に報告して、続きは 5 月後半に。
午前中は自宅で SWF hack。いや、 Haskell 勉強会#12が 9 時から始まるってのは知ってたんだけど、GIH98 (A Gentle Introduction to Haskell version 98) は 5 年前にもう読んじゃったし、いまさら感があって。最後の 30 分だけ参加して、会場でも SWF 弄んでた。大変申し訳ない。最後の 30 分で出ていた質問二つ(GIH98 第3章):
いけがみの理解:ボトムは停止しない式。まあ気にすんな。Haskell に関する文献を読むときに bottom って単語が出てきたときに思い出せばいい。二番目の質問は、Haskell でプログラムをがんがん書かないと嬉しさがわかんない。だから、現段階で分からなくて当然。ドキュメントを読むより、具体的なプログラムをどんどん書こう。そのうち、Haskell じゃないプログラミング言語でプログラムを書くときに、「あれー、これなんで動かないんだ?」と思ったときに悟るものである。
GIH98 は基本的に、Haskell で一通り遊んでから読むと、「おおー」と思える文書なんである。最初に、この文書を読むよりがんがん Haskell のプログラムを書くことをお勧めする。GHC をインストールし、Yet Another Haskell Tutorial の具体例とか見つつ、作りたいプログラムをがんがん書けばいいと思うぞ。Haskell の数値演算でムキーとなり(たとえば、(2::Int) / 0.5 とかやって、理不尽な怒りが湧き上がってきたら立派な Haskeller である)、haskell-ja メーリングリストで聞いてみるのがいいのではないかな。
これはどの言語でも言えると思うのだが、「作りたいプログラム」がないのに、闇雲にプログラミング言語の勉強をしてもしょうがないと思う。というのは、世の中にいろいろなプログラミング言語があるのは、「作りたいプログラムに向いているプログラミング言語、向かないプログラミング言語」があるからだと思うからである。いけがみは Haskell が好きであるが、全てのプログラムを Haskell で書こうとは思わない。
Scala は興味を持ってはいたけど、前日までインストールしていなかった。仕事の関係で Scala と Java PathFinder を組み合わせればなにか面白そうなことができるんじゃね、と思ってたので前々から興味は持っていた。今回はいい機会だと思ったので参加した次第である。前日にインストールして、いくつかの文献を読んで、いろいろ遊んだ:
インタプリタやコンパイラの遅さに泣けた。PowerBook 1.33GHz PowerPC G4, 1.25GB DDR SDRAM な環境では、"Hello, world" すら 1 秒かかる有様である。これは Scala は悪くなくて Java が悪いのだが。早いマシンを買ったら、Scala ともっと遊ぶと思う。講師の keisuke_n さんの Windows なマシンではすらすら動いていたので、やはり私のマシンが非力であるということだ。
ちなみに、ScalaByExample は非常に良く出来ていた。Haskell にもこういう文書がもっとたくさん増えるべきである。
前日に予習をしすぎたので、勉強会の前半は、話を左から右に流しつつ SWF を弄んでいた。その癖、いらんこと突っ込んだ気がする。大変申し訳ない。
Haskell 大好きっ子から見ると Scala は気持ち悪いことこのうえない言語である(そう思うのはいけがみだけかもしれないが)。でも、Java よりは数段ましであるね。Java 絡みの仕事をして、もう Java なんて知らない、ふんが!(例外処理のバグに悩まされ続けた)と思ったことがあったので、 Scala の例外の取扱い(パターンマッチや implicit parameter のトリック)はありがたかった。
追伸: お菓子の差し入れありがとうございました。おいしくいただきました。
まずは、本の紹介から。
Language selection (17.1 : Criteria)
前略
Professional software engineers should instead base their decisions on relevant technical and economic criteria, such as the following.
- Scale:(略)
- Modularity:(略)
- Reusability:(略)
- Portability:(略)
- Level:(略)
- Reliability:(略)
- Efficiency:(略)
- Readability:(略)
- Data modeling:(略)
- Process modeling:(略)
- Availability of compilers and tools:(略)
- Familiarity:(略)
なんだか「略」ばかりで申し訳ないが、引用の範囲を越えてしまってもしょうがないので。ということで、この本は 12 種類の項目でプログラミング言語の選び方を分類している。5 番めの "Level" ってのが一般的な単語なので、補足すると、この本では、アセンブラは低レベル、いわゆる高級言語と呼ばれている言語は高レベル、と称している。その他の項目については、単語から推測できると思う。興味をお持ちの方は手に取って読んでいただきたい。まあ、こういった観点から、プログラミング言語を分類した上で、自分の好みの言語を決めるという方法はありだと思う。
ただ、この本はちと古い(May 28, 2004)。Amazon.co.jp の読者レビューでは5つ星だが、Amazon.comでは酷評されている。いけがみの感想では、後者の酷評が的を射ているような気がして、ようするに本書の対象読者は、プログラミング言語の研究者ではなくて、普通のプログラマ向けに書かれているように思われる。なので、"Missing information and factual errors", "No really theory!" といったレビューは残念ながら当たっている...
ぐさっ
[それは痛いです - ときどきの雑記帳 i戦士篇より引用]
ええと、木村さん*1を刺すつもりはなかったんだけど。言葉足らずでどうもすみません。
世の中、プログラミング言語が満ちあふれているので (Fortran しか無かった頃から比べれば恵まれた時代である)、言語の仕様をすべて理解しようとする前に、いくつかの観点から自分の必要な言語を決めればいいのではないかな、というのが 前回のエントリで言いたかったことです。もう一つ言いたかったことは、メタプログラミングという技法を取得してしまえば、いくつもの言語仕様(特に syntax sugar)を頭の中に詰め込まなくても大丈夫、ということ。つまり、プログラミング言語を一つ習得すれば、もう一つのプログラミング言語の「プログラム」を生成する「プログラム」を書くことはそんなに難しくないということです。もちろん、対象の言語の複雑さにもよるんだけど、たとえば最近流行りの HogeScript なんかは、簡単な仕様ですので、「手で書く」ことなしにプログラムを生成することができます。Haskell から JavaScript を生成とかね。SQL を吐くプログラムとかも、ある意味メタプログラミングだと言える(と思う)。
プログラミング言語の最適な選び方なんて無いでしょうけど、オブジェクト指向言語と関数型言語の二つのうちどっちを選ぶか、は、わかりやすい指標があるのではないかな。プログラムを構成する部品と機能のどちらが種類が多いか。これで決められると思います。
たとえば、GUI は部品のほうが機能よりも多い。GUI では Window に満ちあふれていて (Window, 警告 Panel, ...)、 Window そのものは plane View + title bar + close button + α(最大化ボタン、最小化ボタンなど)からできているわけです。これは、オブジェクト指向のほうが直感的にプログラムを書くことができる。というのは、オブジェクト指向の継承とインスタンスという概念によるところが大きい(というのがいけがみの理解)。一方、関数型言語で GUI ライブラリを書こうとすると、polymorphic type や Haskell の type class 、phantom type みたいな特殊な技法があったほうが便利で、素直には書きにくいのです。ボタンを押したときのイベント処理も、オブジェクト指向言語では移譲という概念がありますが、関数型言語だと継続とか、動的型キャストとか、いけがみにとっては heavy-weight な機能が必要に思える。
その逆に、テキストエディタのような、部品よりも機能が多いソフトウエアでは、関数型言語が有利です。テキストエディタは、文字列の処理や highlight などの機能がたくさんある一方、GUI のような部品は多くありません。このようなソフトウエアをオブジェクト指向言語で作るとどのようなことになるでしょうか。たとえば、MacOSX のテキストエディタは NSTextView クラスを使っているのだけれど、NSTextView クラスはメソッドの個数が約160個もあるのです。さらに、NSTextView クラスの継承関係は NSTextView : NSText : NSView : NSResponder : NSObject ということになっていて、メソッドの総数はどれだけあるのやら。NSTextView のメソッドの一つは (void *)setBackgroundColor:(NSColor *)aColor ですが、このように、機能一つにメソッドが対応するので、結果的にクラスが大きくなってしまうわけです。当たり前のことですけど。その点、関数型言語でしたら、(Haskell の例にしますが) setBackGroundColor :: (ApplicationStateMonad m, View a) => a -> Color -> m () になるでしょう。これ一つで充分です。Emacs が関数型言語 Lisp を採用したのもそういった視点からだと思います。EmacsLisp が名前空間をめちゃくちゃにしてしまうのは困ったものですが...
現状では、どちらの陣営も得手不得手をわかっていて、お互いの良いところを取り入れようとしています。無名関数を持つオブジェクト指向言語は増えてきましたし、一方で、関数型言語にもオブジェクト指向言語の機能を取り入れる試みがなされています。ごっちゃまぜとしては、先日聞いた Scala とか。
論理型言語は、立ち位置がちょっと特殊で、うまく当てはまる問題に適用すると、どの言語よりも楽に記述できる。Prolog は知っていて損はありません。Curryは……触ってないので評価できない。非決定的な振る舞いとか、どういう場面で使ったらいいんだろうか...モデル記述?
まとめると、プログラミング言語は多くあれども、特徴や文法よりも、まず先に、「そのプログラミング言語がどのようなプログラムを作るのに便利であると主張しているのか」を調べるほうが先だと思うのです。言語の信者は当然「素晴らしさ」を強調しますが(『美しい』とか『principle of least astonishment』とか、そういう指標の無い基準を持ち出してきて笑わせんな)、そんなもん信用せずに、自分でプログラムを書いてみて、自分の好みを確かめるのがいいのではないでしょうか。あと、バッドノウハウは勘弁な。最後に、全く関係ないけど C は最高である。C は素晴らしい。C だけ知っていれば充分である。
以下、気になっている本:
*1 ときどきの雑記帳
はよく読んでいます。有益なリンクが多いので助かります。
周りに vim を使う人が多い。私も vi を使うことがあるが、それは itojun 氏の nvi-m17n を昔使っていたからである。当時(という言葉を使いたくないが)、日本語を読み書きすることのできる高機能エディタは nvi か nemacs しか無かったのである(あ、Unix の話ね。MS-DOSや国産OSのほうが当時は日本語処理がまともだった)。どちらも痛し痒しで、状況に応じて両方を使い分けるしかなかったのだ。WWW なんてなかった頃の話である。
で、今はといえば、もう断然 Emacs である。 anything.el なる便利な仕掛けができてしまったので、私はついこの間、とうとう Emacs21 から Emacs22 に乗り換えた。.emacs を移し変えるにあたって、Emacs Lisp とひたすら戯れたのは言うまでもないことである。人生の中でもっとも楽しいのは .emacs いじりではなかろうか。非生産的だし。W4W (Work for Work).
しかし、 Emacs が洗練されているのなら、vi-clone も洗練されてきているのではないだろうか。食わず嫌いはよくないよな、と思って Vim 7 系列にも手を出してみた。昔取った杵柄で、手がキーバインドを覚えているので普通に使えるのだが、肝心の機能がない。 flymake がない。 flyspell もない。
そこで、vimscript で flymake を作った。vimscript を触るのは初めてだったが、一日で一応満足するものが作れた。 flyspell も同じようにできるのかもしれないが、vim の syntax highlight がかっちりしすぎて融通が効かない。 Emacs みたいにいい加減でいいのに。
Vim global plugin for on-the-fly syntax checker Maintainer: Daisuke IkegamiCopyright 2008 Daisuke IKEGAMI Free distribution, use, and modification permitted under BSD3 DESCRIPTION: Performs on-the-fly syntax checks of the files being edited using the external syntax check tool (usually the compiler). Highlights erroneous lines and displays associated error and warning messages. This plugin is a port of 'flymake-mode' for Emacs. INSTALL: 1. put flymake.vim into your plugin directory (~/.vim/plugin) 2. put some file-type plugins into yours (~/.vim/ftplugin) I've never written a vim plugin and this is the first project. Please hack it and distribute freely under the BSD3 license. HINT: To use flymake.vim (the first version), you have two hooks: 1. autocmd BufWritePost * :call FlyMake(arg1, arg2, arg3) 2. autocmd BufWinLeave * :call FlyMakeCloseWindows() Here, the FlyMake function takes 3 arguments: arg1 : the external command to check syntax; which consists of the format of printf. arg1 must have two '%s': one is for a temporary directory another is for a program file (without path name) arg2 : a pattern match for error message. arg2 must have two groupings: one is a line number for where is error occurred another is a message for error message arg3 : a pattern match for warning message, like arg2. See examples in the ftplugin directory for hacking.
ファイルは固めて flymake-vim-plugin.0.0.1.tar.gz として置いておく。開発は、darcs repository でやってるので、patch 作ったら送ってくれてもいい。でも、たぶん、もう触らないと思う。勝手に fork してください。修正 BSD ライセンスです。
darcs repository: http://dora.koka-in.org/~ikegami/repos/flymake-plugin/ Get the latest (nightly build): % darcs get --partial http://dora.koka-in.org/~ikegami/repos/flymake-plugin/
サンプルとして、 C と Ruby の flymake ができるようになってる。C のほうは、Makefile 書いて、 check-syntax: ターゲットを作ってくれればいい。そこらへんは、Emacs の flymake と同じです。
結論:Emacs の方がずっと楽しい。食わず嫌いじゃなくて、やっぱり好みの問題だった。ただ、これで親から Emacs を取り上げられても vim で生きていけるだけのサバイバル能力は付いたのではなかろうか。
なお、作成に当たって、他のウィンドウにコマンドを送りつける - ボクノスさんのコードが非常に役に立った。これがなかったら、エラーメッセージをどう表示したらいいか途方に暮れるところだった。ありがとう。





皆様、ご指摘感謝致します。
Vi v.s. Emacs の戦いは Usenet の頃からの不毛な争いであるので、これ以上参加したくはありません。どちらも使えたらいいんじゃないのかな。
僕が、なんで VimScript に手を出したかといえば、興味半分、あとはこないだ「作りたいソフトウエアもないのに言語をやたらに勉強してもしょうがないだろ」と言った手前です。「しょうがない」を「ダメ」ととらえる人はネガティブですね〜。なんか暗い過去でもあったのでしょうか。忘れた方がいいと思います。
チナミニ Flymake in GNU Emacs22 (YouTube) こんな風に動きます。
via いなばさんとこ。構成的な証明を Coq とかでやれば、プログラムがでてきます。いや、これは不正確な言明で、正確にはでてくることもあります。構成的数学にはいくつかの variant があるけれども、Coq (というか、Predicative Calculus of (Co)Inductive Construction)の制約は非常に厳しい。
が、その逆は真ではありません。プログラムの性質を証明するとしても、普通の人が使うのは、古典論理であって、手で書いた証明のほとんどは Coq などの「型理論に基づいた定理証明系」には通りません。
一方、ESC/Java (or ESC/Java2) はアノテーションに基づいた検査器で、「もしかしたら、これはバグではありませんか」みたいなことを計算機にお伺いをたてるだけのシステムです。そして、計算機は気まぐれに、「うん、そうだね」とか「お前馬鹿あ?」とか言う。つまり、こいつは Java の型システムを通す前に試してみるもので、lightweight な検証ツールとしての位置づけというのが、私の認識である。なにしろ、ESC/Java2 を使うためには、忍者教室に入らなければいけない[PDF]らしい。ニンニンでござる。 ていうか、マジで「気」を使えとか書いてあるし*1。こいつらは伊賀の末裔か。via KindSoftware のゆかいな図書館。
ここまでは冗談で、ここからは冗談じゃない。プログラムを書く前に、証明を考えるというのはいいスタイルだと思います。でも、証明は時として直感よりも長いのが問題。loop invariant にしろ、普通の頭では出てこない or とても長い。
(私の定義する)テストは、証明じゃなくて、実験なので、そういう意味での lightweight 証明もどきと言える。私に言わせれば、どちらもセンスが必要だ。プログラムの性質を確かめるには人間の直感に頼るしかない。どんなに時間がたってもそうである。ゲーデルの祝福によって、計算機の信頼性は地に堕ちた。
*1 "Secret Ninja Formal Method", Joseph R. Kiniry and Daniel M. Zimmerman, The 15th International Symposium on Formal Methods (FM 2008). Turku, Finland. May, 2008. p 6. "This is our ninja 気 (qi, a kind of "life force" or "spiritual energy")...
この辺の話は、具体例あるいは文献を指し示す必要がありますね。今週いくつか考えました。来週以降も続けるつもりです。プログラマがプログラムを正しく書くとはどういうことなのか。正しさとは何に基づいて決めるのか。それとも、人間界のように絶対の正義などは決まらないのか。といった辺りの考察について。既存の研究は多岐に亘っています。そして、私の知る限り、どれも実用的ではない。実用的な物は金輪際現れないという予測もしている(二つ以上の理由から)。
ぴぴるぴるぴるぴぴるぴ〜♪
蔵書が 1,500冊を越えた。しかもハードカバーばっかり。給料が書籍代に消えている。
初代バーコードリーダーが壊れたのでもう一台買った。ピッピピッピと図書館のように面白がって使ったら、ピーとも言わなくなってしまったのである。給料がガジェットに消えている。
そろそろ PowerBook G4 12" では ghc で開発するのが苦しくなってきた。メモリが多くてマルチコアなマシンが欲しい。でもすでに新しいマシンを買う余裕はないのである。毎週末のイタリアンフルコースはもはや習慣なのである。週末以外は自炊だが、高級食材とか果物とか新鮮なお魚に眼がないので、外食以上にお金がかかる。ごはんとお味噌汁の他に、おかずが二皿、小品を二、三は用意するので当然か。生まれたときから母親がそうしてくれたのでこれはもはや習慣なのである。
そうだ、給料出さないかわりに、毎月 Springer の GTM 新冊買ってあげます、とかそういう仕事ありませんか。ひと月で読んで理解しろっていう。では、代わりに、開発用のマシンを半年ごとに更新してあげます、というのはどうでしょうか。
やっぱり、トロのように働くというのもいいです。段ボールだけあればいいです。相棒のクロと楽しく毒吐く毎日がいいです。
RSS feed を再開しました。RSS の思想を尊重するために全文配信はしません、あしからず。