はてなキーワード: リテラルとは
色々縁が合って学部名に情報が入る大学3―4年生の面倒を見てるんだけど,驚くほど英語が出来ない
一応授業である程度習ったらしいけどコーディング能力は低い.具体的にはFizzBuzz問題解けないくらい
しかしそれ以上に問題があるのは英語と基本的な知識で,例えば次の2つのエラー文がどちらからも何が問題なのかわからない
NameError: name 'Fizz' is not defined
IndentationError: unexpected indent
defineもIndentも単語として知らない以前に,変数と文字列リテラルやインデントを理解できてないからエラーコードでググっても解決できないんだよね
同じ理由でDeepL等で訳しても無理.ただ,ChatGPTとかに説明してもらうとわかるらしい
5人中2人がこのレベルなんだけど,本人の希望通りの業界に就職したら0から叩きこまれるんだろうなって思って子牛を見ている気分になったよ
割りとマジだよねと思う出来事をふと思い出したので書いてみる。
といっても後輩が俺の思ってもいないところでつまづいて、それに俺がカルチャーショックを受けたというだけの話。
問題の話なんだけど、とある有名サービスのJSON APIを叩いて呼び出し結果を手元のオブジェクトにマッピングするというただそれだけのコードを書くというもの。
普通に考えて一日もしないで出来ると思うような代物だけど、三日以上悩んで彼はそれでも出来なかった。
{ ..., "count": 10000000000000000000000000000000000000, ...}
という感じで多倍長整数がリテラルとして書かれているのを前提として受け取る仕様だった。
JavaScriptの通常の整数と違って、JSONの整数リテラルは仕様上大きさの制限の記載がないので、上のようなのも合法。
で、彼の使ってたプログラミング言語のオブジェクト から JSONの変換ライブラリが、多倍長整数を文字列("")としてシリアライズするような仕様なことがわかって、彼は行き詰まった。
そこで何をやり始めたかというと、JSONの整数がそのまま1000000000000000みたいにシリアライズされるライブラリ探し始めたんだけど、それは見つからないまま。
というわけで「増田さん、詰まってるんですけど……」と言われて助け舟出すことになったはいいものの、彼のコード見るとJSONの抽象構文木クラスがそのまま使えるようだった。
なので、
String serialiaze(Ast.JsValue value) { return switch(value) { case Ast.JsNull nullValue-> "null"; case Ast.JsInt bigIntValue -> bigIntValue.toString(); case Ast.JsArray arrayValue -> arrayValue.stream().map(v -> serialize(v)).collect(Collectors.joining(", ", "[", "]")); // 他のJSONの木についても同様に処理 default -> throw new RuntimeException("cannot reach") }; }
1時間しない内にこんな感じのコード(言語はJavaじゃなかったけど、だいたいこういう感じ)を書いて無事問題解決。細かいタイポとかあるかもだけど、日記では確認してないのでそれはおいといて)。
結局、JSONの形が期待と違って、しかも既存のAPIじゃいいのがなかったのに延々API探すことしか出来なかったのが問題解決できなかった原因だけど、このくらいのは割りとちょこちょこある。
きっと、それから一週間放置しても問題解決できなかっただろうし、どうも同じチームの同僚も問題を解決できなかったようだった。
最近、APIは叩けるけど、そこでトラブルとどうにもならなくエンジニアにちょくちょく遭遇するんだけど、やっぱりもうちょっと基礎出来てないと駄目だなと思った出来事だった。
ドイツとナチスが絡むと必ず出てくる言説で、ここでもやはり大量に見られる。
はてなブックマーク:欅坂46も立憲民主党議員も…「ナチスをもてあそぶ日本人」にドイツ人がドン引きする理由 | 文春オンライン
https://b.hatena.ne.jp/entry/s/bunshun.jp/articles/-/50047
なんかズルいなあ。現ドイツはナチスとは別で第2次大戦は全てナチスが悪いっと言ってる感じ。昭和天皇は責任から逃げなかった。
コイツの祖父や祖祖父の世代がナチスを指示したからナチスがああなった。ナチスに全てをおっ被せているのは否定できないだろうよ。
ナチスこそが全ての原因で邪悪で悪魔で国民はその被害者という形にしないと成り立たないのがドイツ。想起するあらゆるものは排除っていうスタンスは、他のジェノサイド等の件では全く見られない特殊なもの
戦争責任をナチスに押し付けたからこそ、「我々一般のドイツ人とは違う狂信的な集団」として極端にタブー視する必要があるんじゃないかと穿った見方をしてしまう。
そりゃ「ナチス党を絶対悪においてドイツ人が悪い訳では無い」というスタンスだからな。だから謝罪も賠償もしない。外から見ると「ナチス⊂ドイツ」だけどな。
この言説の出元はズバリ西尾幹二である。といっても西尾が「西ドイツ(当時)はナチスを切断処理して反省を拒否している」と言ったのではない。
前年に西ドイツ大統領に選出されたヴァイツゼッカーは1985年連邦議会で後に有名となる演説を行った。西ドイツ大統領は米国や米国の政体をモデルにした韓国のようなものと違い、首相の上に立つが実権力は少なく元首のような役職だ。
この演説は「過去に目を閉ざす者は結局のところ現在にも盲目となる」の節が有名で、要するにナチスの蛮行の責任を戦後のドイツ人は引き受けねばならない、蛮行に手を貸していないと言い張るのは許されないとの内容だ。
この演説を岩波の『世界』が取り上げて掲載し、後には数百円のリーフレットも発売した。「戦争への反省のモデルケース」としての評価であるのは言うまでもない。
因みに『世界』は敗戦後に相当な影響力を持った論壇誌だったが、経済成長や全共闘の進歩派攻撃などによって影響力は下がっていた。だがこのヴァイツゼッカー演説の掲載は反響を呼び、リベラル人士に挙って引用されるようになった。
ところで複数人で編集されるwikipediaのヴァイツゼッカーの項は、演説内容が「悪いのはヒトラーとナチズムであり、ドイツ国民・民族も被害者である」だったとの節と、「罪の有無、老幼いずれを問わず、われわれ全員が過去を引き受けねばなりません。」との引用文が併置されるという面白い状態になっている。
この盛り上がりに対し、ドイツ文学者の西尾幹二が文藝春秋社『諸君』で批判を加えた。
「演説文章をよく読んでみると、ドイツ国民の直接の罪は回避されている」「ナチスの罪はドイツ国民個人に無い事が前提となっている」という内容だ。
そして「日本の戦争犯罪と違ってナチスの罪は人道に対する罪であって国家そのものが犯罪国家で責任の取りようが無い」。
責任が取れない種類のものを引き受けると言っているのだから欺瞞だ、という事だ。
これは文章解釈であり、悪意を持てば文章は逆の意味に解釈する事も出来る。(「ナチスの手口に学べ」は反語だ、など)
それは言語的堕落だが、西尾がそう評価されなかったのはニーチェ思想を専攻とする文学者の実績があった為だ。例えば中央公論の『世界の名著』シリーズのニーチェの編纂、解説は西尾である。実態が無い〇〇総研勤務や過去論文が紀要に全くない文学研究者やバイト以外職歴不明の動画投稿者ばかりで構成される昨今の保守論壇と当時は全く違った。
それ故、西尾の批判は「無邪気な戦争責任論への懐疑」として評価されていた。ヴァイツゼッカー演説のリテラル(文字通り)の内容は、云わば民族原罪論のようなものなので、それに対してニーチェ的視点から欺瞞を突きつけたくなるのは無理もない。
但し、
一民族全体に罪がある、もしくは無実である、というようなことはありません。罪といい無実といい、集団的ではなく個人的なものであります。
の様な一文を持って「集団が免責されてる」という辺りはニーチェもへったくりもなく単に低質なデマだ。あとで触れるがこれをやり始めたのは小林よしのりだ。この文章は「当時にも残虐行為にタッチしていない人間は居たがその罪は国民は免れない」という意味だからだ。
だから西尾を哲学的文脈で好意的に評価する時、こういう所は無視して、ユダヤ・キリスト教の道徳に類似した欺瞞を指摘した、と評することが多い。
だが西尾はニーチェ専攻にも拘らずにルサンチマンに駆動させられやすく、「切断処理を表明する演説」論者にのせられてそう言っちゃうのよな。で、論壇が経歴不明なバカや宗教右翼で埋まってパージされると冷静さを取り戻す、というのをずっと繰り返している。
90年代前半までとその後の保守論壇というのは質が全く違って、例えば引用したブコメで言うと、
とかは今は普通に見られるが、当時ならあり得ない。何故といって日本は交戦相手の米英仏豪に謝って賠償金を払っただろうか?勿論していない。
フィリピン以外の賠償金は全てチャラにして貰った。特に米国は自国の民間企業に対しても対日債務は諦めるようにした。ドイツも同じスキームだ。
そして日本はそれら交戦相手の連合国にチャラにしてもらう代わりに戦場となった主に東南アジアに対して復興後の開発援助を約束した。これらの戦後処理を全てやったのは自民党であって、それ故保守論壇人士の方が戦後処理に詳しかった。だから「ドイツは交戦国に賠償していない」なんて事は相当のバカじゃなきゃ言わなかった。それはどこも一緒だから。
こういう訳で当初は「ニーチェ研究者の文章解釈」として評価されていた西尾言説が、「ドイツはナチスを切断処理して反省を拒否する立場である」という風に化けて行く。
この決定的な曲がり角は先にも言った小林よしのりなのだが、小林を論壇に引き込んだのは西尾なのだ。だから西尾は小林やそのフォロワーが後者の言説を流布して行くのを黙認していた。
その後西尾は宗教右翼に教科書運動を乗っ取られてパージされてしまい、「彼らの運動論は左翼のそれだ」と批判する羽目になるのだが、彼らを引き込んで論壇の真ん中で活動させたのも西尾だったのだな。
という訳で「ドイツはナチスを切断処理して反省しない立場」節の原初は西尾で、それが解釈ではなくて「表明したという事実」に化けていったのである。
2015年にメルケルが来日した際、朝日新聞で講演して安倍政権の歴史認識を批判する場面があった。
講演、インタビューに態々選んだのが朝日新聞というのは明確なメッセージだ。
これにネットの一部は沸騰してドイツ叩きが盛んになった、という事があった。
何故そんなに逆上したかと言えば、一部で「常識」となっているドイツナチス切断処理論と反対の立場から冷や水をぶっかけられたからだ。
仕舞にはメルケルは極左に振れているという噴飯ものの意見も多く見られた。メルケルの所属するCDUは保守政党である。
このナイーブな恐慌状態は集団で信じていた事を現実が裏切る事で起きていたので、これぞまさにルサンチマンだ。
ニーチェの思想に沿って生まれた解釈が30年経って反ニーチェ的なナイーブに転化していたというのは寓話的だと思う。
当たり前だが、メルケルもドイツもナチス切断処理なんて立場を表に出した事は無い。統一ドイツの成立条件見れば当たり前だ。
西ドイツはEC加盟国だったが東ドイツはそうではない。統一は他の加盟国の承認が必要だった。
そしてベルリンというのは統一の前日、最後まで連合国の占領下にあった。
ソ連は勝手に東ベルリンを自分の勢力下としてしまったが、米仏英はそんな事認めていない。法的には最後まで共同統治であった。
つまりベルリンの占領はこれら4国の承認が無い限り解けない。もしヴァイツゼッカーがナチスを切断処理してドイツに責任無しという演説をしたら、東西ドイツがその態度だったら、ベルリンを首都に出来ただろうか?
そしてEUの顔役が出来ただろうか?
当たり前すぎてバカらしい。
http://gothedistance.hatenadiary.jp/entry/2017/06/20/103000
練習以前の話として。
例えば、
y = x;
という代入文1行でいいところを、しかも最初はこう書いていたのに動かないからといって、よりによってこの箇所を
if (x == 0) { y = 0; } else if (x == 1) { y = 1; } else if (x == 2) { <以下略>
と、考えられる値すべてについての条件文に書き直してしまって、さらにコピペ後の書き換えをミスってバグを仕込んでしまった例を見たときは「こいつはセンスがないな」と思った。
逆に、最初からif文の羅列を書いてしまうような人が、「これは正解ではないと思うが、どう書いていいか分からない」と言ってたときは「こいつはセンスがあるな」と思った。
(if文の羅列自体がどうかという向きもあるかもしれないが、学習段階によっては代入文の右辺にリテラルしか置けないと思ってしまっていることはあり得るので、特段変なことではない)
あ、まず前提として、
はたして貴女を幸福にするかどうか、それはまた別問題だけれど。
IT系の超かしこい男なども多く、
多くっつーかIT系でないのにプログラミング大好き男っていうのは超かしこい学生(まぁこれは有望株)か研究者系なんか、
あとはまったくかしこくもないクセに頭いいつもりして「Lispやってます(キリッ ハローワールドくらいですが」とか言っちゃうアホしかいないわけで、
したがって、釣り師たる女たちにとっては、
なかなかあなどれない釣り場です。
では、プログラミング大好き男に「どの言語が好き?」と訊ねられたとき、
まず最初に、その男がCOBOLのようなタイプのレガシーコードと
あとはC/C++、そして(TechEdに参加するほどではないけれど)VisualBasicが大好きな、
貴女はかれの目を見て、微笑みとともに質問など無視して、こう言いましょう、
「わたしが、仕様書を作ってあげる♪」
これこそまさに必殺の答えです。
そこでプログラミング大好き男が、えへへ、とやにさがったならば、
貴女は、ひそかに、「コピペ量産しやすい技術的ポイントを抑えた仕様書」あたりを
ひそかに練習しておきましょう。これで成功まちがいなしです。
しかし、ここでは、もう少しハイブロウな(?)いわゆるプログラミング好きの男の
落とし方をお伝えしましょう。
「わたしは、JVM上のScalaが好き。
型推論もあるしラムダ式やクロージャもスクリプト言語みたいに書けるの、豊富な組み込みのコレクションメソッドはいつも便利だし、
XMLリテラルもCaseクラスによるパターンマッチもTraitベースのMixi-inも、大好き♪」
もしも貴女がそう答えたならば、
かれの貴女への恋心は、
20%増量になるでしょう。
なぜって、Scalaは、
コンパイルは遅いながらも、そこがまた
ちょっぴりメモリを多く積めばいい富豪プログラミングみたいなふんいきをかもしだしていて。
質高くふるまっていて、なおかつ、
JVM上で動くくせにJavaが「やるやる」と言ったまま実装してなかったラムダ式と仮想拡張メソッド、型推論を実装した功績もあって。
したがってScalaこそは、
本来なんの接点もないまったく縁もゆかりもない別々の世界に生きている、
インタプリタ言語大好きな綺麗系OLと、玉もあれば石も混じっている、そんなプログラミング大好き男たちが、
この世界で唯一(いいえ、JVM系列のJRuby、Clojure と並んで唯三)遭遇しうる場所です。
●
では、参考までに、危険な回答を挙げておきましょう。
プログラミング大好き男に「どの言語が好き?」と訊ねられたとき、
「MicrosoftのVisual Basic for Applicationが好き♪ 週3回は Excelでコーディングするの。」
特にOfficeは平凡ながら、ま、無難にまとめてあるものの、
しかし、「新UIのリボンUI!」「メトロUI対応!」とかなんとか無意味な自慢を吹聴し、
VBAはさらにプログラミングについての謬見を撒き散らした罪がありますから、プログラミング大好き男にとっては天敵なんです。
ティーガー戦車乗りのオットー・カリウスは「ティーガー乗りなら誰でも片側の履帯がはずれ僚車に牽引されて帰ってきた経験を持つはずだ」 って言ったけど
社内SEかSIerなら誰でもクソみたいな前任者が書いたクソみたいなExcel-VBAコードを直した経験があるはずなんです。
また、もしも貴女が「PHPが大好き♪ あたしが書いたPHPのWebサイトが、さくらサーバに7件あるよ♪」
と答えたとしても、同様の効果をもたらすでしょう、
なぜって、PHPは、1990年代にはWeb系を目指す人にとっては簡単で要件を満たすWebサイトが簡単に作れる輝きの道だったものの、
しかし2000年代そうそうから、セキュリティ関係の問題で転落し、
いまや、あの貧弱な言語能力では、Rubyの魅力に遥かに及びません。
(注1)
「わたし、.NET FrameworkのC#が好き、フォームアプリでも書くけど、
最高に好きなのはASP.net♪ SQLServer連携も、ajax control toolkitもすっごくおいしいの。」
と、答えたとしたらどうでしょう?
なるほど、貴女の趣味は高く、
たしかに.NET Frameworkは、C# が cool であるのみならず、
.NET Framework上で動く F# や IronPythonやIronRuby、マネージJScriptも最高においしいんですけれど、
しかし、貴女の答えを聞いて、プログラミング大好き男はきっとおもうでしょう、
(なんだよ、MS信者な女だな、カネかかりそう)って。
(注2)
貴女が、プログラミングが大好きで、言語の名を挙げるにしても、
たとえば、JavaScript(node.js)ならば安心でしょう、
なぜならば、JavaScriptは、かけだしのプログラミング初心者にもマニアにもともに愛されるめずらしい言語で、
貴女がその名前を挙げても必ずしも、(jQueryがやっとの初心者と思われることはあっても)あなたがプログラミング言語おた宣言をしているとは受け取られないでしょう。
むしろ「へぇ。ちゃんとprototypeは使ってる?」と聞かれたら「当たり前じゃない。むしろnode.jsでいいMVCフレームワークが分からないんだけど…」と話を振ってみましょう。
男は嬉々として、30個くらいのnode.jsのフレームワークを教えてくれることでしょう。(まぁどれもどれで帯に短し襷に長しなんですが)
あるいはRighno上で動かしたコードをnodeへ移植する話とか、CoffeeScript、甚だしきはClojureScriptを振ってみてもいいかもしれません。
しかし、たとえば、世界が(つーか竹内先生とポール・グレアムが)誇る超絶関数型言語の名作、Common Lispにせよ、
selfと書きまくることと海外で使われてることに定評のあるPythonにせよ、
バージョンアップごとに言語仕様が変わり、かなり素敵なものではあるもののobsolatedな罠にはまりやすいRubyにせよ、
まったく読めない$_だらけで頭悪い仕様をリセットしてPerl6にする(そしてまた全く読めない)Perlにせよ、
気さくなクジラ飛行机さんがふるまう素敵においしい日本語プログラミング言語のひまわり・なでしこにせよ、
基地外トリッキー言語の代表BrainFxck・Glass・Missa・WhiteSpaceにせよ、
ましてや貴女が、「Haskellが大好き♪ わたし、プロジェクト・オイラーの問題もうほとんどHaskellで、解いちゃった♪」
と答えたならば、どうでしょう?
これはかなり博打な答え方で、
なるほど、Haskellは、純粋関数型でありつつも副作用のある操作が行える超絶名言語ゆえ、
あなたがそう答えた瞬間、プログラミング大好き男がいきなり超笑顔になって、
「へぇ、やっぱりHaskellなら大抵の問題は4行以内くらいで解いちゃった?」とか言いながら
鼻の下がだら~んと伸びちゃう可能性もあるにはありますが、
しかし、逆に、(なんだよ、この女、プログラミングおたくかよ)とおもわれて、どん引きされる可能性もまた大です、
なぜって、必ずしもプログラミング大好き男がプログラミング大好き女を好きになるとは、限らないですから。
男たちは、女を導き高みへ引き上げてあげることが大好きゆえ、
もしも貴女が、「Haskellが大好き♪」なんて言ってしまうと、
そこにはもはや、男が貴女に圏論のモナドを教育する余地がまったく残されていません、
したがって貴女のその答えは、
プログラミング大好き男の貴女への夢を潰してしまうことに他なりません。
ま、ざっとそんな感じです、貴女の目にはプログラマーたちはバカでスケベで鈍感に見えるでしょうが、
しかし、ああ見せて、プログラマーはプログラマーで繊細で、おざなりに扱われると傷つきやすく、ローカル変数の名前一つにも気を使い、女と自分の将来に夢を持っています、
貴女の答え方ひとつで、プログラマーの貴女への夢は大きくふくらみもすれば、
一瞬で、しぼんでしまいもするでしょう。
●
では、スキットを繰り返しましょう。
「わたしは、JVM上のScalaが好き。
型推論もあるしラムダ式やクロージャもスクリプト言語みたいに書けるの、豊富な組み込みのコレクションメソッドはいつも便利だし、
XMLリテラルもCaseクラスによるパターンマッチもTraitベースのMixi-inも、大好き♪」
そして、その瞬間、プログラミング大好き男の目がらんらんと輝いたなら、
貴女はこう重ねましょう、
「それからね、いま、わたしが使ってみたいWebアーキテクチャは、
Play Framework、素敵なリアルタイム嗜好のアーキテクチャって噂を聞いたから。
あなたのお暇なときがあったら、わたしをPlayへ連れてって♪」
これでもう完璧です。
PlayFrameworkと、Play(遊ぶ・じゃれる)のダブルミーニングでかれの股間も刺激しちゃえます。
そうなったらこっちのもの、
デートの日には、ペアプロ用に Happy Hacking Keyboard をばっちり決めて、かわいい下着をつけて(注3)、
github.comの通販で売ってるoctcatのTシャツか、facebookの「いいね!」ボタンがムネのところにあるTシャツ、 あるいは初音ミク(ないし彼のお気に入りのアニメキャラ。北米ならMyLittlePonyで鉄板なんだけど)のコスプレを着てゆきましょう。
その日から、プログラミング大好き男は貴女の虜になるでしょう。
注1:
(と、書いたもののPHPの現状をよく知りません。グローバル変数だらけになるのとか旧ASPみたいなもんなのかなぁ。count($array); とか書くのアホと思うがpythonも同じだった)
(あと、マジで単機能とかTwitter連携とか診断メーカー的なのでもPHPで7つも作ってる女子居たら付き合いたい)
注2:
もっとも。objective-Cなんていう言語をやることに比べれば個人で行う程度なら金のかからない手法もなくはないのですが。
注3:
プログラマーにとっての「かわいい下着」と、女性にとっての「かわいい下着」の定義にずれがあるので注意。
半数くらいのプログラマーはしましまぱんつが可愛いと思ってる気がするので、妙齢の女性が着用するには抵抗あると思うが、ボーダー柄のコットンショーツ(ただしキャラ絵のは除く)とか、
過度でないていどにフリルがついたものがオススメ。また、色は、レッドだとプログラミング大好き男は引いてしまう(だってそれはコンパイルエラーのときの色だ)ので、薄ピンクかホワイト、薄ブルー、せめて黒(に差し色でピンクとか)あたりに留めたい。
補記:
元ネタ: http://tabelog.com/tokyo/A1301/A130101/13002457/dtlrvwlst/3464106/
補記2:
「プログラマー」か「プログラマ」かの問題については、特に意味は無いが前者を採用した。
補記3:
言うまでも無いけど、ネタです。
第1章 有限オートマトン D.Perrin:橋口攻三郎 1. 序論 2. 有限オートマトンと認識可能集合 3. 有理表現 4. Kleeneの定理 5. 星の高さ 6. 星自由集合 7. 特殊なオートマトン 8. 数の認識可能集合 第2章 文脈自由言語 J.Berstel and L.Boasson:富田 悦次 1. 序論 2. 言語 2.1 記法と例 2.2 Hotz 群 2.3 曖昧性と超越性 3. 反復 3.1 反復補題 3.2 交換補題 3.3 退化 4. 非生成元の探求 4.1 準備 4.2 生成元 4.3 非生成元と代入 4.4 非生成元と決定性 4.5 主錐の共通部分 5. 文脈自由群 5.1 文脈自由群 5.2 Cayleyグラフ 5.3 終端 第3章 形式言語とべき級数 A.Salomaa:河原 康雄 1. 序論 2. 準備 3. 書換え系と文法 4. Post正準系 5. Markov系 6. 並列書換え系 7. 射と言語 8. 有理べき級数 9. 代数的べき級数 10. べき級数の応用 第4章 無限の対象上のオートマトン W.Thomas:山崎 秀記 序論 Ⅰ部 無限語上のオートマトン 記法 1. Buchiオートマトン 2. 合同関係と補集合演算 3. 列計算 4. 決定性とMcNaughtonの定理 5. 受理条件とBorelクラス 6. スター自由ω言語と時制論理 7. 文脈自由ω言語 Ⅱ部 無限木上のオートマトン 記法 8. 木オートマトン 9. 空問題と正則木 10. 補集合演算とゲームの決定性 11. 木の単項理論と決定問題 12. Rabin認識可能な集合の分類 12.1 制限された単項2階論理 12.2 Rabin木オートマトンにおける制限 12.3 不動点計算 第5章 グラフ書換え:代数的・論理的アプローチ B.Courcelle:會澤 邦夫 1. 序論 2. 論理言語とグラフの性質 2.1 単純有向グラフの類S 2.2 グラフの類D(A) 2.3 グラフの性質 2.4 1階のグラフの性質 2.5 単項2階のグラフの性質 2.6 2階のグラフの性質 2.7 定理 3. グラフ演算とグラフの表現 3.1 源点付きグラフ 3.2 源点付き超グラフ 3.3 超グラフ上の演算 3.4 超グラフの幅 3.5 導来演算 3.6 超辺置換 3.7 圏における書換え規則 3.8 超グラフ書換え規則 4. 超グラフの文脈自由集合 4.1 超辺置換文法 4.2 HR文法に伴う正規木文法 4.3 超グラフの等式集合 4.4 超グラフの文脈自由集合の性質 5. 超グラフの文脈自由集合の論理的性質 5.1 述語の帰納的集合 5.2 論理構造としての超グラフ 5.3 有限超グラフの可認識集合 6. 禁止小グラフで定義される有限グラフの集合 6.1 小グラフ包含 6.2 木幅と木分解 6.3 比較図 7. 計算量の問題 8. 無限超グラフ 8.1 無限超グラフ表現 8.2 無限超グラフの単項性質 8.3 超グラフにおける等式系 8.4 関手の初期不動点 8.5 超グラフにおける等式系の初期解 8.6 等式的超グラフの単項性質 第6章 書換え系 N.Dershowitz and J.-P.Jouannaud:稲垣 康善,直井 徹 1. 序論 2. 構文論 2.1 項 2.2 等式 2.3 書換え規則 2.4 決定手続き 2.5 書換え系の拡張 3. 意味論 3.1 代数 3.2 始代数 3.3 計算可能代数 4. Church-Rosser性 4.1 合流性 4.2 調和性 5. 停止性 5.1 簡約順序 5.2 単純化順序 5.3 経路順序 5.4 書換え系の組合せ 6. 充足可能性 6.1 構文論的単一化 6.2 意味論的単一化 6.3 ナローイング 7. 危険対 7.1 項書換え 7.2 直交書換え系 7.3 類書換え 7.4 順序付き書換え 7.5 既約な書換え系 8. 完備化 8.1 抽象完備化 8.2 公平性 8.3 完備化の拡張 8.4 順序付き書換え 8.5 機能的定理証明 8.6 1階述語論理の定理証明 9. 書換え概念の拡張 9.1 順序ソート書換え 9.2 条件付き書換え 9.3 優先度付き書換え 9.4 グラフ書換え 第7章 関数型プログラミングとラムダ計算 H.P.Barendregt:横内 寛文 1. 関数型計算モデル 2. ラムダ計算 2.1 変換 2.2 計算可能関数の表現 3. 意味論 3.1 操作的意味論:簡約と戦略 3.2 表示的意味論:ラムダモデル 4. 言語の拡張 4.1 デルタ規則 4.2 型 5. 組合せ子論理と実装手法 5.1 組合せ子論理 5.2 実装の問題 第8章 プログラミング言語における型理論 J.C.Mitchell:林 晋 1. 序論 1.1 概論 1.2 純粋および応用ラムダ計算 2. 関数の型をもつ型付きラムダ計算 2.1 型 2.2 項 2.3 証明系 2.4 意味論と健全性 2.5 再帰的関数論的モデル 2.6 領域理論的モデル 2.7 カルテシアン閉圏 2.8 Kripkeラムダモデル 3. 論理的関係 3.1 はじめに 3.2 作用的構造上の論理的関係 3.3 論理的部分関数と論理的同値関係 3.4 証明論的応用 3.5 表現独立性 3.6 論理的関係の変種 4. 多相型入門 4.1 引数としての型 4.2 可述的な多相的計算系 4.3 非可述的な多相型 4.4 データ抽象と存在型 4.5 型推論入門 4.6 型変数をもつλ→の型推論 4.7 多相的宣言の型推論 4.8 他の型概念 第9章 帰納的な関数型プログラム図式 B.Courcelle:深澤 良彰 1. 序論 2. 準備としての例 3. 基本的な定義 3.1 多ソート代数 3.2 帰納的な関数型プログラム図式 3.3 同値な図式 4. 離散的解釈における操作的意味論 4.1 部分関数と平板な半順序 4.2 離散的解釈 4.3 書換えによる評価 4.4 意味写像 4.5 計算規則 5. 連続的解釈における操作的意味論 5.1 連続代数としての解釈 5.2 有限の極大要素と停止した計算 6. 解釈のクラス 6.1 汎用の解釈 6.2 代表解釈 6.3 解釈の方程式的クラス 6.4 解釈の代数的クラス 7. 最小不動点意味論 7.1 最小で唯一の解を得る不動点理論 7.2 Scottの帰納原理 7.3 Kleeneの列と打切り帰納法 8. プログラム図式の変換 8.1 プログラム図式における同値性の推論 8.2 畳込み,展開,書換え 8.3 制限された畳込み展開 9. 研究の歴史,他の形式のプログラム図式,文献ガイド 9.1 流れ図 9.2 固定された条件をもつ一様な帰納的関数型プログラム図式 9.3 多様な帰納的関数型プログラム図式 9.4 代数的理論 9.5 プログラムの生成と検証に対する応用 第10章 論理プログラミング K.R.Apt:筧 捷彦 1. 序論 1.1 背景 1.2 論文の構成 2. 構文と証明論 2.1 1階言語 2.2 論理プログラム 2.3 代入 2.4 単一化子 2.5 計算過程―SLD溶融 2.6 例 2.7 SLD導出の特性 2.8 反駁手続き―SLD木 3. 意味論 3.1 1階論理の意味論 3.2 SLD溶融の安全性 3.3 Herbrand模型 3.4 直接帰結演算子 3.5 演算子とその不動点 3.6 最小Herbrand模型 3.7 SLD溶融の完全性 3.8 正解代入 3.9 SLD溶融の強安全性 3.10 手続き的解釈と宣言的解釈 4. 計算力 4.1 計算力と定義力 4.2 ULの枚挙可能性 4.3 帰納的関数 4.4 帰納的関数の計算力 4.5 TFの閉包順序数 5. 否定情報 5.1 非単調推論 5.2 閉世界仮説 5.3 失敗即否定規則 5.4 有限的失敗の特徴付け 5.5 プログラムの完備化 5.6 完備化の模型 5.7 失敗即否定規則の安全性 5.8 失敗即否定規則の完全性 5.9 等号公理と恒等 5.10 まとめ 6. 一般目標 6.1 SLDNF-溶融 6.2 SLDNF-導出の安全性 6.3 はまり 6.4 SLDNF-溶融の限定的な完全性 6.5 許容性 7. 層状プログラム 7.1 準備 7.2 層別 7.3 非単調演算子とその不動点 7.4 層状プログラムの意味論 7.5 完全模型意味論 8. 関連事項 8.1 一般プログラム 8.2 他の方法 8.3 演繹的データベース 8.4 PROLOG 8.5 論理プログラミングと関数プログラミングの統合 8.6 人工知能への応用 第11章 表示的意味論 P.D.Mosses:山田 眞市 1. 序論 2. 構文論 2.1 具象構文論 2.2 抽象構文 2.3 文脈依存構文 3. 意味論 3.1 表示的意味論 3.2 意味関数 3.3 記法の慣例 4. 領域 4.1 領域の構造 4.2 領域の記法 4.3 記法上の約束事 5. 意味の記述法 5.1 リテラル 5.2 式 5.3 定数宣言 5.4 関数の抽象 5.5 変数宣言 5.6 文 5.7 手続き抽象 5.8 プログラム 5.9 非決定性 5.10 並行性 6. 文献ノート 6.1 発展 6.2 解説 6.3 変形 第12章 意味領域 C.A.Gunter and D.S.Scott:山田 眞市 1. 序論 2. 関数の帰納的定義 2.1 cpoと不動点定理 2.2 不動点定理の応用 2.3 一様性 3. エフェクティブに表現した領域 3.1 正規部分posetと射影 3.2 エフェクティブに表現した領域 4. 作用素と関数 4.1 積 4.2 Churchのラムダ記法 4.3 破砕積 4.4 和と引上げ 4.5 同形と閉包性 5. べき領域 5.1 直観的説明 5.2 形式的定義 5.3 普遍性と閉包性 6. 双有限領域 6.1 Poltkin順序 6.2 閉包性 7. 領域の帰納的定義 7.1 閉包を使う領域方程式の解法 7.2 無型ラムダ記法のモデル 7.3 射影を使う領域方程式の解法 7.4 双有限領域上の作用素の表現 第13章 代数的仕様 M.Wirsing:稲垣 康善,坂部 俊樹 1. 序論 2. 抽象データ型 2.1 シグニチャと項 2.2 代数と計算構造 2.3 抽象データ型 2.4 抽象データ型の計算可能性 3. 代数的仕様 3.1 論理式と理論 3.2 代数的仕様とその意味論 3.3 他の意味論的理解 4. 単純仕様 4.1 束と存在定理 4.2 単純仕様の表現能力 5. 隠蔽関数と構成子をもつ仕様 5.1 構文と意味論 5.2 束と存在定理 5.3 隠蔽記号と構成子をもつ仕様の表現能力 5.4 階層的仕様 6. 構造化仕様 6.1 構造化仕様の意味論 6.2 隠蔽関数のない構造化仕様 6.3 構成演算 6.4 拡張 6.5 観測的抽象化 6.6 構造化仕様の代数 7. パラメータ化仕様 7.1 型付きラムダ計算によるアプローチ 7.2 プッシュアウトアプローチ 8. 実現 8.1 詳細化による実現 8.2 他の実現概念 8.3 パラメータ化された構成子実現と抽象化子実現 8.4 実行可能仕様 9. 仕様記述言語 9.1 CLEAR 9.2 OBJ2 9.3 ASL 9.4 Larch 9.5 その他の仕様記述言語 第14章 プログラムの論理 D.Kozen and J.Tiuryn:西村 泰一,近藤 通朗 1. 序論 1.1 状態,入出力関係,軌跡 1.2 外的論理,内的論理 1.3 歴史ノート 2. 命題動的論理 2.1 基本的定義 2.2 PDLに対する演繹体系 2.3 基本的性質 2.4 有限モデル特性 2.5 演繹的完全性 2.6 PDLの充足可能性問題の計算量 2.7 PDLの変形種 3. 1階の動的論理 3.1 構文論 3.2 意味論 3.3 計算量 3.4 演繹体系 3.5 表現力 3.6 操作的vs.公理的意味論 3.7 他のプログラミング言語 4. 他のアプローチ 4.1 超準動的論理 4.2 アルゴリズム的論理 4.3 有効的定義の論理 4.4 時制論理 第15章 プログラム証明のための手法と論理 P.Cousot:細野 千春,富田 康治 1. 序論 1.1 Hoareの萌芽的な論文の解説 1.2 C.A.R.HoareによるHoare論理のその後の研究 1.3 プログラムに関する推論を行うための手法に関するC.A.R.Hoareによるその後の研究 1.4 Hoare論理の概観 1.5 要約 1.6 この概観を読むためのヒント 2. 論理的,集合論的,順序論的記法 3. プログラミング言語の構文論と意味論 3.1 構文論 3.2 操作的意味論 3.3 関係的意味論 4. 命令の部分正当性 5. Floyd-Naurの部分正当性証明手法とその同値な変形 5.1 Floyd-Naurの手法による部分正当性の証明の例 5.2 段階的なFloyd-Naurの部分正当性証明手法 5.3 合成的なFloyd-Naurの部分正当性証明手法 5.4 Floyd-Naurの部分正当性の段階的な証明と合成的な証明の同値性 5.5 Floyd-Naurの部分正当性証明手法の変形 6. ライブネスの証明手法 6.1 実行トレース 6.2 全正当性 6.3 整礎関係,整列集合,順序数 6.4 Floydの整礎集合法による停止性の証明 6.5 ライブネス 6.6 Floydの全正当性の証明手法からライブネスへの一般化 6.7 Burstallの全正当性証明手法とその一般化 7. Hoare論理 7.1 意味論的な観点から見たHoare論理 7.2 構文論的な観点から見たHoare論理 7.3 Hoare論理の意味論 7.4 構文論と意味論の間の関係:Hoare論理の健全性と完全性の問題 8. Hoare論理の補足 8.1 データ構造 8.2 手続き 8.3 未定義 8.4 別名と副作用 8.5 ブロック構造の局所変数 8.6 goto文 8.7 (副作用のある)関数と式 8.8 コルーチン 8.9 並行プログラム 8.10 全正当性 8.11 プログラム検証の例 8.12 プログラムに対して1階論理を拡張した他の論理 第16章 様相論理と時間論理 E.A.Emerson:志村 立矢 1. 序論 2. 時間論理の分類 2.1 命題論理 対 1階述語論理 2.2 大域的と合成的 2.3 分岐的 対 線形 2.4 時点と時区間 2.5 離散 対 連続 2.6 過去時制 対 未来時制 3. 線形時間論理の技術的基礎 3.1 タイムライン 3.2 命題線形時間論理 3.3 1階の線形時間論理 4. 分岐的時間論理の技術的基礎 4.1 樹状構造 4.2 命題分岐的時間論理 4.3 1階の分岐的時間論理 5. 並行計算:その基礎 5.1 非決定性と公平性による並列性のモデル化 5.2 並列計算の抽象モデル 5.3 並列計算の具体的なモデル 5.4 並列計算の枠組みと時間論理の結び付き 6. 理論的見地からの時間論理 6.1 表現可能性 6.2 命題時間論理の決定手続き 6.3 演繹体系 6.4 モデル性の判定 6.5 無限の対象の上のオートマトン 7. 時間論理のプログラムの検証への応用 7.1 並行プログラムの正当性に関する性質 7.2 並行プログラムの検証:証明論的方法 7.3 時間論理による仕様からの並行プログラムの機械合成 7.4 有限状態並行システムの自動検証 8. 計算機科学における他の様相論理と時間論理 8.1 古典様相論理 8.2 命題動的論理 8.3 確率論理 8.4 不動点論理 8.5 知識 第17章 関係データベース理論の構成要素 P.C.Kanellakis:鈴木 晋 1. 序論 1.1 動機と歴史 1.2 内容についての案内 2. 関係データモデル 2.1 関係代数と関係従属性 2.2 なぜ関係代数か 2.3 なぜ関係従属性か 2.4 超グラフとデータベーススキーマの構文について 2.5 論理とデータベースの意味について 3. 従属性とデータベーススキーマ設計 3.1 従属性の分類 3.2 データベーススキーマ設計 4. 問合わせデータベース論理プログラム 4.1 問合わせの分類 4.2 データベース論理プログラム 4.3 問合わせ言語と複合オブジェクトデータモデル 5. 議論:関係データベース理論のその他の話題 5.1 不完全情報の問題 5.2 データベース更新の問題 6. 結論 第18章 分散計算:モデルと手法 L.Lamport and N.Lynch:山下 雅史 1. 分散計算とは何か 2. 分散システムのモデル 2.1 メッセージ伝達モデル 2.2 それ以外のモデル 2.3 基礎的概念 3. 分散アルゴリズムの理解 3.1 挙動の集合としてのシステム 3.2 安全性と活性 3.3 システムの記述 3.4 主張に基づく理解 3.5 アルゴリズムの導出 3.6 仕様記述 4. 典型的な分散アルゴリズム 4.1 共有変数アルゴリズム 4.2 分散合意 4.3 ネットワークアルゴリズム 4.4 データベースにおける並行性制御 第19章 並行プロセスの操作的および代数的意味論 R.Milner:稲垣 康善,結縁 祥治 1. 序論 2. 基本言語 2.1 構文および記法 2.2 操作的意味論 2.3 導出木と遷移グラフ 2.4 ソート 2.5 フローグラフ 2.6 拡張言語 2.7 その他の動作式の構成 3. プロセスの強合同関係 3.1 議論 3.2 強双模倣関係 3.3 等式による強合同関係の性質 3.4 強合同関係における置換え可能性 3.5 強等価関係上での不動点の唯一性 4. プロセスの観測合同関係 4.1 観測等価性 4.2 双模倣関係 4.3 観測合同関係 4.4 プロセス等価性上での不動点の唯一性 4.5 等式規則の完全性 4.6 プロセスの等価性に対するその他の概念 5. 双模倣等価関係の解析 5.1 等価性の階層構造 5.2 階層構造の論理的特性化 6. 合流性をもつプロセス 6.1 決定性 6.2 合流性 6.3 合流性を保存する構成子 7. 関連する重要な文献
RubyのSymbolと文字列の違いを研究室の輪講用に書いたのですが,折角なので公開したいと思います.
元々学部生に対する輪講用に書いた物なので,若干上から目線ですがご了承ください.
文字列とSymbolはよく似ています.プログラマから見ればどちらも文字列です.違いを一言で説明すると『プログラムが扱う』文字列か,『プログラマが見る』文字列かの違いです.例えば変数名は『文字列』ですが,rubyのオブジェクトである『文字列』ではないですよね?
例えば,今あなたがC言語でお絵描きライブラリを作っているとしましょう.その中に,色で塗りつぶすfillという関数があり,色を青・赤・緑の3色から選べ,fillの引数でそれを指定できるとしましょう.
fillの引数の設定方法として一番単純なのが,0を青,1を赤,2を緑として,0〜2で選択させる方法でしょう.しかし,それでは,どの数値が何色か覚えないといけないし,fill関数を知らない人から見れば,どういう意味の引数かすらさっぱり分かりません.
ではどうするかと言えば,普通はBLUE = 0, RED = 1, GREEN = 2と適当に定数を設定して,その定数を引数で指定させますよね.
こうして,fill関数の引数が意味の無い数値から意味のある文字列に変わったことによってプログラムが分かりやすい物となります.さて,ここで注意してほしいのは,ここで言う文字列はプログラムが扱うオブジェクトとしての文字列では無いということです.fill関数の引数として,"BLUE","RED", "GREEN"などとC言語の文字列を渡すということは普通しませんよね.それは,ここで言う文字列は,あくまでプログラマがプログラムコードを分かりやすくするために必要な文字列であって,プログラムがオブジェクトとして扱う(例えば,長さを求めるとかする)文字列ではないからです.
分かってきたでしょうか?
プログラムコード上では(つまりプログラマから見れば)どちらも同じ文字列(文字の列という意味で)ですが,実際に動くプログラムから見れば単なる数値と本物の文字列という大きな違いです.結局,fill関数の引数の具体的な値は何でもいいわけです.プログラマから見て文字列であればそれだけでよく,プログラムが動くときの実際のその中身は何でもいいわけです.これのために存在するのが,Symbolであり,:fooとひとたびSymbolを作成すれば:fooの実態は適当な数値となります.(この数値がいくらかなんていうことはもちろん気にする必要はありません)
そして,もちろん同じプログラム上では:foo == :fooはちゃんと成り立ちます.もうここまでくれば,Hashのkeyとして文字列でなくSymbolを使う理由が分かりますね.Hashのkeyはあくまで,プログラマが見る(プログラムコードを分かりやすくするための)文字列であってプログラムが扱うオブジェクトとしての文字列では無くて,keyの実際の値は何でもいい,からですね.(特別な場合を除いて)Hashのkeyに対してrubyのStringのメソッドを使うなんてことは無いですよね.
しかし,他の軽量言語ではSymbolなどなくHashのkeyとして普通に文字列を使うことが多いです.では,なぜrubyだけSymbolを使うのでしょうか.
その答えは一言でいうと,rubyの(プログラムコード上に直接書かれた,つまりリテラルの)文字列は他の言語と違いimmutable(不変)でない,からです.実際,pythonやjavascriptの文字列(リテラル)は破壊的に変更することはできませんが,rubyの文字列は破壊的に変更することができます. ('abc'.concat('d')の様に)
これがどういう違いを生むかというと,コード上に直接現れる文字列がimmutable(不変)であるならば,実行時に一つだけそのオブジェクトを作成し,後はそれを使いまわすという最適化ができます.
そうした時,Hashのkeyの様なプログラマから見た文字列というのは,プログラムコード上のリテラルとして現れるわけですが,これらは実行時に一つだけオブジェクトが作成され(特にコード上に現れる同じ文字列は全て一つのオブジェクトにまとめると),それらの比較はそれらに対する参照(そしてこれは大抵メモリのアドレスなど単なる数値)の比較で済むので,結局Symbolと同じ様な働きをするわけです.
本当はプログラマが見るためだけの文字列だけど,それをオブジェクトとしての文字列としても,Symbolと同じ様な働き,パフォーマンスが得られるならば,別にオブジェクトとしての文字列であってもいいわけです.
繰り返しになりますが,プログラマが見るためだけの文字列は,その中身・実態は何でもいいわけですが,その実態がオブジェクトとしての文字列でも十分なパフォーマンスが得られるならば,別にオブジェクトとしての文字列でもいいわけです.
さて,rubyに話を戻しますと,rubyはコード上に現れる文字列であっても,実行時にそのコードを通る度に毎回新たな文字列オブジェクトを作成します.
(以下のプログラムを動かすことで確認できる.)
def foo 'foo'.object_id end p foo, foo
つまり,rubyでは文字列が可変であるため,先に述べたような最適化ができない(または難しい)ので毎回新たな文字列オブジェクトが作成されるのです.
こうなると,先ほどの話とはうってかわって,プログラマが見る文字列はその実態は何でもいいのに,それを文字列リテラル(rubyのオブジェクトとしての文字列)にしてしまうと,毎回毎回文字列オブジェクトが作成されてしまうという非常にばかばかしい状況になってしまいます.我々はそれらの文字列オブジェクトに文字列としての操作は一切施さないのにも関わらず,です.
こういうわけで,rubyではプログラマが見るためだけの文字列にSymbolというruby特有のものを使うのです.
もちろん,プログラマが見るためだけの文字列を全て定数として(そしてもちろん中身は適当な値で)定義しても構わないわけですが,Hashのkeyとかで数多くのプログラマが見るためだけの文字列が現れることを考えると,とてもじゃないですけどそんなことは面倒でやってられないですよね.ですので,実行時に自動で適当な値にしてくれるSymbolというものが存在するのです.
以上で,Symbolについての説明を終えます.以下は蛇足です.
最初の方で出てきたfill関数をrubyで実装しようとしたとき,青・赤・緑の各色はその実際の値はなんでもいいのでrubyのSymbolを使って:blue, :red, :greenとしてもいいのですが,ライブラリとかでは大抵ちゃんと定数として定義されていることが多いです.
これは恐らく,定数として明示的に定義することで値の存在を明示でき,ドキュメント化の際にも役立つことによっているのでしょう.
しかし,あくまでこれは外部に公開するようなライブラリでの話であって,自分が使うちょっとしたプログラムならこういう場面でも精力的にSymbolを使っていってもいいと思います.ちなみに,僕ならSymbolを使います.
Symbolだと定義もいりませんし,定数は大文字ですから打つのが面倒ですし,あまりソースに大文字が入ると見た目がすっきりしません(主観).
Symbolは非常に便利なものですので,その意義・用途を十分に理解して,Hashのkeyにとどまらず様々な所で使えるようになりましょう.
処女とは言っても、いろいろいるのではないか、と思う。
増田なので信じてもらえるかどうかわからないが書いてみる。
////////////////////////////////////////////
俺の友人の、ある女の子は、20代も半ばで、今まで10人以上と付き合ったことがあるらしいのだが、いまだに処女だそうだ。
理由は、セックスに拒否反応があるから、というか単に「こわい」ということらしい。
「どこらへんがこわいの?」と聞いてみたら、「だっていたい。血が出るし」などと言う。
本人が言う理由をリテラルに受け取ってしまってもいいのか悩むが、いまのところそのまま受け取るしかない。
で、彼女は、いわゆる「処女」のイメージどおりなのかといったら、そうでもない。
たしかに黒髪のストレートだが、おとなしいというわけでもなく、かなりの社交好きだ。
おしゃべりも大好きだし、ふつうにクラブにも行くそうだ。(俺は行かないので驚いた)
いままで付き合ったのは、ほとんど自分からの告白がきっかけだったらしい。
しかしやっぱり、セックスを拒否することは、なかなか相手の男には受け入れてもらえない、と言う。
いままでそれが原因で別れたことは、少なくないそうだ。
だから、付き合った人数が増えた、という側面もあるようだ。
たとえば、相手がシャワーを浴びているあいだにホテルから逃げる、などをして、相手がキレるということがよくあったそうだ。
また、相手の男から、強引に迫られることもあったらしい。
たとえば、ある元カレなんかは、別れたあとに彼女を呼び出して、「おまえ、させないんだったら、口でやってよ」と、ほとんど脅すようなかんじで迫ったそうだ。彼女は、「こわかったから、くわえた」と言っていた。
「あたし処女だけど、フェラチオは体験済み!」などと、笑い話っぽく話してくれたよ。
////////////////////////////////////////////
まあ、そういうわけで、俺も世の中にどのような処女がいるかはわからないけど、こんな女の子もいるということで、なにかの参考になればと思い、書いてみました。
「はじめての正規表現」がホッテントリ入りしていますが、
導入としては、何に使うのかがわかりやすくて良いのではないかと思います。
あれを見て、基本機能をまとめてみたくなったので、正規表現の基本的な機能について書いてみます。
(正規表現が初めてという人は「はじめての正規表現」を先に見たほうがいいと思います。)
例では「検索」か「置換」をするものとして話を進めていきます。
(「はじめての正規表現」が実例を中心にしたのに対して、こちらは機能を中心に書きます)
正規表現は、プログラミング言語やその他のツールなど、それぞれで微妙な違い(方言)があるので、その点には注意が必要です。
(表記法が違ったり、ここに紹介する機能がサポートされていなかったり、逆に紹介していない機能をサポートしていたりする場合があります)
メタ文字とは機能を持つ文字で、『.
』『*
』『*?
』といったものが当てはまります。
リテラル文字は「文字それ自体」と解釈される文字で、『
』『a
』『<
』といったものです。
「検索する文字列:『egg
』 置換する文字列:『chicken
』」
などとすれば、正規表現を使わない置換と同じ効果になります。
なお、検索して検索文字列が当てはまることを「マッチする」と言います。
メタ文字に使われている文字を検索したい場合は、直前に『\
』を置きます。(これを「エスケープ」と呼びます。)
『.*?^$()[]{}
』などがメタ文字です。
『$100
』を検索したければ、『\$100
』とすればいいということになります。
(『\
』は環境によって、半角の『¥』『\』のどちらかになります。)
言語、ツール、モードなどによっては『@/#
』もエスケープが必要です。
また、『\
』自体は常にエスケープが必要です。
メタ文字 | 意味 |
---|---|
? | 直前の文字を0回または1回繰り返す |
* | 直前の文字を0回以上繰り返す |
+ | 直前の文字を1回以上繰り返す |
{n} | 直前の文字をn回繰り返す |
{n,} | 直前の文字をn回以上繰り返す |
{n,m} | 直前の文字をn〜m回繰り返す |
これらのメタ文字は「量指定子」といって、直前の文字の繰り返しを意味します。
『*
』は「任意の文字を0回以上繰り返す」とありますが、
「0回以上繰り返す」とは、「全く何もなくてもいいし、いくらあってもいい」という意味です。
よって、『?
』は「あってもなくてもいい」、『+
』は「1つ以上あればいい」と解釈できます。
『colou?r
』は『u
』があってもなくてもいいので「colorかcolour」ということになります。
『{n}
』は、たとえば『-{15}
』なら、「ハイフン(-)が15個続くもの」となります。
『-{10,}
』なら「ハイフン(-)が少なくともは10個続くもの(多いのはいくらでも)」、
『-{10,15}
』なら「ハイフン(-)が10〜15個続くもの」となります。
また、複数の文字を繰り返したい場合は括弧で囲みます。
『(Gang){2}Dance
』は『GangGangDance
』と同じ意味になります。
メタ文字 | 意味 |
---|---|
? | 直前の文字を0回または1回繰り返す(欲張り) |
* | 直前の文字を0回以上繰り返す(欲張り) |
+ | 直前の文字を1回以上繰り返す(欲張り) |
?? | 直前の文字を0回または1回繰り返す(非欲張り) |
*? | 直前の文字を0回以上繰り返す(非欲張り) |
+? | 直前の文字を1回以上繰り返す(非欲張り) |
「欲張り」とは、「なるべく多くの文字に適用しようとする」、
「非欲張り」とは、「なるべく少ない文字に適用しようとする」という意味です。
すると、検索する文字列が『a+
』なら『aaa bbb ccc
』、
検索する文字列が『a+?
』なら『aaa bbb ccc
』が置換対象となります。
(「すべてを検索/置換」する場合は当てはまりません)
「『a
』を1回以上繰り返す」ということは、『a
』でも『aa
』でも『aaa
』でもマッチすることになりますが、
「欲張り」かそうでないかで実際のマッチは変わってくるわけです。
文字クラス | 意味 |
---|---|
[abc] | a、b、cのいずれか |
[a-z] | a〜zのいずれか |
[^a] | a以外の文字(改行文字を含めaを除いた全て) |
[^a-z] | a〜z以外の文字(改行文字を含めa〜zを除いた全て) |
文字クラスは『a
』や『<
』などの代わりに文字の種類を指定するものです。
a〜eのどれかの1文字という指定をしたい場合に『[abcde]
』や『[a-e]
』といった指定ができます。
また、文字クラス内の最初に『^
』をつけて『[^abc]
』などとすれば、
「a、b、c以外の何の文字でもいい」とすることができます。
間違いやすいのが「そこにaもbもcも存在しなければいい」という意味ではないということです。
文字クラスは「なんらかの1文字の身代わり」なので、それは何か1文字を表しています。
『-
』は範囲を表すのに使用します。そのため、『[;-%]
』で「; - %のどれか」を表現することはできません。
『-
』を含める場合は必ず最初に持ってきます。すると『[-;%]
』という風になります。
「; - %以外の文字」としたいならば『[^-;%]
』とします。
『[
』や『]
』、『\
』を文字クラスに含めたい場合は直前に『\
』を置いてエスケープします。
「『[
』または『]
』」であれば『[\[\]]
』となります。
『^
』やその他の記号は先頭に置かなければいいので、エスケープの必要はありません。
『.
』は「改行以外のすべての文字」を表しています。
改行は『\n
』で表されるため、『.
』は『[^\n]
』と等価です。
(ただし、正規表現のモードによっては「改行も含めすべての文字」を表す場合もあります)
文字クラス | 意味 | 同等の表記 |
---|---|---|
\w | 記号や空白ではない文字すべて | [a-zA-Z0-9_] |
\W | 記号や空白ではない文字以外 | [^a-zA-Z0-9_] |
\d | 数字 | [0-9] |
\D | 数字以外 | [^0-9] |
\s | タブや改行など、空白類とされる文字 | [ \t\n\r\f\v] |
\S | タブや改行など、空白類とされる文字以外 | [^ \t\n\r\f\v] |
(*間違って『\s
』の同等の表記にも『^
』がついていたのを修正しました)
(『\t
』はタブ、『\v
』は垂直タブ、『\r
』はキャリッジリターン(CR、改行の一種)、『\f
』は改ページ)
これらは『[a-fA-F\d]
』のようにすることで、文字クラスのブラケット(角括弧)内に含めることができます。
「同等の表記」と書きましたが、文字をユニコードして扱うツールの場合は、上記が同等の表記にはならず、
たとえば『\d
』であれば漢数字が含まれてしまったりするので注意が必要です。
『(A|B)
』は「AまたはB」という意味です。(これを「選択」と呼びます)
『(A|B|C)
』なら「A、B、Cのどれか」という意味になります。
『(gray|grey)
』は『gr[ae]y
』とほぼ等価となります。
『[ae]
』は「1文字のaまたはb」という意味になるので結果的に、ほぼ同じ効果が得られるわけです。
(ただし、これはgrayとgreyの違いが1文字だけだったためで、そうでない場合はこうはなりません)
気をつけなければならないのは、その順番です。
『(Java|JavaScript)
』で検索すると、対象文字列内に存在する『Java
』と『JavaScript
』すべてマッチするように思えますが、
『JavaScript
』は選択肢の前(左)のほうにある『Java
』が当てはまってしまうため、
『Script
』部分にはマッチせず、『JavaScript
』というマッチになってしまいます。
選択では左側が優先されるので、『(JavaScript|Java)
』とすることでこの問題は防げます。
(言語、ツールによっては、この問題が起こらない=順番関係なく長いほうを適用しようとするものもあります)
メタ文字 | 意味 |
---|---|
^ | 行頭 |
$ | 行末 |
\b | 単語境界 |
\B | 単語境界以外 |
リテラル文字や文字クラスが「文字自体」にマッチするのと違い、アンカーは「位置」にマッチします。
検索する文字列が『^
』、置換する文字列が『>
』なら、「行頭に『>
』を挿入する」という意味になります。
単語境界とは、「単語を構成する文字=『\w
』に相当する文字」と「単語を構成しない文字=『\W
』に相当する文字」の間の位置のことです。
『regular expression.
』なら『^regular^ ^expression^.
』の4ヶ所に当てはまります。
『\b.*?\b
』とすれば単語すべてにマッチさせることができます。
しかし、「単語構成文字」が基準なので、『JavaScript
』は1単語でも、『L?K?O
』は1単語とは見なされません。
アンカーは位置にマッチするので、文字クラス内に含めることはできません。
『^
』や『$
』を文字クラスに含めても、その文字自体という意味になります。
つまり、『[^$]
』なら「行頭または行末」ではなくて、「『$
』文字以外」ということになります。
また、『\b
』は文字クラス内のみ、バックスペース文字を表す場合が多いようです。
正規表現には、大抵「大文字と小文字を無視する」というオプションがあります。
これが入っていないと「『to:
』で検索しても『To:
』にマッチしない」といったことが起こります。
言語、ツールによっては、正規表現の一部にのみ大文字と小文字を無視する機能があるものもあります。
例えばRubyでは『(?i:foo)
』という形式を使用できます。
『(
?i:Ruby) Python
』という表現なら、『ruby Python
』や『RuBy Python』にはマッチしますが、
『RUBY PYTHON
』にはマッチしない、ということになります。
括弧内に入れた文字列は、ある場所に記憶されます。(「キャプチャ」と呼びます)
これは『\n
』という表記を使って呼び出すことができます。(nは数字)
同じ単語が2連続で出てくるもの(『merry merry
』みたいなもの)を探すという場合、
『\b(\w+)\b \1
』とすることができます。(ここで使った『\1
』を「後方参照」と呼びます)
こうすると、『\1
』の部分は、『(\w+)
』を使ってマッチしたものと同じものがあるものとして解釈されることになります。
括弧を何個も使う場合は、左の括弧から順に『\1
』、『\2
』、『\3
』となります。
また、後方参照は置換文字列にも使うことができます。
つまり置換文字列内に『\1
』と書けば1番目の括弧、
『\2
』と書けば2番目の括弧でキャプチャされたものがそこに入ることになります。
この場合、言語、ツールによっては『\n
』ではなく『$n
』を使う場合もあるようです。
括弧は『(foo|bar)
』という選択や、『(humbert){2}
』というグループ化など、キャプチャ以外にも使われます。
そのため、キャプチャに使われた数字をわかりやすくするために、キャプチャしない括弧もあります。
それには『(?:foo)
』という表記を使います。
前の例であれば『(?:foo|bar)
』と『(?:humbert){2}
』になります。
「その位置の続くものを確認する」というのが「先読み」です。
対象文字列を『JavaScript Java Applet』として考えてみましょう。
『Java(?=Script)
』は「『Script
』が後に続く『Java
』」にマッチします。
『(?=Script)
』の部分が、「『Script
』が後に続くかどうか」をチェックしているので、
後ろに『Script
』が続かない単なる『Java
』にはマッチしません。
『(?=Script)
』の部分は「後に『Script
』が続く位置」にマッチしていることになります。
この例のマッチは『JavaScript Java Applet』となります。
逆に、『Java(?!Script)
』とすれば、「『Script
』が後に続かないかどうか」をチェックするので、
後ろに『Script
』が続かない単なる『Java
』にマッチさせることができます。
こちらは「否定先読み」と呼びます。
この例のマッチは『JavaScript Java Applet』となります。
言語、ツールによっては、「その位置の前にあるものを確認する」という「戻り読み」「否定戻り読み」がサポートされているものもあります。
(これは『(?<=foo)
』『(?<!=bar)
』という形で使います)
先読みや否定先読み、戻り読みなどをまとめて「前後読み」と呼びますが、
前後読みは位置にマッチするため、戻り読みは先読みとは通常書くべき位置が逆になります。
『(?<Mozilla )Firefox
』とすれば、『Mozilla
』に続く『Firefox
』のみにマッチします。
メタ文字 | 意味 |
---|---|
?+ | 直前の文字を0回または1回繰り返す(強欲) |
*+ | 直前の文字を0回以上繰り返す(強欲) |
++ | 直前の文字を1回以上繰り返す(強欲) |
上のほうで?、*、+は「欲張り」だと書きましたが、「欲張り」な量指定子も“ゆずる”ことがあります。
対象文字列が『"something"
』だとして、検索文字列『".*"
』はこれにマッチします。
しかし、強欲な量指定子『*+
』に置き換えて『".*+"
』とするとマッチしません。
これはなぜかというと、「欲張り」な量指定子を使った『.*
』の部分は、
最後の『"
』がなければ『something"
』にマッチすることになりますが、
正規表現の最後に『"
』があるために、対象文字列の最後の『"
』をゆずっているのです。
『.*+
』の部分が『something"
』にマッチしてしまい、
強欲な量指定子をサポートしていない言語、ツールでも、「アトミックなグループ」というものが使える場合があります。
アトミックなグループでは『(?>foo)
』という表記を使います。
『\w?+
』なら『(?>w+)
』、『\w*+
』なら『(?>w*)
』、『\w++
』なら『(?>w+)
』で代替できます。
『*
』の「直前の文字の0回以上の繰り返し」はよく気をつけないと、間違ったものにまでマッチしてしまいます。
リテラル文字と文字クラスは「文字自体」にマッチすると書きましたが、
『-*
』というような表現は、『-
』や『--------
』だけでなく、
なぜそうなるかというと、「0回以上」ということは「なくてもいい」ということだからです。
空文字列へのマッチは、実質上「位置」へのマッチと似たようなものになります。
検索文字列を『-*
』として一括置換すると、
『-
』や『--------
』が置換されるだけでなく、
『-
』が存在しないすべての場所に置換文字列が挿入されてしまうことになります。
正しい正規表現を書くためには、「どう書けばマッチするか」だけでなく、
「どういう場合にマッチしなければいいか」についても考えてみる必要があります。
*
』≒正規表現の『.*
』とありますが、これは厳密には微妙に違います。
ファイルグロブでは《*
》は「任意の文字を1回以上繰り返す」
つまり、1文字以上あればなんでもいいということになります。
この意味だと、《*.*
》は "foo." や ".bar" は当てはまりません。
しかし、「0回以上」であればマッチすることになります。
正規表現では「1回以上繰り返す」は、《+
》なので、
「任意の文字を1回以上繰り返す」は『.+』となります。
よって、《*.*
》とほぼ等価な表現は『.+\..+
』となります。
これは私の勘違いでした。miauさんご指摘ありがとうございます。
「*.*」は foo. にマッチするはずだし、.bar にマッチしないのは、「*」がドットファイルにマッチしないっていう特殊ルールがあるから・・・ですよね?
ファイルグロブの《*
》は、「0回以上繰り返す(ただし例外として、一番最初のドットは表せない)」ということのようです。
《*.*
》とほぼ等価な表現は、正しくは『(?!\.).*\..*
』となります。
正規表現を使うにあたっては、検索対象がどのようなものか知っておくことが重要です。
『\d{4}[-/]\d{1,2}[-/]\d{1,2}
』で日付と思われる文字列を検索することができますが、
これは『00-0000-00-00
』というものにもマッチしてしまいます。(『00-0000-00-00
』)
しかしこれを厳密にしようと思えばかなり複雑な正規表現になってしまうので、
どの程度の厳密さが必要かを把握しておくことが肝要と言えるでしょう。
冒頭にも書きましたが、正規表現は、言語やツールによって微妙な違いがあるので、
その辺りについては各言語、ツールの説明を参照してください。
本格的に学びたい場合はオライリーの「詳説 正規表現」がおすすめです。
(ただ、この本はプログラミングのことを多少は知らないと難しいかもしれません)
また、PHP正規表現チェッカーですぐに試せるようです。
b:id:K-Onoさんの
について。
実ははてなダイアリーもある(d:id:sleepwlk)んですが、長いこと書いてなかったので、
匿名ダイアリーのほうが多くの人に見てもらえるのではないかと思ってこちらに書いてみました。
*2008-09-23 誤記の修正と、一部加筆しました。
*2008-09-24 ワイルドカードの記述を修正しました。
*2008-09-24 文字クラスの記述の間違いを修正しました。b:id:FunnyBunnyDizzyさんご指摘ありがとうございます。
オタクは自分の本能に従っている。
博学というのは理性に従っている。
「オタク/博学」「本能/理性」の二分法がテキトーすぎる。だから、
社会性というのは他人とのコネクションのことを指すので、
そして、そこには理性的な努力が必要だったりする。
の部分で論旨が混乱してる。理性的な努力が必要な領域に関わっているオタクがいるのであれば、「理性に従ったオタク」と「博学」の差はどうなるの? 今書かれている文章だけだと、リテラルには破綻しているようにしか読めない。さらにいえば、そもそも「社会性」と「オタク社会の中だけで通用する社会性」を分けるためには、「社会」と「オタク社会」の差を明確に指摘できないとダメなんだけど、そこはどう考えてるの? 分析的な文章が書きたいのであれば、イメージに頼らないようにすべきだと思う。たとえ匿名で緩く書き込める場であっても。
以前「オタクはルサンチマンで説明できる」とかなんとか言って、ボコボコにされながら粘着していた天然クンを思わせる……。
ついで。
http://anond.hatelabo.jp/20070428012327
(東浩紀しかそんなこと言っていない)
http://anond.hatelabo.jp/20070428015502
(このレスをしてるのが元エントリの増田かどうか確証はないが)なんだ、無知かと思って反応してみたらただの馬鹿なのか。がっかり。
世の中、大と小だけじゃないけど、
大と小で表現するわけだ。
なんで? 大と小で表現する必然性ないじゃん。
それどころか、分析対象に中間領域があるってわかっているなら最低でも大・中・小に分けて分析して表現するべきじゃないのかね。
複雑さの度合いが「現実>分析」なんてのは当たり前の話。その中でどこまで分析の精度上げていけるかが大事。その努力を怠る奴が、知った風なことをほざく権利はないね。たとえ増田でも。
しっかし釣りにしてもツマランなぁ。以前の天然クンはなかなかにアジがあったのに。
http://anond.hatelabo.jp/20070428012327 の追記3
理性ってなんなんですかね。人間の本能の一部じゃないのかな。
生物学的な意味での「人間」に、何の教育も与えずに孤独に放置しておいても「理性的」な振る舞いができるようになるんだったら「人間の本能の一部」だろね。一時期、認知科学方面でそういう発想に基いた研究が流行ったけど、今どうなってんだろうなぁ。まあ、きっちりと証明されていない以上、フツーに「(人間の)理性とは後天的に身につけることができる論理的思考能力のことで、対比物は『悟性』」とか考えたら良いんじゃないのかなあ。俺も哲学シロート同然なのでなんともいえんとこだけど。