Hatena::ブログ(Diary)

プログラミング言語を作る日記

2016-08-03 シン・ゴジラ観た

[](ネタバレ注意)シン・ゴジラを観たのだけど、いろいろ気になって気になって

シン・ゴジラ、公開2日目7/30にIMAXで観てきました。

Twitterでもはてな界隈でもかなり話題になっていて、なんか書くなら今しかないか、ということで書きますよ。

私は、エヴァも観てるしトップをねらえに至っては特に5話6話なんてだいたいセリフ暗記してるような人間なので、シン・ゴジラも、ああ庵野監督の映画だね、ということでおおむね楽しめましたが、あまり一般受けする映画ではないのではないかなあと思った。なにせ視点のほとんどは現場でなくて会議室ですし、おっさんの顔のアップばかりで、なんというか、暑苦しい。

ただ、私が観てて気になったのはそんなことではなくて。

以下、ネタバレ注意!!

ゴジラには、通常兵器が効いたわけですよ。大型貫通弾MOP IIで背中の外皮に穴を開けて出血させるところまではできていた。もちろん、この攻撃のあと、ゴジラのビーム攻撃で手痛い反撃を食うわけですが、このビーム攻撃にはエネルギー制限があって、そう連続して撃ち続けられるわけではないことは劇中で語られている。だったら、血液凝固剤作戦の序盤で実際にやったように、在来線爆弾とかで連続攻撃を加えてビームを使いきらせた状態でMOPを大量にぶち込んでいたら、何も核を使わなくても殺せたのではないか。いや、それで殺せるかはともかく、あんなの街中に2週間も放置するか?

こういうことが気になってくると、普通なら「まあ娯楽映画だしな」で流せることも気になってしょうがない。血液凝固剤、あんなものを口からホースで流し込んだとして、普通、飲むか? 酔いつぶれた酔っ払いに水を飲ませようったってそううまく飲んでくれるもんじゃない。微量でも喉を通れば殺せるようなものならともかく、製造が間に合わなくてフランス経由で核使用を1日待ってもらったぐらいだから、製造した量の大部分(劇中では70%と言ってたっけ)が飲み込まれなければいけないんだろう。到底可能とは思えないし、だいたい敵は口からビームを吐くのに口元に悠長にクレーン車集合させてどうしようって感じだし(実際ビーム吐かれてたし)、だいたい口を閉じただけで終わりではないか(実際口閉じてたし)。

それにあれ、一貫して「血液凝固剤」と呼ばれてたと思うんだけど、なんで最後は凍るんだよ。

そもそもの話として、ゴジラは何しに東京に来たんだっけ。別に目的はなく迷い込んだだけかもしれないけど、途中で冷却のために海に戻って、それからまた上陸してきたんだから何かしらの目的があるはずだよね。たとえば、原発の核燃料でも食いに来たのなら、うまいこと撒き餌して海に戻ってもらう、という方法も取れたのではないか。そういうことを劇中でだれも言いださないのも不思議であった(海に戻った理由は気にしたくせに)。

こういうことが気になってくると、なかなか素直に楽しめないものです。

なお、公開2日目7/30 18:00〜の回(109シネマズ名古屋IMAX)では、上映後、特に拍手は上がりませんでした。エヴァ破の時には拍手があった*1から別に名古屋人がノリが悪いというわけではないと思いますが。

さて、最近のブログ記事では、何かしらかこつけて拙著「Webサーバを作りながら学ぶ 基礎からのWebアプリケーション開発入門」の宣伝をしてきたのですが、今回ばかりはかこつけるネタも見当たらないけど宣伝はするよ!

よろしくお願いいたします。

*1:Qの時は困惑したようなどよめきだけであった。

2016-07-17 まだたとえ話で消耗してるの?

[]まだたとえ話で消耗してるの?

常に話題には乗り遅れる私ですが、ちょっと前、「変数を箱にたとえる」ことについて議論がありました。

プログラミングの変数を教えるときの「箱の説明」の是非について。 - Togetterまとめ

実のところこの話題は昔から何度も出てきた話で、「何周目だ」という話ではあります。私自身、「センス・オブ・プログラミング!」に書いたことがあります。

変数は「箱」か? - the code to rock

そして、上記の「the code to rock」の文章にもありますが、「箱モデル」の代わりとしてよく提唱されるのが「名札モデル」です。

こういうことは文章で書いてもわかりにくいので、それぞれ、絵にしてみましょうか。

箱モデル

■「a = 5;」という代入

f:id:kmaebashi:20160717224325p:image

「aという名前が付いた箱に、5という値を格納する」プログラミング言語の入門書によく出てくる説明ですね。

■それに続いて、「b = a;」という代入

ここで、以下のような、「aの箱から値を取り出してbの箱に入れる」というイメージをしてしまうと、

f:id:kmaebashi:20160717225406p:image

「この代入のあと、aの箱は空っぽになってしまうのでは?」という疑問が出るかもしれません。これが箱モデルの(欠点といえば)欠点です。

しかし、それ以前の話として、「5が代入されたaという変数は、5という値が書けるところなら基本どこにでも書け*1、5と同じ意味を持つ」、という原則からすれば、「b = a;」という代入は、結局「b = 5;」と変わりません。

f:id:kmaebashi:20160717225405p:image

こう考えれば、そう難しい話でもないのではないでしょうか。

名札モデル

さて、名札モデルです。名札というと、小学生が胸につけてるアレのイメージでしょうか。だとすると絵にするとこうでしょうか。

f:id:kmaebashi:20160717230444p:image

しかし、名札モデルの人のイメージでは、どうも名札モデルが重要なのは参照型の場合であるようなので、

ここではこんな、「紐付きラベル」で描いてみます。

f:id:kmaebashi:20160717230443p:image

■「a = 5;」という代入

f:id:kmaebashi:20160717231136p:image

「5というオブジェクトに、aという名札を付ける」と言えばよいでしょうか。

■それに続いて、「b = a;」という代入

f:id:kmaebashi:20160717230443p:image

「aという名札の先にあるオブジェクトに、bの名札を付ける」でしょうか。

しかし、先ほどの「5が代入されたaという変数は、5という値が書けるところなら基本どこにでも書け、5と同じ意味を持つ」という原則からすれば、「b = a;」は「b = 5;」と等しいので、以下のようにならないでしょうか。

f:id:kmaebashi:20160717231819p:image

いやそんなの前者に決まってるだろう何因縁つけてんだ、と思う人は、それに続いて、「c = 5;」という代入を行った際には、こちらをイメージするのでしょうか。

f:id:kmaebashi:20160717232122p:image

それともこちらでしょうか。

f:id:kmaebashi:20160717232121p:image

箱モデルなら悩む余地はありません。こうです。

f:id:kmaebashi:20160717224406p:image

初心者が最初に扱うのは基本型だ

実のところこんなことは、クラスみたいな参照型を使うときには疑問の余地なく決まることです。Pointクラスがあったとして、「p1 = p2;」なら、p1とp2は同じオブジェクトを指しますし、「p1 = new Point(10, 20); p2 = new Point(10, 20);」なら、(たとえ座標が同じでも)違うオブジェクトを指します。

しかし、プログラミング言語の入門で、最初に例に出すのは、intみたいな基本型でしょ? 違いますか?

まず、少なくともJavaなら、intはプリミティブであり、参照型ではないので、箱モデルの方が直接的でしょう。

Rubyなら……「Rubyはあらゆるものがオブジェクトだ!」という声が聞こえてきそうですが、Fixnumの実装云々を持ち出すまでもなく、FixnumもBignumもimmutableなので、実質、値型と同様に使えます。

  1. 初心者に、参照をイメージするような「名札モデル」を教え、
  2. その上で、整数型はimmutableだからこうなる、

と教えるよりは、最初は「箱モデル」で教えるほうがなんぼか無難ではないでしょうか(別に断言はしませんが)。

箱モデルで教えていて、次に参照を教えるときはどうするかって? 「参照値が入る箱」でよいのでは。

f:id:kmaebashi:20160717235208p:image

何が言いたいのかというと

この手の「変数は箱か名札か」的な話は、変数の挙動について「既にわかっている人達」が、「どっちが自然か」ということでケンケンゴウゴウするもので、実際にその議論が初心者のためになっているかというと、全然なっていない気がするんですよ。

経験的に、ですが、たとえば私と一緒に会社の新人研修を受けた人達(のうち本当の初心者)の中で、「変数」がわからなくて数日レベルで悩んでいる人はいませんでした。たぶん最初の説明は「箱モデル」で受けたと思うのですが、それでそこが突破できるなら別にそれでいい。それに、実のところ初心者にとって「あらゆるものがオブジェクトだ!」みたいな「統一性」は、言語を学ぶ際にはそれほど大きな助けにならない。あまりにもばらばらなのは考えものですが、整数型なんてのは、最初は値として考えておいて、「あらゆるものがオブジェクト」言語なら、後から「ああこれもオブジェクトなんだ」と理解(感動?)しても特に問題にならないと思います。ていうか、たいていの人は、この順序で理解したんじゃないかなあ。

そして、学習を進めるうちには、「変数は、スタックとかstaticとか、あるいはオブジェクトのメンバとして保持され、オブジェクトそのものはヒープに確保される」「オブジェクトを指し示す値が参照である」「参照値は、(実装により間接参照になってたりするかもしれないが)まあ要するにアドレスのことだ」ぐらいには、物理的な実装に近いところまで理解できるでしょうし、その知識は無駄にはならないでしょう(メンタルモデルとして有用ですし、パフォーマンス等を考えるならなおのこと)。

「センス・オブ・プログラミング」に以下のように書いたのは、そういう意味です。

しかし――変数が「箱」であるのか「メモ用紙」であるのか、そんなくだらない話を真剣に議論してもしょうがないでしょう。たとえ話は所詮たとえ話です。「変数」が実際にどのようなものかを知りたければ、結局、「メモリ」の話を抜きにすることはできないと思います。

というわけで、プログラミングする上では、ある程度低レベルの概念を知る必要が常にある、という意味で、宣伝につなげますよ。

「変数」を知りたければ結局「メモリ」を知らなければいけないように、WebアプリケーションプログラマならHTTPを知らなければいけません。そこでこの本ですよ。

ApacheのようなWebサーバを、自分で作ることにより、Webアプリケーション開発を真に納得して行うことができるようになります。

もちろん、最初に「箱モデル」で変数を学ぶことが悪いことではないように、最初に、HTTPをわかりもせずフレームワークを使ってWebアプリを作ってみることは悪いことではありません。しかし、いずれにしても、どうせすぐ必要になる知識です。「Webサーバを作るなんてマニアックな!」と思わず、読んでみてくださいませ。

余談

なぜ日本人はオブジェクト指向をなかなか理解できないのか?:新刊ピックアップ|技術評論社

くうだらない、じいつにくうだらない。

てかさ、

オブジェクト指向では,「データ」を「オブジェクト」として扱いますので,「変数」もまた「オブジェクト」と同じものだと言えます(※2)。

これからオブジェクト指向言語を学ぶ方は,ここで紹介した「変数とはオブジェクトのこと」というイメージを胸に,学習に臨んでみてください。

「変数とはオブジェクトのこと」って、はっきり間違いだろうよ。

*1:「3a」と書いたからといって「35」(さんじゅうご)にはならないので、この原則にも説明は必要ですが……

2016-07-05 インタープリタは「翻訳」しない

[][]インタープリタは「翻訳」しない

404: Not Found - Qiita

中間言語方式 Java・.Net

(バイトコードなど)中間言語に変換してから、JavaVMなどがネイティブコードで実行する。

インタープリタ言語 PHP/Ruby/JavaScriptなど

1行ずつ、コンパイルしながら実行する。

コンパイラ(コンパイル作業)すら必要ないようにした。

■ 最終的にマシン語(機械語)に翻訳されます

……うへえ。今時こんな文章を読むことになろうとは。

当たり前ですが、JVMを含め、インタプリタネイティブコードへの変換は行いません*1

今から文章書くにはもう眠いので、昔、拙著「センス・オブ・プログラミング」に書いた文章を貼っておきます。

センス・オブ・プログラミング p.83の補足『インタープリタは「翻訳」しない』より

インタープリタは「翻訳」しない』

どうも、入門書によっては、コンパイラインタープリタについて、以下のような説明をしているものがあるようです。

コンパイラは、ソースプログラム全体を一気に機械語に翻訳して、オブジェクトプログラムを作成する。

それに対し、インタープリタは、事前に一括翻訳するのではなく、実行と同時に、1行づつ部分的に機械語に翻訳する。

はっきりさせましょう。この説明は、完璧に間違っています

インタープリタでは、ソース(または中間形式)を、インタープリタというプログラム自身が解釈しながら実行します。インタープリタが、ソースから機械語への変換を行なうことはありません。

最近のJava仮想マシンは、バイトコード機械語に変換する機能を持っています。しかしこれは「JIT(Just In Time)コンパイラ・・・・・」と呼ばれる技術であり、この部分を指してインタープリタとは呼びません。

この間違いは、私が8ビットパソコンのBASICで遊んでいた頃(もう20年近くも前になりますか---遠い目)にはあちこちで見掛けたものですが、さすがに最近は絶滅したものだと思っていました。

しかし、本書の執筆のため、本屋で各種入門書を見てみると、最近の入門書にも、上のような嘘が書かれているものがちょくちょくあるようです。これが驚異のべすとせらあ?

――困ったものです。

ここで、「これが驚異のべすとせらあ?」と書いている本は、「プログラムはなぜ動くのか 知っておきたいプログラミングの基礎知識」(矢沢久雄著)です*2。当時、「これが驚異のベストセラー!」というアオリが帯に書かれていたのです……

上記の補足を書いた「センス・オブ・プログラミング」が出版されたのが、2004年ですよもう12年も前ですよ。

だいたいプログラマーなら、インタプリタのひとつやふたつみんな作るものだろうに一度でも作ったらこんな勘違いすぐに解消されるだろうに。

はい宣伝。プログラミング言語の作り方に興味が出てきた方はこちら。

関係ないけど今一番売れてほしいのはこの本なので、これも宣伝しておきます。

Webアプリケーション開発を学ぶのに、「Webサーバを作る」という低レベルなところから攻めていこうという本です。低レベルなところから攻めるという点で、プログラミング言語の動く仕組みとかを考えるのと、関係なくはないですね。

ところで、Qittaにはトラックバックとかは飛ばせないようですが、元記事書いた方には、いったいどの本を読んで、インタプリタが「1行ずつ、コンパイルしながら実行する」という(誤った)知識を得たのか、ぜひ教えていただきたいところです。

*1:もちろんJITのような技術はありますが、これはJust In Time コンパイラであって、この部分を指してインタプリタとは呼びません。

*2:私が確認したのは1版7刷 (1刷ともに2001年

2016-06-07 「基礎からのWeb〜」発売されました!

[]「本当の基礎からのWebアプリケーション入門――Webサーバを作ってみよう」書籍版が発売されました!!

連日宣伝ですみませんが、以前よりWebで公開していた「本当の基礎からのWebアプリケーション入門――Webサーバを作ってみよう」の書籍版である「Webサーバを作りながら学ぶ 基礎からのWebアプリケーション開発入門」本日6/7に発売されました。

f:id:kmaebashi:20160604223850j:image

技術評論社さんの紹介ページはこちら。

Webサーバを作りながら学ぶ 基礎からのWebアプリケーション開発入門:書籍案内|技術評論社

私のWebサイトにおける紹介ページはこちら。

http://kmaebashi.com/webserver/index.html

amazonはこちらから。

もともとこの本の構想は、記録をたどると2007年2月20日に私のWebサイトの掲示板の書き込みの頃にはあったようです。10年近く前か……

http://kmaebashi.com/bbs/list.php?boardid=kmaebashibbs&from=880&range=1

とはいえ、CGIはWebアプリケーションの基本ですから、(Perlでもよいので)一度は 
作っておくべきものかとは思います。最近は、PHPやらJSPやらStrutsやら、果ては 
ASP.NET等いろいろ便利な道具があって、もちろんそれはそれでよいのですが、 
結局下回りを知らないと困ることもありますから。 

「本当の基礎からのWebアプリケーション入門 ―Webサーバを作ってみよう―」 

なんての、誰か書いてくれませんかね… 

その後、このブログでも言及したりしていますが、

「本当の基礎からのWebアプリケーション入門――Webサーバを作ってみよう」って誰か書いてくれませんかね - プログラミング言語を作る日記

1章から5章までは、ほぼ上記の記事にメモした構成のままで、このたび本になりました。

つまり私にしてみれば、10年近く前からずっと、世の中にはこういう本が必要だろうと思い続けていた内容です。

その分、内容が古いように見えるかもしれません。確かに、本書の内容の大半は、15年以上前の本に書いてあってもおかしくありません。というより、15年くらい前にこんな本があったら、私自身がもっと実感を持ってWebアプリケーションを理解できたのに、という思いが本書の出発点です。

ドッグイヤーのIT業界、そんな古臭いことなら今から勉強しなくても、と思う人もいるかもしれませんが、むしろドッグイヤーで新しい技術が次々と現れて消えるこの業界で、15年前から現在まで有効だった内容であれば、今後もそれなりに長期にわたって有効であり続ける可能性が高い、と言うこともできるでしょう。なにしろ、HTTP/2になったって、HTTPのGETやPOSTやリクエストヘッダやレスンポスヘッダが変わったわけでもありません。

本書の対象読者は、Webアプリケーションをこれから作ろうとしている人、または既にWebアプリケーションを作っているがいまひとつ何がどうなっているのか納得できない人です。「もう自分でコードを書くことはめったにないが、お客様との仕様調整は行うアラフォーのおじさん」も、できもしない仕様をお客様と握ってきて現場のプログラマがひどい目にあうことを避けるため、ぜひ読んでいただきたいと思います。

2016-06-06 「基礎からのWeb〜」書籍版だけの内容

[]「Webサーバを作りながら学ぶ 基礎からのWebアプリケーション開発入門」書籍版だけの内容

「Webサーバを作りながら学ぶ 基礎からのWebアプリケーション開発入門」いよいよ明日が発売日です(書店によってはもう置いてあるのかもしれませんが)。

技術評論社さんの紹介ページはこちら。

Webサーバを作りながら学ぶ 基礎からのWebアプリケーション開発入門:書籍案内|技術評論社

私のWebサイトにおける紹介ページはこちら。

http://kmaebashi.com/webserver/index.html

amazonはこちらから。

さて、書籍「Webサーバを作りながら学ぶ 基礎からのWebアプリケーション開発入門」は、元々Webで公開していた「本当の基礎からのWebアプリケーション入門――Webサーバを作ってみよう」に対しいろいろ加筆修正していますが、6章、7章は完全に書き下ろしです。

サポートページにも目次を載せていますが、こんなことを書いています。

OSI参照モデルは普通にネットワーク関連の文章を読んだりする際にはどうやったって避けられない知識です。プロキシサーバSSL(TLS)、認証などの話もそうでしょう。この手の知識についてはあちこちで解説されていますが、本書では、あくまで自分で試してみることを念頭に、プロキシサーバとして試しにsquidインストールしてみたりとか、BASIC認証やDigest認証についてリクエストとレスポンスを追いかけたりとかしています。

「6.6 クライアントサイドの技術」では、JavaScriptでDOMをいじる例として、「1行追加」ボタンで行を足せる入力フォームを作ってみたり、

f:id:kmaebashi:20160606222346p:image

Ajaxの例として、郵便番号から住所*1を自動入力する機能を作ったりしています。

f:id:kmaebashi:20160606222347p:image

こういう機能は、割とあちこちのWebページで実現されている便利な機能であるにもかかわらず、いざ自分でゼロから作れと言われるとちょっと怯む、という人も多いのではないでしょうか。本書では、最低限のサンプルプログラムでこれを実現しています。もちろんjQueryなんぞ使っていません。いやさ最近はてブでもjQuery不要論(You Don't Need jQuery - Qiita)が話題になったりしましたが、jQueryがいくら便利でも結局DOMエレメントを使わずに済むわけじゃなし、だばだばと水漏れする抽象化でしかない以上、まずはjQueryのようなライブラリを使わずに作ってみる必要があるかと思います。ソースを見るとわかりますが、さして難しくもないですし。

セキュリティについては、下手に書くとあちこちからマサカリ飛んできそうで怖いのですが、今時のWebアプリケーションプログラマにとって必須であることは間違いないので、よく問題になる点について触れています*2

さて7章。multipart/form-dataを解釈してファイルをアップロードしたりとか*3、画像を動的に生成して昔ながらのアクセスカウンタを作ったりとか、CSVファイルのダウンロード機能を作ったりとかしています。

こういうことは、ちゃんと「わかった」ベテランプログラマの人にとっては、なんでもないことなのかもしれません。

しかし、Webでぐぐって見つけた断片的なコードをコピペしていても、なかなか体系的には身に着かない知識でもあります。

本書を、最初から通し読みすることで、コピペするにしてもちゃんと「わかって」コピペできるようになります。本書はそういう狙いで書きました。

*1:住所データベースなど持っていないので、ふたつの郵便番号にしか対応しないなんちゃってプログラムですが、Ajaxの例としては十分でしょう

*2CSRFについて書くべきだったか、と思ったりもしていますが……

*3:そういえばほんの1年くらい前だったか、Androidでmultipart/form-dataを使ってアップロードする側のコードをガリガリ書いた記憶があります。こういう汎用的な機能は何でもライブラリが解決してくれる、と思っていても、意外とあちこちに落とし穴があいているものです。