DT日記

家を離れた自宅警備員の日記

なぜ「現代仮名遣い」で書かないのか

別に使ふ理由がないから、現代的ではないから、この假名遣を決めた連中が気にくはないから。以上。

ではあまりに不親切なので、ウィキペディアでも読んでろよ、といふ気持ちをぐっとこらへていまの自分の思ひについて書くことにする。

(その前に補足。この記事では「かなづかひ」を「假名遣」と漢字で書く。この字は常用漢字表にある新字体「仮」と同じだが、僕はこの字が大嫌ひなので可能な限り避ける。この「假」の右側は「暇」とまったく同じで、音読みは同じ「カ」である。ここで注意してほしい。「暇」は常用漢字表に掲載されてゐて、「假」よりも画数が多いにもかかはらず、「日反」のような略字になってゐない!)

はじめに「現代仮名遣い」について。これは1986年に公布された内閣告示であり、昭和61年内閣訓令第1号によって各行政機関においては,これを現代の国語を書き表すための仮名遺いのよりどころとするものとするとされた。これ以降、この表記法が「日本のお役所における正書法」となってゐる。ここで、この内閣訓令が効力を持つのはお役所、それも、国の行政機関に対してのみであることに気をつけてほしい。

この「訓令」といふことば、何かで聴きおぼえがあるかもしれない。それはおそらく、ローマ字の「訓令式」ではないかと思ふ。この訓令式ローマ字は小学校の教科書に掲載されてゐるれっきとしたローマ字の表記法であって、これも1954年の内閣訓令による、いまも有効な正書法だ。加へて、ISO 3602といふ国際標準にもなってゐる。

訓令式に対して現代の日本で主流のローマ字表記はヘボン式と呼ばれる方式の亜種である(ここでローマ字とは、アルファベットのことではなく、日本語をラテンアルファベットの26文字を使って書き表すことを指す)。訓令式ヘボン式の差異はいくつもあるが、たとへば「自社製府地図(じしゃ/せい/ふ/ちず)」といふことばがあったとして、これは訓令式では「Zisyaseihutizu」、一般的なヘボン式では「Jishaseifuchizu」となる(このそもそもそんなことばはないのだが…)

自分の名前をアルファベットで書くとき、ヘボンだ訓令だと気にすることが、どれだけあるのか。現状では各自が拘りを持って、好き勝手にローマ字表記を決めてゐる、といふのが実際のところではないかと思ふ。またはキーボードの日本語入力などはフリーダムの極みで、単に個人の習慣やキーの押しやすさで好きなものが選ばれる。ここに政府による強制は存在しない。

ここで假名遣の話に戻すが、現代仮名遣いが政府によってよりどころを示された守るべきルールであり、これに背くことが非難されるべきことなのだとすると、同格の内閣告示・内閣訓令による訓令式ローマ字も同様に遵守すべき基準なのではないか。このどちらかのみを責めたてるのは二重規範である*1

現代仮名遣いは一般の社会生活において現代の国語を書き表すための仮名遣いのよりどころとして公示されたものではあるが、前書きにこの仮名遣いは,科学,技術,芸術その他の各種専門分野や個々人の表記にまで及ぼそうとするものではないともある。つまり私的な文章や技術的な記事を書くにあたって、この假名遣を盾にして非難される筋合はなく、「読みにくい」は単なる個人の感想の域を出ない。

ここまでで「なぜ現代仮名遣いで書かないのか」の理由のひとつ「別に使ふ理由がないから」を説明した。

……とはいっても、現代仮名遣いで書かれてゐない文章が読みにくいと感じるのも道理ではある。出版物・道路標識・そのほか身の周りにある日本語文は、ほとんどすべて現代仮名遣いと新字体で書かれてゐる。

歴史的假名遣は中学・高校の国語科で扱はれるので義務教育を修了した人ならば、「ゐ」「ゑ」などが使用された現代文を読む準備があるはずなのだが*2、実際にはその単元の後には目にする機会がなくなるので、そのまま「読みにくい」といふ認識が残ってしまふことは十分理解できる。

ウェブなどでは現代仮名遣いで書かれない文章*3の使用者に対して、まるで踏み絵のように「お前は本当に仕事でもそんな書き方をするのか?」と批難されることがある。

私は基本的に業務で作成する文書、連絡、あるいは出版社などから原稿料を頂戴して寄稿する記事などには、躊躇なく正格の現代仮名遣いで書く。上記のようなことを一々説明し説き伏せる理由など特にないのと、假名遣に拘ることなどよりも大切なことはいくつもあるからだ。

http://hitode909.hatenablog.com/entry/2013/09/09/130736

この記事を書いたのは id:hitote909 の書いたbookmarkletがきっかけなのだけれど*4、この記事には批難はなく、読みにくいといふ感想と要望が書かれてゐて、それを表明されることは望ましいことではある(むしろはてブにそのような感想がいくつもつくことを期待した)。

ただ純粋に疑問なのだけれど、ライセンスの選択を恐れる必要はありませんは、假名遣を直したところで本当に読みやすくなるのか?

そもそも日本語としてこなれてゐない箇所、翻訳が極めて怪しい箇所、一般的ではない訳語を説明なく残してある箇所が、まだいくつもある。そんな不親切な文書が、本当に読みやすいのか? 「わかりやすい」とコメントしてる人はみな流し読みをして、わかった気になってるのではないか? そんなことを考へると、おそろしくなる。

読みにくい日本語に対してブックマークレットでパッチを当てることは素晴らしい対処法だと思ふし、僕がその立場だったら同じことをするかもしれない。しかし、ひらがなと漢字の数文字を置換する小手先の手段よりは、原文かライセンス本文を各自で読みにいった方がずっと生産的なのではないかと感じる。

それに関して有益な情報なので多くの人が読めるほうが役立つと思うについて。その理窟を持ち出すならば、英語でChooseALicense.comの解説記事を書くのが、もっと多くのひとにライセンスの理解をひろめるベストな手段だったのではないか*5。実際には、想定を上回る人数があの記事を読みにくいながらも読んでるらしいので、私としてはなほさら現代仮名遣いで書く理由がなくなった。

最後に辯明をしておきたいのだけれど、あのdiffについては単純にtypoですね。僕はいつもSKKを使って書いてゐて、現代仮名遣いで書いてから変換するような面倒な手間は経てゐない*6

あとふたつの理由

  • 現代的ではないから
  • この假名遣を決めた連中が気にくはないから

ぐぐれ。

*1:公平のために、政府によるローマ字表記の指針としてはもう一つ「外務省ヘボン式」と呼ばれる方式も存在することを紹介しておく。実際に道路標識や案内板のローマ字表記はこちらに従って書かれることが多い。しかしこれは「フェ」を「Fue」と表記する表記法である。……ほんとにこんなものを支持できるのか?

*2:これは、理系の立場でいふと「高校出てるなら微分も確率も計算できるはず」みたいな話になるのではないか…?

*3:これには、歴史的假名遣に加へて、ギャル文字など、かなを別の記号に置換したもの、ぁぃぅぇぉゃゅょなど小書きにするものなどを含む

*4:それはさておき、これのお蔭でHatena::Letといふサービスを知れたので、とても感謝したい

*5:ただし私は英語が書けない

*6:そもそもSKKは基本的に假名遣にまったく依存しない

「就職しました」エントリ

(この記事を読んでる人はなんとなく察してるよね、の前提で) 就職しました

僕がこの日記を始めた 2010年7月22日 の記事とか読むと、ほんとにイシキタカイ系プログラミングのガチ初心者、といふか大学4年なのにろくに就活もしてないておくれ系大学生から、よく頑張った気がします。

なんでこの会社選んだのよ

直接的な動機としては YAPC::Asia で中の人たちと話して「遊びにおいでよ」→「面接しようよ」みたいな流れでした。副次的な理由としては、一利用者として、熱心にでこそないものの頻繁に利用してたサービスであって、イラスト以外にもやる夫スレや 2ちゃんねるの SS など二次・三次創作を積極的に楽しんでゐる者としては、その成功例に非常に興味がありました (←面接で言った)。

まさか通るとは露にも思ってなかった (ほんとに記念受験のつもりだった) ので半ば青天の霹靂だったのですが、ろくな成果物もなく、よく採用する気にけふんけふん。いまの技術力の不足はまったく自覚してるので、成長を見込んで雇ってもらったのはありがたいことでなので、これからも 趣味の範囲で たゆまぬ努力が必要ですね。

いつから働いてたのよ

2012年11月16日からです(キリッ

前歴ほぼニートでいままでの開発実績とかろくなのがないので、とりあへず新しい Web サービスを Ruby on Rails で構築しようかといふ感じでした。僕は幸ひにも Ruby 大好きっ子だったので、勉強しながら Rails で楽しく開発することができました。「MVC? 名前は聞いたことありますが」「あたい知ってるよ、MySQL ってでーたべーすなんでしょ」程度の理解でモデルを作り始めたので、さくっと作ることはできましたが後から機能要件が増えたときに設計変更めんどくさいことに。

12月移行はマレーシアからきたデザイナーと組んで仕事を進めることになり、僕がはじめに作ったデザインはいかにもな Bootstrap Bootstrap 的なサイトだったのですが、彼が参加した途端に Bootstrap をカスタマイズした上ですごく意欲的な意匠に仕上げてくれました。 デザイナーのちからって すげー! ちなみに彼の専門は Web ではなかったらしい……。

ただこのサイトは公開する領域が限られてますので、みなさまの目に触れる機会は、もしかすると遠い将来にあるかないか、と言ったところです。ちらっとでも見せられるといいなあ。まだローンチはされてないのですが、もし発見しましたら、おそらくログインは不可能ですがログイン前のページは見られます。それでも十分かっこいいです。

お見せできる仕事としては、PHP と社内の API の勉強がてらに作った、すごーく小さいサービスが、近日中に公開される見込みです。タブンネ。別に大した工夫もなく、べたーっとした実装なのですが。お見せすると言っておきながら、きっと僕の作った部分は目に見えません。ふしぎふしぎ。

これから何の仕事をするのよ

わぁいPHP あかりPHP大好き

割とまじめに言っておくと言語に貴賤はないですし、ちゃんと勉強すれば僕にもいける感じだと思ひます。たぶん… きっと……!

働いてから思ったこと

すごく国際的といふか多国籍といふか、そんな趣きのある会社です。英語が公用語ってほどではないのですが、英語が話せないとコミュニケーションに差支へのあることもありますので、ちゃんと勉強したいところ……!

さういへば、いまのところ自分と同年代の人と働いた経験が皆無だったので、いつもすぐ近くで同年代の人とコミュニケーションがとれる環境はすごく楽しいですね……!

なんか「英語で会話してる横でわかったようなわかってないような顔をしてにやにやしてる」のが僕なので、会話に参加できるときっと楽しいです。

これからやりたいこと

  • 幸せになるために .emacs をちゃんとする
  • 幸せになるために会社の近くに引っ越す
  • 幸せになるために茸を捨てて庭に帰る
  • 幸せになるために Android を捨てる
  • 幸せになるためにサーバを一台組む
  • 幸せになるために SICP をちゃんと読めた暁には餘勢を駆って TaPL まで読んでみたい (死亡フラグ)

がんばります。僕は幸せを手にします。おちんぎんが出るまで幸せは遠い感じもしますが。あと PHP と英語。

自宅警備してたときに考へてたこと

自分には何ができて、何ができないのかをよく把握しよう努めて、それを補ふためにがんばらうとしてました。思考法としてはともかく、それを理想通りに実践できてたかと考へると、おそらくできてないです。

全てのハックはももんがに通ず

ももんが Advent Calendar 2012の四日めです… ヾ(〃><)ノ゙

コンピュータの得意な方は、コンピュータともももんがと関係の無い事を、コンピュータの得意でない方は、ももんがとは関係無くコンピュータに関する事を書きましょう。ももんがと関係の無い事は、要するにももんがに関する事です。

ももんが Advent Calendar 2012 - c4se記:さっちゃんですよ☆

なるほど、僕はさっちゃんにしてやられたといふわけだ。コンピュータが得意でない僕は ももんがとは関係無くコンピュータに関する事を書 くしかないじゃないないか。全ての道はローマに通ずるのだ。

だが困った。コンピュータに詳しくない僕に、いったい何が書けるといふのだ。コンピュータに詳しい者はハッカーと呼ばれると、コトワザにもあるではないか。ふむ。ハッカーについて書けばコンピュータについても書いたことになるのではないのか。

ハッカーとは何か? 「テンサイ級・ヤバイ級にコンピュータに詳しいワザマエを持つタツジン」をハッカーと呼ぶのだ、と主張する人も居る。しかしそれは違ふのではないか? お前は ブラッディ・マンデイ を読んでないのかよ*1

曰く、主人公のタカギ・フジマルはテンサイ級の能力を持つ凄腕ハッカー『ファルコン』であるといふ。彼はどんなコンピュータにでも難無く侵入できるスキルを持つといふ。では 侵入とは何なのか?

まづ初めに、目の前にある機械(それはUNIXマシンかもしれないし、携帯IRC端末であるかもしれないが)は、単なる計算機に過ぎないといふことに留意する必要があるだらう。つまりは電卓の化け物だ。それは計算能力的には副作用のない、入力に対して演算を行って一定の出力を返す純粋な機械でしかないのだ*2

計算機への入力はUNIXマシンの前で坐禅を組み精神統一してキーボードを叩くべし、と心に決めてゐる者もあるかもしれないが、実際にはLANケーブルを通じて遠隔地にあるUNIXマシンにIRCログインすることもできる。しかしハッカーは、あなたに代って遠隔UNIXマシンにログインしてしまふこともあるのだ。それが「侵入」である。インガオホー!

では、いかにハッカーはあなたのUNIXマシンに侵入するのか? ひとつにわかりやすいものとして、あなたのログイン名とパスワードを盗み出すことだ。そのハッカーとは、あなたの兄弟であるかもしれないし、夜には熱く前後する仲の恋人であるのかもしれないのだ。サツバツハッカーのワザマエにしてニンジャめいたこの技術を、人はソーシャル・エンジニアリング・ジツと呼ぶ。

次に、セキュリティホールを突きユーザの権限を奪ってしまふ方法だ。IRCの仲間がメッセージを通じて、便利なソフトウェアを送ってきてくれるかもしれない。ブッダシット! それはハッカーの狡猾な罠なのだ。あなたのUNIXマシンで起動されたプログラムはデータをハッカーの元に送り、あまつさへUNIXマシンの上であなたのキーボード入力を、そしてパスワードの入力を盗み続けるかもしれない。備えよう。

以上、平安時代の哲人剣士、ミヤモト・マサシのハック戦術書よりの抜萃。石にも仏性があるが如く、ももんがは斯くにも Hackable な概念なのである。

マッポーの世である現在ではユーザとパスワードのみで認証するのはあまりにもウカツなことであり、そのようなUNIXマシンを設計した担当者=サンは上司にセプクを強要されるかもしれない。少くとも指を数本ケジメされることは覚悟することだ。

*1:たっどさんは読んでないって言ってました

*2:現実にはハードウェアの環境や劣化破損、またはその他の物理的影響によって「常に」一定とはいかないが、この場では措いておく

おめが Advent Calendar 2012 3日目

こんにちはこんにちは。ぞぬさんです。2012年も、指折り数へるところまできてしまひましたか。 おめが Advent Calendar 2012。本日が3日めです。前日は @おめが Advent Calendar 2012 2日目 - あんパン でした。

おめがといへばあのこにくたらしい Schemer で、奴が東大生だといふ噂が流れたときはうっかり信じてしまひましたが、中学生軍団のオフ会に空気を読まず押し掛けた体験が幻覚でなければ、やはり相応の中学生でした。イケメンだけどな。

このおめがといふしゃもじは僕の100倍くらゐプログラミングに詳しく(誇張なし。たぶん)、 技術欲男 といふなかなかためになる blog を書いてゐて、さらにためになる記事をフィーチャーしてみようとも思ったのだけれど、めんどくさくて飽きた。 各自で読んどけ

最近ぐぐったら辿りついた Gauche「rlwrapとGauche-readlineの違い」 - 技術欲男 で知った rlwrap は便利すぎて惚れた。

どうやら記録によれば、どこからか RT されてきたらしいこのついーとを読んで僕はおめがをフォローしたんじゃないかって感じがしますね。僕の方からは最初から Lisper だと思って近付いたといふことか……。

どうしてこうなった… と思ったけど、 別のソース をあたってみると僕もそんなに頻繁には「垢消せ」とは喚いてないですね><

さーて、次回の垢消し Advent Calendar 2012の担当は… もう一回 @ ?

最後に

クソが*1

*1:って書いておかないと締まらないんじゃないですかね…

近況のお知らせ

どうも、童貞です。自宅警備業を離職しました*1。いや、アルバイトなんですけど。

新しい職場は [ピー] クシブ株式会社です。いとお先輩の居る会社*2ですね。いろいろと縁がありまして。

2011年6月から2012年6月までは学生や自宅警備業の傍らでクロストラスト株式会社にアルバイトとしてお世話になってました。 id:nakayoshix さんがいらした会社です。クラウド的な仕事をしてた気がします。こちらではちょっとしたツールみたいなものは Python で書いてました。 Linux スーパー初心者だった僕がスーパー初級者くらゐにはステップアップできる機会をいただきまして、たいへんありがたいことでした。 SSL のご用命がございましたらクロストラストまでどうぞ。うさみさんの名前を出したらちょっとくらゐは安くしてくれるかもしれません。してくれないかもしれません。

2012年6月から2012年7月は専業自宅警備任務に従事してました。いま思ふとあんまり身になってなかった気がしますね><

2012年8月は東京をぷらぷらと放浪したりしてました。某キャンプの最後に遊びに行ったりもしました。案外生きてけるもんでしたが、最後は風邪をひいて命からがら帰ってきた感じです>< 無計劃窮ってまして、自宅近くのバス停まで来たときには財布の中身と預金残高の合計が1000円を切ってたのでおそろしいことです……。似た経験は3度めですね>< *3

2012年の9月と10月は東京に引っ越してきまして、上野の方で生活してました。某海鮮丼の会社さんからお仕事を紹介いただきまして、こちらでは Ruby 的な、 Rails 的なお仕事に従事して居りました。短い間ではありましたが、たいへん勉強になりました。

……といふわけで2012年の11月は頭から自宅警備業に従事する傍らで積み本崩し業とやる夫スレタブ消化 *4 に専念してたのでした。

実際のところは、こちらに雇っていただけるか否かと怯え暮らしてたのですが><

るびー初心者歴の長い童貞ですが、がんばって働きますのでコンゴトモヨロシク… Asakusa.rb とかに来れば僕と握手できます! たぶん!

コマンドラインで乱数

どうも、自宅警備員です。

コマンドラインからささっと乱数を生成したいときにべんりかもしれないシェル函数Rubyワンライナーを書いたので宣伝しませう*1。シェルは Bourne shell っぽいやつなら sh でも bash でも dash でも ash でも、そして zsh でも大丈夫ですね。

使ひ方は、一番お手軽には $HOME/.bashrc とか $HOME/.zshrc の最後の方に書き足してやるのが良いですね。ほんとは . / source コマンドで読み込んでみるのが良い気がします。

rand

えっと、一往ここにもコード載せますが、 Gist の方が最新である可能性が高いですね。

要するに RubySecureRandom を叩いてるだけなので、Ruby のドキュメントとシェルスクリプト本文を読むのがてっとりばやい気がします!

rand () {
    a=$1
    b=$2
    type=random_string
    len=10
    post="cat -"
    chop="sed -e s/.$//g"
    case `echo $a | tr '[:upper:]' '[:lower:]'` in
        "")  a=$type; b=$len ;;
        ba*) a=base64        ;;
        f*)  a=random_float  ;;
        h*)  a=hex           ;;
        b*)  a=random_bytes  ;;
        u*)  a=uuid          ;;
        s*)  a=random_string ;;
        n*)  a=random_number ;;
    esac
    if test "$a" = uuid
        then type=uuid; len=''
    elif test "$a" = random_float
        then type=random_number; len=0
    elif test "$a" = random_string -o "$b" = ""
    then
        type=hex
        test ! "$b" && l=$a
        if test "$b" -gt 0 2>/dev/null
            then l=$b
        fi
        len=`expr $l / 2`
        mod=`expr $l % 2`
        if test "$l" = 1
            then post="$chop"; len=1
        elif test $mod = 1
            then post="$chop"; len=`expr $len + 1`
        fi
    elif test "$a" -a "$b"
        then type=$a; len=$b
    elif test "$a"
        then len=$a
    fi
    ruby -rsecurerandom -e "puts SecureRandom.${type} ${len}" | eval $post
}

どうせ一回は ruby を起動するんだから全部 Ruby で書きゃ良かったんじゃないかって気もなきにしもあらずなのですが、単純なものならシェルスクリプトもお手軽に書けて大好きです。

rand とだけ叩いてやれば10文字のそれっぽい文字列が出てきますし、 rand 20 と叩いてやれば20文字で出てきます。 rand float とか rand f とか書いてやれば、1未満の浮動小数点数が出てきます。 rand byte 10 とかやると10バイトのバイト列が出てきます! その他はコード読んでください!

*1:ただし最後にアップデートしたのは21日前…

【DT閑話】童貞プログラマが函数型言語(とラムダ計算)を理解してみる【初心者向け解説】

単なる函数オブジェクトをラムダと呼んだら怒られる気もするけど…*1 まあ小噺程度に僕も話してみたいです><

函数プログラミング言語に実用性はあるか? といふ問題についてはちゅーんさんが書いてくれてるので、プログラミング初心者なりにラムダ計算に焦点を当てて考察していけたらなー、と思ひます。

初心者が初心者向けに語ることは良いことと悪いことがそれぞれたくさんあって、初心者丸出しのこの blog でもいつも悩みながら書いてます。初心者が解説を書くことで自分の中にあるもやもやとした理解をまとめ上げることができる、そして熟練者が失ってしまひかねない初学者ならではも躓きを捉へられるといふのが良い点。そして悪い点としては、正確でない表現を別の初心者が間に受けてしまって、伝言ゲームで間違った認識を得ること。そんなわけで、僕はできる限り正確に把握したいと調べながら記事を書くことにしてます。

元記事さんを読んで気になるところとして、用語の不正確さがあります。「ラムダ式」と呼ばれてるものは、「ラムダ計算 (λ-calculus)」と、プログラミング言語の「ラムダ式」と呼ばれることもある機能について混同してます。プログラミングの文脈では「ラムダ式」は、後述するような函数を扱った機能のことを指すことが多いように感じられます

函数とは何か

細かい定義は ja.Wp - 関数 (数学) を読んでください、ってことでいまは話を進めることにします。つまりは、  f(x) = 2x + 3 としたときに、  f(5) = 2 \times 5 + 3 = 13 になるものが函数です。俗に「数学的な函数」と呼ばれるもので、われわれが中学校の数学の時間に習ったシンプルな形がこれです。

この函数は、たとへば C言語でも十分に表現することができます。

int f (int x) {
    return 2 * x + 3;
}

JavaScript でも、ほぼ同様に書くことができるので、以下は JavaScript をベースに書くことにします。

var f = function (x) {
    return 2 * x + 3;
}

JavaScript を動かすには Google ChromeJavaScript コンソールを利用するのがいちばん簡単です。

λとは何か

λ計算 とは、アロンゾ・チャーチの考案した計算体系です。なぜ λ なのかは諸説あるのでこの場では拘りませんが、はじめ ^ と表現したのが誤植により Λ (λの大文字) になり、やがて小文字の λ になったのだ、との話が一般的なようです。つまり、 λ には「函数の記号」以上の意味はありません。

さて、さきほどの函数の定義を λ記法 と呼ばれる流儀の書きかたで表すと、次のようになります。

 f = \lambda x.\, 2 \times x + 3

また、  g(x, y)  = y / x であれば  g = \lambda x.\, \lambda y.\, y / x となります。

この記法では、  f(5)  f\, 5 と、  g(3, 2)  g\,3\,2 と書くことができます。難しい話はできるだけ抜きに行きたいのですが、「函数 f に引数 5 を渡して戻り値を得る」ことを「 f5適用する」と表します。

なぜこのように、一般的な数学の教科書などと別の記法をとるのかといふと、  f(x) とだけ書いたときに 函数 f の定義なのか、 fx に適用(Cなどのプログラミング言語では函数呼び出し)した結果なのかの曖昧さを排除するため、とのことです*2

実は純粋な λ計算λ式 では数字や計算式をこのように書くことができなくて、チャーチエンコーディングなどの方法で自然数を表現してやる必要があるのですが、ここではやはり気にせず次に進んでいくことにします。

JavaScript と λ

はい、ここからが「ラムダ式」の話になります。

プログラミング言語でいふところの ラムダ式C#, Python, Ruby, C++11 など、多くの言語に導入されてゐます*3。そして、我らが JavaScriptfunction 式 も、ほかならぬこれらと同様のものです。

さきほど紹介した JavaScript のコードで function f (x) { ... } と書かずに var f = function (x) { ... } ; と書いたので、もしかすると違和感を覚えたかもしれません。

JavaScript には混乱しやすいことに、 function 式function 文 があります。 式と文 の区別は各自で気の向いたときに確認していただきたいのですが、ひとつ重要なことがあります。

function f (x) { ... }函数定義では、この函数に必ず f と名前が付きます。ところが var f = function (x) { ... } ; では、 函数に名前がありません函数を作ったあとで、変数 f に代入してます。 var a = 1, b = "str"; とか書くのと同じ気軽さですね。そして、どちらの方法で函数を定義しても、まったく同じように f(5) と書けば使用することができます。(これは JavaScript の驚くべき特徴です!*4 )

このような「名前のない函数」のことを指して、 無名函数 と呼ぶことがあります。通常はこの無名函数のことを指して ラムダ式 と呼ばれます。また注目すべき点として、函数の中で函数を定義することができます。これは C言語しか知らない方には想像もしなかったことかもしれませんし、いままでラムダ式をご存じでなかった方にもやはり驚くべきことかもしれません。僕は驚いた

ラムダ式と高階函数

「引数 x をとり、3倍した数を返す函数 f を定義せよ」「引数 h, x, y, z をとり、x, y, z, をそれぞれ h で適用した数を合計した数を返す函数 g を定義せよ」

こんな問題について考察してみます。数学の授業っぽい表記だと、こんな感じですね。

 f(x) = 3x
 g(h,x,y,z) = h(x) + h(y) + h(z)

λ表記で表すと、こうなります。

 f = \lambda x.\, 3 \times x
 g = \lambda h.\, \lambda x.\, \lambda y.\, \lambda z.\, (h\,x) + (h\,y) + (h\,z)

じゃあこれを C言語で書いてみようか… となると別の函数を定義しなければいけなかったり、函数ポインタの出番になったりちょっと面倒なのですが、 JavaScript ではいつでもどこでも、函数の中だろうと外だろうと、そのまま書けば大丈夫です*5

var f = function(x){ return 3 * x; };
var g = function(h, x, y, z){ return h(x) + h(y) + h(z); };
console.log( g(f, 1, 2, 3) ); //=> 18

このように、変数として函数を受け取る函数のことを 高階函数 と呼びます。

ひとつ注目して欲しいところがあります。 h, x, y, z と平然と並んでますね。x, y, z は、当然「数」であることが期待されます*6h函数オブジェクトです。 JavaScript函数は、文字列や整数と同列に並ぶ、値の一種に過ぎません。これも C言語ではないことです*7

一般化して考へる(mapとreduce)

さて、上記の JavaScript のコードですが、プログラムとして見ると柔軟性にかけるところがあります。

  • 引数が 3つにしか対応してない
    • 例: 2つのとき、5つのとき、 70のとき、 10000のとき…
  • 「合計」にしか対応してない
    • 「全ての数を掛けたい」場合

引数を 2つにするのに var g2 = function(h, x, y){ return h(x) + h(y); }; と修正するのはたやすいことです。 5つにするために var g5 = function(h, x, y, z, a, b){ return h(x) + h(y) + h(z) + h(a) + h(b); }; とするのもまた簡単なことです。

しかし、 70個の数に対応するためにこのような改造を施すことは、呆れるほどの手間がかかります。まして、 10000個の数に対応するために同じ調子でやってたのでは、正気で居ることの方が困難です。

といふことで、上記の需要を満たすために、もっと柔軟なコードに変更してみませう。

  • 数をいくつでもとれるように配列で受けとる
  • Array#map メソッドを使用して、配列全体に函数を適用する
  • Array#reduce メソッドを使用して、配列を畳み込む
var f = function(x){ return 3 * x; };
var h = function(acc, n){ return acc * n; };
var gd = function(h,i,a){ return a.map(h).reduce(i); };
gd(f, h, [1, 2, 3, 4, 5]);

できましたー。

λ計算JavaScript

…あれ、プログラミングできなくね?と思ったあなたは正解。

ラムダ式の機能そのものには、プログラミングに必要な基本的な機能がほとんどありません。
真偽値もないし、比較級(if文)もないし、画面への出力もない(戻り値だけ)ので、ラムダ式だけでプログラミングはできません。

【SE閑話】文系プログラマが関数型言語(とラムダ式)を理解してみる【初心者向け解説】 | EHACO.net

この一節については、まったくもって擁護不能な、真っ赤な大嘘といふほかありません。このどちらも、 λ計算で表現可能 です。といふことは JavaScript の function 式でも書くことができます。

今回は、条件分岐と真偽値を函数で表現することを考察してみませう。

// これはふつうの JavaScript
var a = true;
var b = false;
(a) ? "foo" : "bar";
(b) ? "foo" : "bar";

// こっちは函数バージョン
// var IF = function(COND, THEN, ELSE) { return ...; };
// var TRUE = function(...) { return ... ; };
// var FALSE = function(...) { return ...; };
var A = TRUE;
var B = FALSE;
IF(A, "foo", "bar"); // => "foo"
IF(B, "foo", "bar"); // => "bar"

雛形はこんな感じになりますよね。

IF 函数は条件、真の場合の値、偽の場合の値、の三つの引数を受け取ります。そして条件が TRUE だったときに真の場合の値、FALSE だったときに偽の場合の値を返すようにしたいです。

単純に書いてみると IF 函数の定義は次のようになります。

var IF = function(COND, THEN, ELSE) { return COND(THEN, ELSE); };

これに適切な TRUEFALSE を定義してやれば、函数だけで条件分岐が動きます。まだ λ で条件分岐と真偽値を表現できたことが信じられない……?

って向きの方のために、λ式で同じことを書いてみませう。

 true = \lambda x.\, \lambda y.\, x
 false = \lambda x.\, \lambda y.\, y
 if = \lambda x.\, \lambda y.\, \lambda z.\, x\,y\,z

このλ項は上の JavaScript のコードと同じ構造ですので、 λ計算で条件分岐を実現できた ことになりますね。

簡潔な説明では済まなくなるので今回は避けますが、 λ式再帰、つまりはループを表現することもできます*8。そのような性質と併せて、 λ計算は「チューリング完全」だといふことが證明されてゐます*9

チューリング完全」とは「チューリング機械と同じ計算能力を持つ」ことを意味します。チューリング機械とはアラン・チューリングの考案した想像上の計算機械で、入力から答を求めることができる問題であればどんな問題でもプログラミングして、有限時間で計算して答を出すことができます。

たいていのプログラミング言語チューリング完全性をがありますし、 JavaScript も、 C言語も、 RubyPython も、もちろんチューリング完全です。そして、 λ計算チューリングマシンと等価な計算能力を持つことは、1930-40年代には既に ja.Wp - チャーチ=チューリングのテーゼ として知られてました。

ここで記事は唐突に結び

ほかにも触れたいことはたくさんあるのですが、ここまでで λ計算の基礎の基礎と、現実のプログラミング言語λ計算の関連については触れられたかと思ひます。僕自身、ラムダといふ言葉を2011年の1月に知人宅で読んだ β簡約! λカ娘 といふ同人誌(ペーパー)で知り、その後半年ほど忘れたままだったところを前職の同僚から F# といふものを知り、実際に手を動かして基礎について学ぶことができたのでした。それまでは「ML? メイリングリストのこと? あたい SGML のことならわかるよ!」と行った次第で、プログラミング言語については無知も甚しいものでした。

そんなこんなで勉強は怠っちゃいけないなー、と思ひつつ日常生活はたてこんでしまふもので、大した勉強ができてるわけでもありません。が、そんな中で何冊か読みかけの本はあるので、参考文献としてこれらを紹介して記事の結びとしたいと思ひます。

これは重要なことですが、僕ははてなダイアリープラスの会員ではないので、この記事経由で本をお求めになっても僕には一円も入りません……。

計算論入門―計算の基本原理理解のために

計算論入門―計算の基本原理理解のために

素数夜曲―女王陛下のLISP

素数夜曲―女王陛下のLISP

チューリングを読む コンピュータサイエンスの金字塔を楽しもう

チューリングを読む コンピュータサイエンスの金字塔を楽しもう

どれもたいへんおもしろい、ためになる本なのですが、いづれも通読できてないので罪悪感に苛まれますね。

*1:Twitter / myuon_myon: クロージャを使って無名函数を定義!ってよく見るんですけど、無名函数を定義することとラムダ式が書けることは全く別物なのでは

*2:2011 荒井省三/いげ太『実践F# 関数型プログラミング入門』技術評論社 より

*3:Groovy などの言語では クロージャ とも呼ばれますが、同じものです。ただし クロージャ といふ用語に触れると解説がさらに辛くなるので、いまはスルーします

*4:Ruby では天地がひっくり返ってもできません。 PythonC# では、できます

*5:厳密には、この JavaScript は上のλ式を正確に写したものではありません。もし興味がありましたら F#がすげーかっこいい話(カリー化) - DT戦記(zonu_exeの日記) をお読みください

*6:ただし JavaScript の性質上、これだけのコードでは整数か浮動小数点数かは特定できませんし、文字列などが入ってきても実行時まで不正かどうかはわかりません

*7:C言語で変数に入るのは函数オブジェクトそのものではなく、あくまで函数へのポインタです

*8:このあたり興味のある方は、きしださんの 2009-04-09 おとうさん、ぼくにもYコンビネータがわかりましたよ! - きしだのはてな をお読みいただくと良いと思ひます

*9:チャールズ・ペゾルドチューリングを読む コンピュータサイエンスの金字塔を楽しもう』などで、わかりやすく解説されてる気がします