議論がしたければ罵倒はするな

Java における本質的でない記述がどのように大規模開発に役立つのか - kなんとかの日記にまつわる事項。

kwatch氏のJavaへの恋わずらい

Re: Javaに恋するスクリプト - kなんとかの日記
愛情の反対は無関心だという*1Java使いに並々ならぬ憎悪を持つkwatch氏は相当にJavaを愛していると言えよう。この点についてはJavaに恋するスクリプトで書いたが*2、冗談を書き慣れていない自分としてはイマイチだったと思ったのだが、kwatch氏には

いやー、最近の工作員はレベルが高くて困る。笑い死にするところやったで!

と絶賛いただけた。嬉しい限りである。

間違ったことを言えば正すのはエンジニアの正義

さて、一連のkwatch氏のエントリ、非常に辛辣に突っ込まれるのはkwatch氏自身の論理が破たんしているからだろう。
「怠慢はプログラマの美徳」というけれど - kなんとかの日記にて

Java 屋とスクリプト言語屋の間には、「めんどくさい」と感じるセンスについて超えられない壁が存在している。

本質的でない事柄に関する記述があったときに、スクリプト言語屋は「めんどくさい」と感じ、Java 屋はそれを感じないか、または「これは必要な冗長性だ」と本気で思い込んでいる。

前にとり上げたけど、アクセッサの記述がその典型例。本質的でない記述がずらっと並んでいることに、Java 屋はホントに何も感じないのだそうだ。あれがどれだけ readability を下げているか、まったく分かっていない。

と語っている。この部分は、Java*3に対する侮蔑でしかない。

ここで読解が難しいのは「本質的でない事柄」という部分で、一般的にこの手の罵倒をする人は本質理解しない人が多いことから、kwatch氏もそうであろうという前提のもとに突っ込みが行われた。しかし、kwatch氏は静的言語の良さというものへは一定の理解があると表明している。動的言語とは別種の価値観があることはコメントにて認めているところである。
この「本質的でない事柄」にはkwatch氏自身が短い ≠ 分かりやすい - kなんとかの日記で釈明を要した。しかし、曖昧な用語に基づいての議論*4では今後も誤解は絶えないだろう。罵倒しながらモノを指摘しても、まともなことは言っていまいと先入観を持たれることの一例である*5
なんかさー - kなんとかの日記では予想以上の反応に戸惑っている様子もある。無差別でいわれのない侮蔑をすれば文句を言われるのは当たり前なのだが*6

kwatch氏は「本質的でない事柄」という表現をダブルスタンダードで使っている。
ブックマークコメントへのコメント - kなんとかの日記に顕著だが、「本質的でない冗長」なんて指摘を挙げた数点のみ。そのピンポイントの部分が「本質的でない冗長」で、型定義などの表現はkwatch氏も認める「本質的な冗長」となるが、

Javaが不必要に冗長なのは確かで、それらは大規模開発におけるメリットにはならない。その辺を反省して最近はSyntax Sugarっぽい機能が多く入ってきているってことでいいじゃん。

いきなり的確にまとめられてしまいました。Javaのコードとは対照的な、なんたる簡潔さ。

のブックマークコメントの「Javaが不必要に冗長」がアクセッサだけを指しているとは思えない。動的言語派が感情的に嫌う型定義の冗長と思われる。だが、ここで「本質的」をダブルスタンダードに使いkwatch氏への賛成意見のように捻じ曲げている。

そして、本質的冗長が大規模開発に便利という意見に対しては「で、本質的でない冗長な記述は大規模開発にどう役立つと思いますか?」と議論をすり替えている。これは、kwatch氏の主張である「Java屋はアクセッサのような冗長に不便を感じないか必要な冗長だと信じている」を演出するために故意にやっていることと思われる。

とにかく、Java屋への侮蔑は議論の役には立たないので置いとくとして、当初、kwatch氏が挙げたJavaに対する提言は

  • フィールドアクセスに対してプロパティ構文がなく冗長な記述を強要される点が問題だ
  • System.out.print()はstatic import を使うことで print() と書けるようにすべき
  • FileReaderで文字コードを指定できない。そしてこの問題に誰も言及してない

といったところ。

一部をもって全体視するという論理の飛躍

変な侮蔑をせずにこの点を淡々と指摘したのであれば、kwatch氏は議論のための労力をもっと削減でき、もっと本質的な議論を行えたかもしれない。

Javaの一部の欠点をあげつらって、Java屋はこれらを問題にしない、と侮蔑するのは議論の妨げにかなるまい。Javaという複雑で精緻な言語にはいくらかの欠点も当然含まる。欠点があることをもってユーザが許容していることにはならない。論理の飛躍である。

さて、こんな苦言を言うだけではあまりに芸がないのでJava屋は問題点に疑問を持たないといういわれなき汚名を晴らしておくとしよう。

Java屋待望のプロパティ。当然無関心などではない

Java7ではプロパティ構文が導入される見込みである。この仕様策定はJSR-295で行われている。
The Java Community Process(SM) Program - JSRs: Java Specification Requests - detail JSR# 295
さて、ここで日付を見るとExpert Group FormationのStartが09 May, 2006と書かれている。つまり、Expert Groupが作られた2006年5月以前から、この問題に対してそれ以前からの議論があったことの証拠である。

C#Javaを参考にして作られている*7ため、当初からJavaのclassのフィールドの扱いの問題の議論を踏まえて、プロパティ構文を取り入れている。C#登場が2002年だが、当然ながらC#のプロパティ構文の策定のもととなっているJavaのフィールドアクセスに対する議論がそれに先行する。

publicフィールドというものの問題を洗い出せたという点で、Javaがなしたエンジニアリングとしての功績は大きいだろう*8。フィールドアクセスに対しては操作に対して何かコードを差し挟むような箇所(アスペクト指向でいうジョインポイント*9)が存在しない。この問題に対し、C#のプロパティ構文は一定の解を与えたと言える。

さて、JSR-295の2006年からすると4年の歳月が間にあることになる。この時間は何に使われたのだろうか?それは、現行のJavaコンパイラの仕様を既存のJavaコードと折衷して使えるような方法論の議論に用いられた。
既存のgetter,setterとの整合性をどのように取るかという難点があったわけである*10。言語の先頭に盛り込めたC#に比べ、対応までに時間を要したのはそうした互換性維持の事情があるのである。これはJavaジェネリクスを盛り込む際も同様であった*11

static import で print()と書くには

どこかしらのクラスにstaticメソッドとしてprint()を用意することで確かにprint()とだけ書くことで記述できるようにはなる。
そして、そもそもコマンドラインバッチ処理でも書くのでなければ、本質的なコードとして標準出力に出力など行わないから、あんまり使う機会がないんじゃないの、という点はkwatch氏のblogのコメント欄で議論があった通り。

FileReader の問題か…。前世紀のことなんで忘れていたよ

短い ≠ 分かりやすい - kなんとかの日記

FileReaderに文字コードを指定できないことに誰も言及してないんだけど、それってやっぱり誰も疑問に思ってないってことだよね?

といっているが、Java屋は当然そのAPIの欠陥は知っているし問題にしている。それも前世紀に。

Bug ID: JDK-4022676 java.io.FileReader/Writer: Want to change encoding converterが18-DEC-1996
Bug ID: JDK-4152393 FileReader - new constructor to specify encodingが25-JUN-1998
久々にこのAPIの欠陥もあったなぁと思いだした。

そういえばコレ、未だに放置されているのか。なんでなんだろう?
java.nioパッケージを使えってことなんだろうか。
I/O負荷が高い場所ならFileChannelとCharsetEncoderで処理すべきなんだとは思うが。

*1:マザーテレサの言葉である。憎悪は愛情と紙一重

*2:私の技術系のblog.向こうは表現が硬い。猫を被っているともいう。文章は常体で書く方が楽だ

*3:Javaを主要な言語として用いる人全般を指す言葉という認識でよいと思われる

*4:「本質的でない事柄」というのはかなりトリッキーな言論の道具足りうる。つまり、後になって本質的だと理解したときに、それは本質的ではない事柄じゃないから否定していないよ、という知見の後出しじゃんけんが可能となる。

*5:ゆえに、議論が本気でしたいならば、感情による見誤りがないように工夫する方が得策だ。特に相手が議論慣れしていない場合は、論理的な正しさを納得させるために感情への配慮が必要となることが多い

*6:Javaについて書かないとアクセスが伸びないという旨の発言もしていたから、Javaへの罵倒は客寄せのための可能性は否定できない。しかし全体的な表現からは単にJavaに恨みを持っているだけのように思える

*7:MSは当初はJavaを改造してWindows開発に用いようとしたがJavaコミュニティに反発されたため独自のC#を作るはめになった。その残骸がJ++やJ#である

*8:つまるところ、プロパティがないというのはJavaの失敗だった。大規模開発向けOOP言語という新境地開拓に際してJavaは驚くほどの先見性を見せたが、このあたりは数少ない予見の失敗と言える

*9:フィールドとメソッドを統合してアスペクト指向AOPをするような言語設計はできないものだろうか

*10:該当フィールドを単純に参照した状態から、getter,setterで何かの処理を行うように修正できるようにするためには、フィールドアクセスではなく暗黙にgetter,setterを呼ぶような仕込みがされている必要がある。これは、メソッド利用側のバイトコードが、フィールド参照の場合とメソッドコールでは違っているため。フィールドアクセスに対して何かしら処理をジャックするような仕掛けにすると流石にVMの互換性が維持できないように思う。

*11:Javaジェネリクスのあの複雑な仕様をJava1.4までと接合したのは神業としか言いようがない。