はてなキーワード: SCHEMEとは
2009.05.08 長すぎて1つの記事では全てを表示できないようなので、2分割しました。
「爆発音がした」まとめ 上 - http://anond.hatelabo.jp/20080506041614
「後ろで大きな爆発音がした。俺は驚いて振り返った。hydeは156cm。」
爆発(ばくはつ)とは、急速な膨張を言い、一般的には気体の急速な熱膨張を指す。
専門家の間では、燃焼による爆発の内、膨張速度(炎の伝播速度)が音速に達しないものを「爆燃(ばくねん)」、膨張速度が音速を超えるものを「爆轟(ばくごう)」と呼んで区別することがある。これは、爆燃が衝撃波を伴わず、被害が比較的に軽微であるのに対し、爆轟は衝撃波を伴い(時には数百mから数kmの範囲で)甚大な被害を及ぼすからである。
「爆発音がした」ということなので、早速ふりかえってみることにしました。詳細は以下より。
「どかーん!!。まあ爆発ですわ・・・る」
「まぁーた来たやがった…全ての始まりと終わり!この世界の創造と破壊の爆発が!!だがこれが最後だ…いけぇぇぇ!!」
「クソッ、また俺を狙って組織が動いたか・・・!」
「後ろで大きな爆発音がしました。その時私は隠れ家的お店にいました。
頑張った自分へのご褒美です。女性の鬱にも勝てますよ。
自立した大人の女性です。ワーキングビューティーとも書きます。
なので私は振り返りました。」
nice bakuhatsu.
「来るぞ・・・来るぞ・・・ 来たぁーー!!」
「爆発を爆発と見破れない人には(振り向くのは)難しい」
「爆発で死にそうになったら働く」
「俺の後ろで爆発音がしたけどめんどくせえから寝た。自宅警備も大変だな。」
「また大阪か」
「ちっ…ついにやつらここをかぎつけやがったか…」
ブラッディ フォーチューン
「振り返り様、俺の右腕に宿る"血塗られた運命"が騒ぎ出す…」
「くっ…近すぎるぜ…"こいつら"が"生贄"を求めている…」
「なんだ爆発か・・・」
「地球が爆発すればいいのに」
「振り返る服がない」
「後ろで大きな爆発音がした。きっと工作員の仕業に違いない。」
スレタイ:今後で爆発音がしたんだが
本文:安価>>10
ズン、と腹に響く爆発音が、オレの頭の約5メートルほど後ろから聞こえたお。腹に響くといえば、オレはまだ昼飯食ってない。もうだめぽ。仕方がないから振り返ろうとしたら、首が回らないことに気づきまくりんぐ。そういえば今朝、寝違えたことを思い出したお。どうするか……そうだお!右向きじゃなくて左向きで振り返ればいいだろ……常識的に考えて……オレはかくして昼飯に思いを馳せながら、後方を見るべくゆっくりと左向きに振り返った。なにもねえwwwwwwwうぇっうぇっwwwwwwwwwwww
音うぜえw
スレタイ:なんか後ろで爆発音がしたんだけど
本文:もしかして俺の屁?
うはwwwwwなんか音がしたおwwwwうぇうぇwwwwwwww
スレタイ:お前らちょっと後見てみろ
本文:どかーんwwwwwwwwwwwww
爆弾が爆発するのではない。爆発するものが爆弾なのである。
私が金持ちになったのも、金を稼ぐより金を使う方が難しいということに気づいたからだ。
弾言する。爆発とはコンピュータであると。
Dan the Bomber
「俺の背後で大きな爆発音がした。っぐわ!…くそ!…また暴れだしやがった…
奴等がまた近づいて来たみたいだ…俺は邪気眼を使い振り返った…」
私の背後からは・・・。そうだな、赤い濁流とでも言おうか、天を沖さんばかりに吹き上がる炎があったわけだ。その後執った私の行動は、君、判るだろう。自分に火の粉が吹きかからない事象に人は得てして酷薄で、また法悦を抱くものだからね。先に若い女性がプラットホームから車線に転がり出た時―彼女の意思かどうか知る術も無いが―そこに参集してきた彼らの瞳は、様々な内包物が混淆としながらも濡れていたんだ・・・私の奴もそであっただろうな。兎に角、又瞳が濡れるのを感じながら其処を見遣ったんだよ。
「@爆発音 爆発しろっ!」
「爆発音がした。イマココ! L:○○県○○市○○」
bombtter「爆発音が爆発しました。」
[あとで振り返る]
「[爆発][事件][けまらしい][しねばいいのに]
http://d.hatena.ne.jp/finalvent/20090510/1241923485
「こんな大きな音が爆発音のはずがない!」
「おいィ?何いきなり爆発してきてるわけ?」
恥知らずな忍者がアワレにもベヒんもすの盾ができずに背後で爆発したようだったが、リアルモンクの俺はとっさにカカッとバックステッポで避けた。タゲを失った破壊力バツ牛ンのベヒんもすは辺りを漂っているようだったが誰も手出しできないようでただ黙っていたので、たまに行く学校で羨望の眼差しを与える黄金の鉄の塊に身を包んだ俺がふいだまを入れると同時にフラッシュでメイン盾となりグラットンスウィフトを入れ一気にダメージを与えた。これは一歩間違うと全滅の危険をある危険な技だったのでギャラリーが拍手しはじめたが、俺は「うるさい、気が散る、一瞬の隙が命取り」と言うとギャラリーは黙った。
「爆発ってレベルじゃねぇぞ!!」
爆発しました・・・(15)
「爆発に振り返らないたった一つの冴えた方法」
「爆発?いいえ、ケフィアです。」
ニュータイプ「! うしろっ!」
バーーーン(爆発)
アムロ「だ、駄目だ、振り返ったら駄目だ。光と人の渦がと、溶けていく。あ、あれは憎しみの光だ」
「 なら爆発するしかないじゃないか!」
シンジ「逃げちゃ駄目だ逃げちゃ駄目だ逃げちゃ駄目だ」
「何、爆発だってぇ。それが何だって言うんだよぉ」
例えばね、グワッアーン!と、背後で爆発が起こったとしましょう。それで振り返ります。で、「やれやれ」って面倒臭そうに振り返るような、僕はそんな主人公は絶対書きません。
──厭世的ということですか。
それ以前です!あのね、爆発があったら、それが近くであれば先ずエイッって飛び退くでしょ。遠くのことでも「何だ何だ」と振り返る、そういう身体感覚を持っているのが普通です。これは何度経験しても同じですよね、命に関わる事なんですから。だから、こんな鈍感さを持つキャラクターが成立していいのか?ということに自覚的であることは、作家としての最低条件だと思っていますが、今そこら辺を見回してみると、そういった破綻を無意識のうちにやらかしている作品というのは、本当に多いんです。そういうのは、芝居にすらなっていない。
「うしろで爆発音がしたんですね、わかります。」
「後ろですごい音がしなかった?」
*ばくはつのなかにいる*
「振り向く権利をやろう」
「( ゚д゚ )彡そう!」
「樹海を進む君達を衝撃と轟音が襲う。静寂に包まれた樹海を一瞬で蹂躙したその音はどうやら君達のすぐ後で鳴り響いたらしい。君は後ろを振り返ってもいいし、このまま探索を続けても良い」
All your bakuhatsu are belong to us.
「バクハツいっこおきる」
エアリス「うしろ。音した。びっくりぃ!」
エインシャント卿「……」
「おおうしろよ!は"くはつしてしまうとは なさけない」
「ぬわーーっっ!!」
君子「すごいね!びっくりだね!」
「挟まった!」
「バクハツヲ ムシシテ ヘイキナノ?」
「Q:この音はガスが爆発したのですか?
A:いいえ、爆発したのはトムです。」
「この音はおならですか?」
「いいえ、それは爆発です」
「48発の爆弾が爆発しました。最初に用意した爆弾のうち、20%が不発だったとすると、最初に用意した爆弾は何発だったでしょう?」
「どこに座標系をとるかによって誰が爆発したかが変わってくる。」
「爆発…ですかね」
クルーグマンは発言をコロコロ変えるので有名だが、爆発についての意見はとっくに撤回しており、爆発派の間でこのような不毛な議論が続いているのは日本だけである。この本は、翻訳が下品なことに眼をつぶれば評価できる。
「あの時はどうしてあそこを通っちゃったのかなぁ…
夜道をですね、1人で歩いてたんですよ。ある番組の打ち上げがありまして、
ちょっと一杯引っかけて、ああ、夜風が気持ちいいなぁ、なんて思いながら。
するとですね、突然後ろから聞こえてきたんです。ドカーーーン!…って音が。
あたしゃビックリしましてね。ガス爆発なのか、それとも事故なのか。
でもね、本当の爆発なら衝撃っていうか、爆風みたいなのがありますよね。
それをまったく感じない。こりゃこの世の音じゃないな、そう確信しましてね。
ちょっと酔っ払ってたのもあって、よせばいいのに
脅かすならやってみやがれ、って振り返っちゃったんです」
「ぶははははwwwここは中東かwww」
「爆発だああああああああああああああああああああああああああああああああああ」
「プラズマだって何度ry)」
「ドカーンと爆発がしましたが何か問題でも」
小倉「僕はねえ、これはいつか爆発するんじゃないかなと思ってたんだよねえ、デーブ」
デーブ「アメリカでは、以前からこの事問題になってたんですよね」
「いいですか、村田さん。あなたはね、簡単にね、爆発とね、言いますけどね。これはね、ただの爆発じゃないんですよ。グローバル化した、アメリカ中心の、国際社会の中で、…違いますよ。最後までちゃんと聞きなさいよ。誰もそんなこと言ってないよ。」
「爆発音を聞いてどう思った?」
「ギョギョーーーー!!!!!!!」
「爆発すると思ったので振り返った」
「ずっと爆発すると思っていました」
「(爆発音の後で)別に」
「爆発したんです!」
神保:「これはさあ、要するに爆発しちゃったって感じなんだけど、宮台さんなんか言うことある?」
宮台:「これはまさに、バカな田吾作どもによるケツ舐め爆発って奴ですね。その点においては、右も左もなんら変わらない」
浜田:「ほんで?」
松本:「ほんなら、いきなり後ろからバーン爆発ですよ」
浜田:「またまた~」
松本:「いや、ホンマやねんって!」
「これは言ってみれば、自衛隊が自分で爆発させたようなもんでね。1 発の爆弾が 2 発になれば 2 発の爆弾が 1 発になったときより余計爆発するわけだから。みんな米軍がやった米軍がやったって言っておるけれども、米軍にはそんな能力はないし、自衛隊だけでじゅーぶん爆発させられる。だから、これは言ってみれば…」
「エクスプロージョン!」
「欧米か!」
「バックをルックするぜ!」
「大柴か!」
赤川一平「姉さん事件です」
「そしたら大きな爆発音がしたの。まあ嘘なんだけどね」
「そしたら、アンタ、どうなったと思う?」
「爆発した…?」
「爆発物は単なる機械であり、宇宙の決定論的な性質により爆発は起きた。」
(ドーン)
「どうだ今の爆発は、驚いただろう……そうか、驚いたか。
我輩もちょっと驚いた。
実はリハーサルの時はもっと小さな爆発だったんだ……まあそんなことはどうでもいい!」
「爆発物に見入る者を、爆発物もまた見つめ返す」
「金星人だ」
太田「そしたらその人、爆発しちゃって」
田中「なわけねーだろ!なんで爆発するんだよ!」
「まさかとは思いますが、この「爆発音」とは、あなたの想像上の存在にすぎないのではないでしょうか。」
「瞬間、私は怒りを爆発させた」
「うわぁ~、爆発やぁ~」
「習慣と習癖の結果、爆発が起きた。」
「どかーんなんつって、爆発しちゃったりなんかして~ このぉ!つんつん。んもう、振り返っちゃうよ?この~ウスラトンカチのチョンチョン」
「仮に爆発があったとしても、何がいけないんですかねぇ?」
「いま何やら爆発音がしたようですね。ちょっと心配です。ではお天気いきましょう!市川さん!」
「どうなのよみなさん?もうね、爆発してもらいたいね」
「ほんならー、後ろでドッカーン爆発しましてー、ほいでもう石やらなんやらがボンボン飛んできてー、そばにおった子供なんてもうこんなんですよ(立ち上がって実演)」
「森永さん。アナタねえ、爆発とかいうけどねえ、いままでにねえ、日本で爆発があったことがありますか? だいだいねえ、アナタみたいなトンチキな奴がいるから日本はダメなんだよ。アナタのお父上は立派な人だったけど」
「爆発音を聞いて振り返ると脳が活性化するんですよね」
「いやだからー、これは単に、爆発させたいから爆発させちゃったってだけなんですよ。だってぇ、○○省が出した答弁の中にぃ、爆発ってちゃーんとかいてあるんですもん。結局、 ○○省の連中はみんな爆発させたいだけなんですって。」
「田原さん、それはちょっと違いますよ。確かに、自民党の中にも爆発させろと言ってる人もいます。でも…」
「それは具体的に誰?」
「それはちょっと言えないですけど(言いよどむ)、自民党はそんな党じゃありませんから」
「後ろで大きな爆発音がしたが笑ってごまかした」
「藪からスティックにエクスプロージョンするなよー、カッ!」
「BackでbigなExplosionがしてよ~俺はAmazedでlooked backしたのさ!」
「スッと行こうとしたらバンときた」
「そらそんなん(大きな爆発音が)あればそう(振り返る)なるわな」
「なんでそんなんを、ばく発のアレを言われなアカンのや!」
「そらそうよ」
「爆発したから振り返った。それだけ。」
「爆発音が起きただけで声の上がる日本サポーター。ああ、いやだいやだ。欧州ではこんなことが当たり前だと、なぜ分からないのか。バルセロナの方角を向いて、思う。私は、ただ、嘆くばかりだ。」
歩いていたら
爆発したんじゃ
まじ驚いたわ
「いわゆるひとつのエクスプロージョンがですねぇ、こうドーンと」
「振り返っていく」
「(後ろで爆発があったことを)知らなかった。」
「今回は結果が出ませんでしたが、修正すべきところは修正して、次に繋がる爆発をしていきたいと思います。」
「後ろで大きな爆発音がした。『オッケーイ!』俺は驚いて振り返った。」
「急に爆発が起きたので」
くり返す この爆発
あの衝撃は まるで戦争
振り返る いつかみたいな
あの光景 甦るの
くり返す この爆発
あの反動が うそみたいね
くり返す この爆発
ああ手榴弾 みたいな恋だ
またくり返す この爆発 この爆発
ハァ
空母も無ェ 戦艦も無ェ
戦車もそれほど走って無ェ
ヘリも無ェ ミサイル無ェ
軍曹 毎日ぐーるぐる
朝起きて イージス艦
二日ちょっとの 演習中
携帯無ェ パソコン無ェ
スパイは一日一度来る
俺らこんな爆発いやだ 俺らこんな爆発いやだ
爆弾貯めて 東京でテロするだ
かっくん:「お兄さんは最近なにやってるんですか?」
うらら兄:「今度は、保管専用爆弾ってのを考えたんだよ。」
かっくん&うらら:「保管専用爆弾?」
うらら兄:「ほら、アメリカとかロシアとか、いっぱい爆弾持ってるけど、全然使わないだろ? だから、保管専用爆弾ってのがあれば売れるんじゃないかと思って。」
うらら:「でも、保管しておくだけだったら爆弾の意味ないじゃない?」
うらら兄:「だから、実際には爆発しなくてもバレないんだよ。」
歌:「はい木久翁さん」
木:「布団屋の後ろの地面が爆発しました。」
「世界にはさらに驚くべき爆発があった!」
「っと、その時後ろで爆発音が。ボブが振り返ったそこには!
・・・
3ヵ月後、そこには元気に走り回るボブの姿が!」
「もう僕二度と爆発なんてしないよ!」
桂小枝「シオアル?」
ハチ「ねえナナ、あの日の爆発を覚えてる?あの爆発はもうないよ」
「その時、田中の背後で爆発がした。
プロジェクトに暗雲がたちこめた。」
「背後で爆発があったとということだが、一発だけなら誤射かもしれない。」
「背後の爆発を見るため、振り向くよう求める声も高まった。だが、心配のしすぎではないか。 」
「先程のニュースの中でお聞き苦しい爆発音がございました。謹んでお詫び致します。」
「そのとき、歴史が、動いた」
「岩石蒸気に襲われた世界では雪は瞬時に溶け、川を作るまもなく蒸発していきます」
『「われわれの敵がい心が爆発すれば…」 北、日本の先制攻撃論に反発』
「爆発?なあに、かえって免疫力がつく。」
「現場付近の爆発速度は毎秒約20メートルで減速規制するほどでなかったというが、 平時と同じ時速約100キロで最上川の橋梁(きょうりょう)を渡ったことに問題はなったか。 爆発とは言いながら、 風の息づかいを感じていれば、事前に気配があったはずだ。 」
「爆発音(ガイア)が俺に早く振り返れと囁いている」
「なんでやねん!」
「オーマイガ!」
「いやー、オイの後ん方ででっかか音のきこえったたい。そいでびっくいしたけん、目ばそこんほうにむけたとばってんがね。」
後方大爆音我驚振向
「初めに爆発があった。神は七日後に振り向いた」
子曰く「吾十有五にして爆発す。三十にして振り返る。」
「そもそも、爆発とはなんぞや?」
後ろでの爆発音に続く処理を表すものが継続です。
1000 1001 1000 0010
「芸術は爆発だ!」
「多すぎて爆発した」
「爆発音がした」まとめ 上 -> http://anond.hatelabo.jp/20080506041614
くわしくはトラックバック先の記事やはてなブックマーク等をご覧ください。
はてなブックマーク⇒http://b.hatena.ne.jp/entry/http://anond.hatelabo.jp/20090508095607
ついかもときどきしていきます。
ツールにひっかかるから、ですらないと思う。単にそういう技が必要なくなっただけ。 そもそもexploitに晒されるほどポピュラーでかつOSの動的リンク機能が使えるほど近代的な環境になってさえ、動的コードセグメントを使ってまで最適化スピードアップしなきゃいけないような変態的ケースは今じゃ殆ど無いんじゃねーの。ゲームかPC DEMOくらい? ひょっとしてケータイでもそういうことをやるのだろうか。 そもそもそれ以前にアルゴリズムの改善とかアーキテクチャの見直しとかできることは山ほどあるような気もするが。 というかツールで監視するくらいならCPUの保護機能でオフにするんじゃないのという気もする。
人工知能的なことをやりたいのであればCは圧倒的に不向きで、そもそもevalがある言語(Python/Ruby/etc..)使えばいいんじゃねーの、という話になる。もちろん Lisp/Schemeもそうだけど。。。
(追記に対してレス…)
void *(*psrc)(void *); void *pdst = (void *)psrc; 究極 printf("%x\n",(int)psrc);
そーいうのは曖昧と呼ぶの? どちらもC言語的には未定義動作で、単にコンパイラがこういう風にコンパイルしますよということが分かっているから書くのだし、何もambiguousではないよね。
そーいうことはxbyakとか使えば楽にできるとおもう
下向いちゃうしww
strip_tagsとかでサニタイズなんてされたら・・・・もう最悪ww
常識的に考えて欲しいだけなんです!
「phpできます!」なんて自信たっぷりに言われた時の恥ずかしさとか分かる?
あのね? たとえば週末10〜20人ぐらいで勉強会とかするでしょ?
みんな普通にDやSchemeやErlangやHaskellで構築するわけでしょ
http://anond.hatelabo.jp/20081111000645
VRアダルト動画おすすめ
オナホールのレビューと評価のランキング
ピンクローターJp:おすすめバイブ評価とローター通販の比較
ソーシャルゲーム速報
いま就職活動中なのにふと思い立ってScheme勉強しだした。
このサイト見ながらいまセクション4まですすんだとこ。
ぜんぜんよくわからんかったが、Edwinってエディタで四苦八苦しながらすすんでるとすこし面白くなってきた。
あれだな、このエディタもはじめよくわからんかったけど使い出すとよく考えられてる気がする。NetHackみたい。
しかし、なにより。
なんつうか、自由だな。これ。…すげー開放感!
自分で関数のうごきとかきめたりとか、こーゆーのって『当然』で、すごくすごくあたりまえなことなんだろうけど
どうにも既成概念に縛られまくってた自分からしたらめちゃめちゃ驚愕に値することだわ。
今、実際庶民として生きてたら、ゲームの中なんていうまでもなく、日常生活にしても、僕らのコマンドはある程度決まってるように見えてるじゃん。
実際、そう見えてるだけなんだけど。
ファイル保存するときにCtrl-x, Ctrl-sって押下するように、高校でも大学でも課外活動でも恋愛でもほとんどすでにコマンドは決まってる。
関数を自分で定義するって言うすごくしょーもないことだけど、そっから見ればありえない開放感だよ。これ。
昔っからプログラミングしてた人たちはこーゆー開放感をずっと味わってきたのか…!しかも自然に…!
なんとうらやましい!今の微かな直感だけでも言えるけど、この開放感はなによりも人格形成に影響を及ぼすわ。
そりゃ、dankogai氏みたいな人もでてくるわな。そんだけ。なんかたのしい。
(/ 2 3)の動作を暗記するのと、これを "divide 2 by 3"と読むのは違うからな。これがひとつならともかく、積み重なってくると骨が折れそうだ。( subst a b c )を"substitute a with b in c"と読めるかどうかで記憶効率も違うし。と、Scheme知らずのOld Lispユーザーがつぶやいてみる。
前回から随分間が開いてしまったんだけど、その2。中高一貫校に通う15歳男子のプログラミング独習記。
http://anond.hatelabo.jp/20080201001641 (その1)
さっそく文字通り初歩的な問題、すなわち練習問題をどう解いていいかわからない、という壁にぶつかったのである。
Schemeではすべて(仕事 A ... B)という形で表現される、らしく、
例えば、
5*5/2なんかは、
(/ (* 5 5) 2)と書く、と。
(sqrt A)や(expt A B)なんかで数学的な処理も可能らしい。
で練習問題で、
Find out whether DrScheme has operations for squaring a number; for computing the sine of an angle;
and for determining the maximum of two numbers.
ってあるんだけれど、これって何?ということなのです。
DrSchemeで"2乗"するのを、(sin A)とかで確認しろってこと?
determining the maximum of two numbersっていうのもよくわからない...
どなたかへるぷみー。
前回から随分間が開いてしまったんだけど、その2。中高一貫校に通う15歳男子のプログラミング独習記。
http://anond.hatelabo.jp/20080201001641 (その1)
さっそく文字通り初歩的な問題、すなわち練習問題をどう解いていいかわからない、という壁にぶつかったのである。
Schemeではすべて(仕事 A ... B)という形で表現される、らしく、
例えば、
5*5/2なんかは、
(/ (* 5 5) 2)と書く、と。
(sqrt A)や(expt A B)なんかで数学的な処理も可能らしい。
で練習問題で、
Find out whether DrScheme has operations for squaring a number; for computing the sine of an angle;
and for determining the maximum of two numbers.
ってあるんだけれど、これって何?ということなのです。
DrSchemeで"2乗"するのを、(sin A)とかで確認しろってこと?
determining the maximum of two numbersっていうのもよくわからない...
どなたかへるぷみー。
私はプログラミング言語を学ぶのに、コンピュータサイエンスは必ずしも必要ではないと主張する。はてな界隈の流れがその真逆であるにも関わらずである。(結局のところこの話題には「初心者・入門者」が誰なのかをきちんと規定していないので、どんな言語でも「初心者向け」と主張できる。)
プログラミングをするのはプログラマだけとは限らない。数学者、物理学者など、数学を利用する分野の学者はMATLABやMathematicaなどを利用するのはもちろんのこと、家計簿をつけるお母さんがより便利に家計簿をつけるためにExcelVBAを学んでもよいわけである。
ホッテントリを眺めていると、プログラミング入門の話題がいつのまにか、コンピュータサイエンス入門へとすりかわっている。例えば、SchemeやCを推薦する記事などがそうである。はてなの流れはまずコンピュータサイエンスありきなのである。はじめにコンピュータの動作原理を知り、これからも変化の絶えないプログラミングの世界を渡り歩く力を求めるのである。(少なくとも、センター試験の数学に出てくるBasicにはコンピュータサイエンスのかけらもなかった。)しかし、それは前述した学者やお母さんには牛刀で鶏をさばくような、大げさなものなのである。
http://anond.hatelabo.jp/20080201001641:title
こういうの見るとやはり梅田望夫や羽生直也は正しいこと言ってると思う。
ただこいつの環境っていう面もあなどれない。親がおそらく優秀なプログラマだってことはなんとなくわかるし、
SICPは中学英語で読めるようなもんじゃないから帰国子女の可能性もある。
昨日親に話してみたら、Structure and Interpretation of Computer Programsっていう本を勧められて、
今度はHow to Design Programsっていうもっと入門編の本を教えてくれて
こんな親父なかなかいない。
エスカレーター式私立中学校に通う男子のプログラミング独習記。(Scheme/DrScheme)
本来高校受験を目の前に控えているはずなんだけど、怠けの坊ちゃん学校にはそんなものもなく教室の空気は緩んでいる。
3年前になんだかんだで部活動に入りそびれた僕は、際立ってダラダラなカテゴリに属す。
ベタにギターをやってみたり、携帯のオンラインRPGにハマったり、プロフで女の子と会ってみたけどあまりしっくりこない。モバも飽きた。
唯一ハンズで買った財布づくりキットみたいなヤツをきっかけに革を触って何か作ったりするのは続いてる。革の裁断面を磨きまくるコバ磨きをしていると何故だか落ち着く。
僕のことばかり書いてても仕方ないな。で、なんか中学生活で達成したとかそんなの全然ないし、高校生活に胸をときめかせるとかもなくて。
それじゃああんまりだと言う事で、何か新しいことを始めたいなぁと思ってたんだ。
ちょうど親がプログラマーで、(全然パソコンには詳しくないけど)モノをつくるのも好きだし、やってみようって気になった。
昨日親に話してみたら、Structure and Interpretation of Computer Programsっていう本を勧められて、MITっていう大学(?)のサイトで見てみたけど難し過ぎた。
ってそのままお父さんに言ってみたら今度はHow to Design Programsっていうもっと入門編の本を教えてくれて、これ以上簡単な解説書はないからもうこれでわからなかったら諦めろと。
なんだか悔しいし、どうにかしてモノにしたい。早速MITのサイトから100ページ分ぐらいダウンロードしてみた。
親に聞くのもイヤだし、(いつの間にかできるようになってたい)2chもそれ関係のスレはマニアック過ぎて謎過ぎたからここで書いてみる。
書いてることが間違ってたらぜひぜひ教えて欲しいです。
今日は最初の12ページ分。なんかプログラミングって何?とかプログラミングを学ばなきゃいけない理由とかが書いてあった。
プログラミングって、職業的なスキル以上のものになってきてる。
すごく楽しいし、創造性のはけ口になるし、抽象的でふわふわしたアイデアを目に見える形で表現できちゃったりする。
(このアイデアを形にする手段、っていうのはなんかイイなと思った。やっぱりなんかひとりでモノをつくれる人は尊敬できるなぁ。)
プログラミングはクリティカルリーディング、分析的思考、創造的統合(?)、細部へのこだわりを教えてくれる。
(創造的統合って何だろう?creative synthesisっていわれるとイメージはできる気もするけどうまく言葉にできない。
複雑なものをformingするってことだよね。多分...)
さらに何がイイかって、すぐにフィードバックが返ってくるところ。
冒険的、実験的になれるし、自己評価もできる。達成感を味わうっていうのもあるみたい。数学のドリルをするより全然。(確かに目に見える何ができるって励みになりそう)
この本ではプログラミング言語の細かいところとかにはあまり触れずに、デザインプロセスに焦点を当てる。
つまり問題定義からオーガナイズドされたソリューションまでの一連の流れについて語る。
2つのイノベーションがこの本にはあって、以下。
まず一つ目。今までの本は抽象的でクソみたいな定義の提案しかしてこなかった。例えば「デザインはトップからボトムに」とか「構造的にデザインしろ」とか。
この本には明確なステップがあって、読むこと、分析すること、組織化すること、実験すること、システマティックに思考することを学べる。
二つ目は、初心者向けのプログラミング環境であるということ。既存の本は周りにプログラミングのプロがいて、すぐにその人に質問したりできることを前提に書かれていた。
この本はそういった意味の分からない前提は捨てて、独習できるように設計してある。
1. 問題のデータのかたまり(problem dataってなんだ?)を記述する
3. 挙動を図にしてみる(例をつくる)
4. プログラムの型(program templateってなんだ?)やレイアウトをきっちりつくる
5. テンプレートを変形して、完全な定義をつくる
(なんかプロセスとしてはわかりやすいけど、抽象的でプログラミングしたことのない僕には雲をつかむような感じ...
inputデータの記述からどうやってprogram templateが得られるんだろう?1→2がよくわからない)
1. ある数とある数を関係づけること
2. 名前の代わりに値を用いることで、関係を評価する
ってこと。(これもわかったようなわからないような。1はinputとoutputの間の話?2は数値化するってこと?)
最初はトラップやドリブル、パス、シュートの仕方を学んで、次はあるポジションの役割を学んで、戦略を学んで、どの戦略を選ぶかを学んで、時々新しい戦略をつくったりもする。フィットするヤツがない場合はね。
彼らが楽器の技術や書く技術、建築の技術を学んでアイデアを形にするように、プログラマーもプログラムを学んでモノをつくる。
この本ではSchemeというプログラミング言語を使う。開発環境はDrSchemeで行う。
ただこの本はSchemeの解説書ではないから、Schemeの構成概念の6つだけを使う。
function difinition、application、conditional expressions、structure definition、local definition、assignmentsだ。
---
とりあえず1回目はこんな感じ。
まだ全然良く分かってない。ただ親が使ってるのがlispっていうプログラミング言語で、Schemeはその方言みたいなものってことは今調べてわかった。ふーん。
まだ何がわからないっていうか全部わからないので、アドバイスのしようもないとは思いますが、最初はこれやっとけ!とかこのサイト読めとかあったら教えてください。
ただ、RubyとかLLとかいう単語が大した脈絡もなく出てくると「ああ、またか」
って感じがして一気に興ざめるんだよね。
たとえばRubyの言語としての能力を語るときに、ルーツとして
SchemeやC++やPythonに遡及するのは必然的なんだけど、Rubyどっぷりの人は
いつも話題がRubyどまりでそこから進展することがない。ここまでステロタイプな
信者ではないにしても、事あるごとにRubyやらLLやら言い出す人は
「俺、ちゃんと流行に乗っかってますよ」的な言外のメッセージを出しすぎていて、
いくつか考えてみた
(問1)高階関数と再帰関数を必ず使って数値を要素とするリストの要素の総和を求める関数を書け。ただし高階関数を使うという要件と再帰関数を使うという要件は同じ関数で満たしてもよい。
(問2)二つの引数をとり二つのうち大きいほうを返す関数と高階関数、再帰関数をつかって数値のリストの最大値を求める関数を書け。ただし高階関数を使うという要件と再帰関数を使うという要件は同じ関数で満たしてもよい。
というのは簡単すぎるか?簡単すぎるなら
(問3)高階関数と再帰関数を必ず使ってある数値に5を足し、10かけて2で割った数を求める関数を書け。ただし高階関数を使うという要件と再帰関数を使うという要件は同じ関数で満たしてもよい。
こっちの方がいいかな。でもトリッキーすぎる気もする。
一応問題を出したので、SchemeとPythonで自分で想定している答えを書いておいた。はてなではSchemeが人気のようなので、あまり知らなかったけど関数言語ではSchemeで書いておいた。Pythonで書くのはSchemeだけだとわかりにくいので、なにかスクリプト言語で書いておこうと思ったから。Rubyの方が人気なので、はじめはRubyで書こうと思ったけど挫折した。だれかRubyで書いてくれないかな・・・。コードオブジェクトってなによ。というか関数はオブジェクトなのに引数にできないの?なんで?(以下疑問と愚痴の嵐なので略)Perlは古株が多くてユーザー数も多そうだけど、・・・その・・・無理です・・・。あの言語仕様はやる気がしない。ぶっちゃけ理解できない。Pythonを知らないひとは多そうだけど、知らなくてもSchemeよりは感じは掴めると思うのでPythonでも書いておくことにした。
http://anond.hatelabo.jp/20071110215936
http://anond.hatelabo.jp/20071110220132
これで大部分のひとがこの問題に興味をもたなくて解答するひとがいなくても、興味を持ったひとは安心だね!
追記:
問3で次のは無しとしておきたい。
(define continuous-apply (lambda (lst obj) (cond ((null? lst) obj) (else (continuous-apply (cdr lst) ((car lst) obj)))))) (define plus5 (lambda (num) (+ num 5))) (define times10 (lambda (num) (* num 10))) (define divide2 (lambda (num) (/ num 2))) (define plus5-times10-divide2 (lambda (num) (continuous-apply (list plus5 times10 divide2) num))) (plus5-times10-divide2 2)
def continuousApply(lst, obj): if lst: return continuousApply(lst[1:], lst[0](obj)) else: return obj def plus5(num): return num + 5 def times10(num): return num * 10 def divide2(num): return num / 2 def plus5_times10_divide2(num): return continuousApply([plus5, times10, divide2], 2) plus5_times10_divide2(2)
あくまで自分でこう答えるという話。
(問1)
(define fold-left (lambda (func obj lst) (cond ((null? lst) obj) (else (fold-left func (func obj (car lst)) (cdr lst)))))) (define my-sum (lambda (lst) (fold-left + (car lst) (cdr lst))))
・例
(my-sum '(1 2 3 4 5 6 7 8 9 10))
(問2)
(define fold-left (lambda (func obj lst) (cond ((null? lst) obj) (else (fold-left func (func obj (car lst)) (cdr lst)))))) (define large (lambda (x y) (cond ((>= x y) x) (else y)))) (define my-max (lambda (lst) (fold-left large (car lst) (cdr lst))))
・例
(my-max '(58 90 1 2 4 3 100))
(問3)
(define fold-right (lambda (func lst obj) (cond ((null? lst) obj) (else (func (car lst) (fold-right func (cdr lst) obj)))))) (define my-apply (lambda (func obj) (func obj))) (define plus5 (lambda (num) (+ num 5))) (define times10 (lambda (num) (* num 10))) (define divide2 (lambda (num) (/ num 2))) (define plus5-times10-divide2 (lambda (num) (let ((lst (list plus5 times10 divide2))) (fold-right my-apply (reverse lst) num))))
・例
(plus5-times10-divide2 5)
全部畳み込み関数を使っているのは、はじめ使い道がないと思ってたのにかなり使い道があることがわかったので、それを示したかったから。あとmap関数あたりはほかの言語でもあるから、すぐに思いつくだろうし。
というか最後のやつは手続きを抽象化することでリストの形で扱えるようにしているから、関数プログラミングでは重要だと思う。関数プログラミングの肝は計算によって手続きを含めたすべて表すことができることだと思っている。その例だと思うんだけどね。例えばSchemeなら上記の答えを応用して、似たような「手続き」を生み出す関数を作ることができる。
(define make-proceduce (lambda (fst . rest) (let ((lst (cons fst rest))) (lambda (num) (fold-right my-apply (reverse lst) num)))))
これを使うと次のようにできる。
(define divide2-plus5-times10 (make-proceduce divide2 plus5 times10)) (divide2-plus5-times10 2) (define divide2-times10-plus5 (make-proceduce divide2 times10 plus5)) (divide2-times10-plus5 2)
関数合成がつかえるならそっちのほうが楽だけど、リストという形で「手続き」をつくり出していることがわかるだろうか?手続きをリストで操作できるのだ。こういうのが関数プログラミングの肝だと勝手に思っている。
こうやってくると型推論や多相型の重要性もわかると思うんだよ。上記のようなことはPythonでもできる。でも高階関数はつかいすぎるとわかりにくい。どっかにバグが入ってくるかもしれない。それを機械的に防ぐのが型推論。型という観点から型推論でおかしいところを探し出してくれる。それならC言語でもいいのではないかという人もいるかもしれない。だがC言語は融通が利かない。例えばapply関数にしても引数の型が数値なら数値、文字なら文字と決まっている必要がある。だから数値に向けにapply関数を作っても文字には使えない。こうした型のデメリットをなくす一方、そのメリットを享受するためにあるのが多相型。これによってapply関数やmap関数を一般的に作ることができ、型のメリットを享受しながらデメリットをなくすことができる。このように関数で手続きなんかを抽象化するときに型推論や多相型があると便利なのだ。
http://anond.hatelabo.jp/20070910101211
かっこいい..
http://anond.hatelabo.jp/20070910063901 を書いた者ですが,
確かに2回文字列を走査するのは無駄っすね.グローバル領域を汚してるし.
私の書いたコードはschemeの長所を生かせてないと思ってました.
発祥: http://ex23.2ch.net/test/read.cgi/morningcoffee/1188654905/
Scheme という Lisp 語族の言語を用いて ℃-ute の相関関係をプログラムし、様々な角度から関係性を分析する手法を紹介していきます(ソースコードは最後に張ります)。
まずは、メンバー間の関係を「リスト」というデータ型で表現します。例えば「栞菜->愛理」という関係は
(kanna . airi)
という形で表すことができます。これに、「大好き」という情報を付加し、ついでにその関係の性質を数値化したものを加えると
((kanna . airi) (desc "大好き") (score . 1))
のようになり、関係図における一つの矢印の情報をデータ化できたことになります(暫定的に、好意は 1、良好・中立は 0、険悪は -1 の3段階で表すことにします)。
メンバー間の全ての関係性をこのデータ単位で定義し、データベース化しておくことで、色んな条件に基づいた検索やスコア計算などが可能となります。
ここで相関関係図における矢印を「リンク」と呼ぶことにして、あるメンバーから他のメンバーへどのようにリンクし、またリンクされているかを調べることができます。
(sort-nodes (number-list (from-links)))
結果:
((kanna . 6) (saki . 5) (maimi . 4) (erika . 3) (mai . 3) (chisato . 3) (airi . 2))
栞菜ちゃんがメンバー全員にリンクを張っていることが分かり、℃-ute ラブっぷりが伺えます。なっきーにも同様の事が言えます。例の「女の子が好き」発言を数値的に裏付ける結果と言えるかもしれません。
ただ、データ不足でリンク件数がまだ少ないのと、リンクの性質(好意/反感など)までは分からない点を考慮する必要があるでしょう。
同様に、リンクの終点の件数を調べてみます。
(sort-nodes (number-list (to-links)))
((chisato . 5) (erika . 5) (kanna . 4) (maimi . 4) (airi . 4) (mai . 3) (saki . 1))
えりかちゃんと千聖ちゃんが高ポイントです。メンバーからの人気や注目度の高さを示すデータですが、千聖ちゃんの場合敵対的なリンクが2件含まれている点に注意してください。
なっきーの被リンク数が極端に少ないですが、単純にデータ不足のためだと思われます。はぶら(ryとか言わないようにお願いします。
リンクに付随するスコアを計算することで、愛情の度合いを測ることができるのではないか、という考えに基づく研究です。
まず、全ての関係性を対象として、スコアがマイナスの関係を抽出してみます。
(filter-nodes (lambda (n) (< (score-relation n) 0)))
結果:
(((kanna . chisato) (desc "愛理に手出すんじゃねぇよ") (score . -1)) ((saki . chisato) (desc "愛理に手出すんじゃねぇよ") (score . -1)))
件数だけを得ると
(length (filter-nodes (lambda (n) (< (score-relation n) 0))))
2
僅か2件です。
良好・中立的な関係は
(length (filter-nodes (lambda (n) (= (score-relation n) 0))))
8
愛に満ちた関係は
(length (filter-nodes (lambda (n) (> (score-relation n) 0))))
16
非常に多いです。舞美ちゃんの「℃-ute同士でラブラブなんですよ」発言(例のラジオ)を数値的に裏付ける結果と言えるんじゃないでしょうか。
次に、メンバーごとのスコアを算出してみます。Lisp 的には以下のようにフィルタリングと畳み込み (fold) で計算することができます。例えば
(foldr (lambda (n acc) (+ (get-score n) acc)) 0 (filter-nodes (cut to? <> 'kanna)))
3
上式を一般化して一挙にメンバー全員に適用してみると
(sort-nodes (map (lambda (x) (cons x (score-loved x))) (all-members)))
結果:
((airi . 4) (kanna . 3) (mai . 2) (erika . 2) (maimi . 2) (saki . 1) (chisato . 0))
愛理ちゃんが好意を寄せられやすい傾向が伺えます。
今度は逆方向のスコアを計算してみると
(sort-nodes (map (lambda (x) (cons x (score-loving x))) (all-members)))
((kanna . 3) (maimi . 3) (chisato . 2) (airi . 2) (saki . 2) (mai . 1) (erika . 1))
まいまいとえりかちゃんが特に堅い・一途だという傾向を読み取ることができます。
今度は組み合わせ(カップリング)の評価です。
2点間相互のリンク・スコアを加算したものを「相性」と考えられるものとします。最大値 (互いに好意を寄せている場合の数値) は現在のスコアリング方式では 2 です。例えば
(score-between 'kanna 'airi)
の値は
2
となります。1 であれば一方通行と考えます。
関係性が未定義の場合もあるので 0 のものを除外して算出すると
(sort-nodes (filter (lambda (n) (not (= (cdr n) 0))) (map (lambda (n) (cons n (apply score-between n))) (all-combinations))))
(((chisato mai) . 2) ((chisato airi) . 2) ((airi kanna) . 2) ((saki kanna) . 2) ((kanna maimi) . 2) ((erika maimi) . 2) ((saki airi) . 1) ((saki erika) . 1) ((kanna mai) . 1) ((maimi airi) . 1) ((saki chisato) . -1) ((kanna chisato) . -1))
となります。若干ピンとこない部分もあるかも知れませんが、計算上は矛盾無くデータの内容を表しています。
(map (lambda (p) (find-relation (cons (caar p) (cadar p)) identity)) (filter (lambda (n) (= (cdr n) 1)) (map (lambda (n) (cons n (apply score-between n))) (all-combinations))))
(((kanna . mai) (desc "喰ってやるよ") (score . 1)) ((saki . airi) (desc "好き") (score . 1)) ((maimi . airi) (desc "良き妹") (score . 1)) ((saki . erika) (desc "彼氏にしたい") (score . 1)))
のようになります。
以上の調査を経て気になった問題点を列挙してみます。
特に最初の点に関して、「百合的」なるものの質的評価がなかなか難しいと感じました。例えば「大好き」も「良き妹」も同じ 1 と評価してしまっているのが妥当かどうか、といったことです。
また、スレにて与えられた情報を評価・分析する方法としては有効だとしても、逆方向のフィードバックの手段がなかなか見つからないというのが三つ目の問題です(技術力不足とも言います)。(注:画像化の方法が分かりました。追記参照)
最後に、プログラムのソースを示します。実行には PLT Scheme が必要です。文字コードは UTF-8 で保存した上で、(load "c-ute.ss") としてください。文字化けする場合はターミナルが UTF-8 を表示できるよう設定する必要があります。がんばってください。
c-ute.ss:
(require (lib "etc.ss") (lib "list.ss") (lib "26.ss" "srfi") (lib "delete.ss" "srfi" "1")) ;;; Utilities (define true? (compose not not)) (define (ignore _) #f) (define fif (case-lambda ((predicate consequent) (fif predicate consequent ignore)) ((predicate consequent alternative) (lambda (x) (if (predicate x) (consequent x) (alternative x)))))) (define (concat! xs) (apply append! xs)) (define (mapconcat f lst sep) (let lp ((str (f (car lst))) (lst (cdr lst))) (if (null? lst) str (lp (string-append str sep (f (car lst))) (cdr lst))))) (define (slice-string str len) (let lp ((res '()) (str str)) (if (<= (string-length str) len) (reverse! (cons str res)) (lp (cons (substring str 0 len) res) (substring str len))))) (define (break-string str len) (mapconcat identity (slice-string str len) "\\n")) ;; NOTE: input and output ports have to be either file-stream or #f ;; (i.e., cannot be a string port) (define (run exe opt in out) (let-values (((p p-i p-o p-e) (subprocess out in #f exe opt))) (subprocess-wait p) (close-input-port p-e))) ;;; Database ;; http://ja.wikipedia.org/wiki/%E2%84%83-ute (define names '((erika . "えりか") (maimi . "舞美") (saki . "早貴") (airi . "愛理") (chisato . "千聖") (mai . "舞") (kanna . "栞菜"))) (define (symbol->name sym) ((fif true? cdr) (assq sym names))) (define nodes '()) (define edges '()) (define (relate from to desc score) (let ((n (cons from to))) (or (find-relation n (lambda (r) (let ((d (assq 'desc r)) (s (assq 'score r))) (set-cdr! d (cons desc (cdr d))) (set-cdr! s (+ score (cdr s)))))) (begin (set! nodes (cons n nodes)) (set! edges (cons (cons n `((desc ,desc) (score . ,score))) edges)))))) (define (find-relation n k) ((fif true? k) (assoc n edges))) (define (related? x y) (find-relation (cons x y) (lambda (_) #t))) (define (from? n x) (eq? (car n) x)) (define (to? n x) (eq? (cdr n) x)) (define flip-relation (case-lambda ((n) (and (related? (cdr n) (car n)) (cons (cdr n) (car n)))) ((n k) ((fif true? k) (flip-relation n))))) (define (get-score n) (cdr (assq 'score n))) (define (get-description n) (cdr (assq 'desc n))) (define (describe-relation n) (find-relation n get-description)) (define (score-relation n) (or (find-relation n get-score) 0)) (define (print-node . ns) (for-each (cute find-relation <> (lambda (r) (display (format "| ~a => ~a (~a)~%" (caar r) (cdar r) (mapconcat (lambda (s) (string-append "\"" s "\"")) (cdr (assq 'desc r)) ", "))))) ns)) (define (iter-nodes k) (let lp ((nodes nodes)) (unless (null? nodes) (k (car nodes)) (lp (cdr nodes))))) (define (filter-nodes p) (let ((ns '())) (iter-nodes (fif p (cut find-relation <> (lambda (n) (set! ns (cons n ns)))))) ns)) (define (from-links) (map car nodes)) (define (to-links) (map cdr nodes)) (define (all-members) (delete-duplicates! (from-links))) (define (all-pairs) nodes) (define (ordered-pairs) (concat! (map (lambda (x) (map car (sort (filter-nodes (cute to? <> (car x))) (lambda (x y) (> (get-score x) (get-score y)))))) (sort-nodes (map (lambda (x) (cons x (score-loved x))) (all-members)))))) (define (all-combinations) (let lp ((cs '()) (ns nodes)) (if (null? ns) cs (let ((n (car ns))) (lp (if (member (list (cdr n) (car n)) cs) cs (cons (list (car n) (cdr n)) cs)) (cdr ns)))))) ;; number-list :: [a] -> [(a . Int)] (define (number-list ls) (let lp ((ns '()) (ls ls)) (if (null? ls) ns (let ((x (car ls))) (lp ((fif not (lambda (_) (cons (cons x 1) ns)) (lambda (n) (set-cdr! n (add1 (cdr n))) ns)) (assq x ns)) (cdr ls)))))) ;; sort-nodes :: [(a . Int)] -> [(a . Int)] (define (sort-nodes ns) (sort ns (lambda (x y) (> (cdr x) (cdr y))))) (define (diff-nodes ms ns) (let lp ((ds '()) (ns ns)) (if (null? ns) (sort-nodes ds) (lp (let* ((n (car ns)) (m (assq (car n) ms))) (cons (cons (car n) (- (cdr m) (cdr n))) ds)) (cdr ns))))) (define (get-total-score x p) (foldr (lambda (n acc) (+ (get-score n) acc)) 0 (filter-nodes (cut p <> x)))) (define (score-loved x) (get-total-score x to?)) (define (score-loving x) (get-total-score x from?)) (define (score-between x y) (+ (score-relation (cons x y)) (score-relation (cons y x)))) (define (-> x) (display (format "~%Links from [~a]~%" x)) (iter-nodes (fif (cut from? <> x) print-node))) (define (<- x) (display (format "~%Links towards [~a]~%" x)) (iter-nodes (fif (cut to? <> x) print-node))) (define (<-> x) (display (format "~%Reciprocal links for [~a]~%" x)) (iter-nodes (fif (cut to? <> x) (lambda (n) (flip-relation n (lambda (m) (print-node m n))))))) (define (<=> x) (display (format "~%Reciprocal matches for [~a]~%" x)) (iter-nodes (fif (cut to? <> x) (lambda (n) (flip-relation n (lambda (m) (if (ormap (lambda (x) (ormap (lambda (y) (equal? x y)) (describe-relation m))) (describe-relation n)) (print-node m n)))))))) (define (<?> x) (let ((to (assq x (number-list (from-links)))) (from (assq x (number-list (to-links))))) (display (string-append (format "~%Link statistics for [~a]~%" x) (format "| ~a => ~a (love ~a)~%" x (cdr to) (score-loving x)) (format "| ~a => ~a (love ~a)~%" (cdr from) x (score-loved x)))))) (define (info x) (for-each (cut <> x) (list <- <-> <=> -> <?>))) ;;; GraphViz (http://www.graphviz.org/) support (define graphviz "C:/Program Files/ATT/Graphviz/bin/dot.exe") (define (nodes->dot ns) (string-append "digraph cute {\n" ;;"\tordering=out;\n" ;;"\trankdir=LR;\n" "\toverlap=true;\n" "\tnode[fontname=\"msgothic.ttc\"];\n" "\tedge[fontname=\"msgothic.ttc\",fontsize=9];\n" (let lp ((str "") (ns ns)) (if (null? ns) str (let* ((n (car ns)) (s (score-relation n))) (lp (string-append str (format "\t\"~a\" -> \"~a\"" (symbol->name (car n)) (symbol->name (cdr n))) (format "[label=\"~a\",color=\"~a\"," (break-string (car (describe-relation n)) 7) (cond ((> s 0) "red") ((= s 0) "green") (else "blue"))) (format "style=\"bold~a\"];\n" (if (and (not (= s 0)) (< s 1) (> s -1)) ",dashed" ""))) (cdr ns))))) "}")) (define (write-dotfile dot file) (and (file-exists? file) (delete-file file)) (with-output-to-file file (lambda () (display dot))) file) (define (dot->png dot png) (call-with-input-file (write-dotfile dot "c-ute.dot") (lambda (in) (and (file-exists? png) (delete-file png)) (call-with-output-file png (lambda (out) (run graphviz "-Tpng" in out))))) 'done) ;;; Setup database ;; Based on: ;; http://ex23.2ch.net/test/read.cgi/morningcoffee/1188654905/116-142 (begin (relate 'maimi 'erika "大好き" 1) (relate 'maimi 'kanna "良き妹" 1) (relate 'maimi 'airi "良き妹" 1) (relate 'maimi 'mai "姉妹" 0) (relate 'erika 'maimi "一番可愛いよ" 1) (relate 'erika 'kanna "仲間" 0) (relate 'erika 'chisato "おソロパジャマ" 0) (relate 'kanna 'erika "仲間" 0) (relate 'kanna 'maimi "好き" 1) (relate 'kanna 'saki "喰ってやるよ" 1) (relate 'kanna 'mai "喰ってやるよ" 1) (relate 'kanna 'airi "大好き" 1) (relate 'kanna 'chisato "愛理に手出すんじゃねぇよ" -1) (relate 'saki 'maimi "荷物整理" 0) (relate 'saki 'erika "彼氏にしたい" 1) (relate 'saki 'kanna "興味がある" 0.5) (relate 'saki 'chisato "愛理に手出すんじゃねぇよ" -1) (relate 'saki 'airi "好き" 1) (relate 'airi 'kanna "受け入れる" 1) (relate 'airi 'chisato "最近親密" 1) (relate 'mai 'erika "保護者" 0) (relate 'mai 'maimi "姉妹" 0) (relate 'mai 'chisato "恋人" 1) (relate 'chisato 'erika "おソロパジャマ" 0) (relate 'chisato 'mai "恋人" 1) (relate 'chisato 'airi "最近親密" 1)) ;; query relations / draw graphs (if (file-exists? graphviz) (dot->png (nodes->dot (ordered-pairs)) "c-ute.png") (for-each info (all-members)))
Graphviz というソフトによって関係図を可視化できる、ということを教えていただきました(既に上プログラムを実行すると自動的に関係図画像を作成するようにしてあります)。ここでは技術的な観点から幾つか注意点を挙げておきます。
まず、Scheme プログラムから Graphviz を動かす方法について。コマンドラインからの起動のように、プログラムへのオプション文字列で入出力ファイルを指定する方法ではどうも上手く行きませんでした。調査の結果、入出力ファイルのポートを Scheme 側で用意しておく必要があるようです。処理系によって異なりますが、PLT Scheme の場合 subprocess という関数を次のように呼び出します。
(subprocess output-port input-port #f "/path/to/dot.exe" "-Tpng")
ここで output-port は png 等画像ファイルへの出力ポート。input-port は dot ファイル(グラフの定義ファイル)の入力ポートです。エラーポートは必要無いでしょう (#f)。
dot という名前の実行ファイルが、関係図のような有向グラフを描画するプログラムです。最後にオプション文字列として出力形式を指定します(png, jpeg, gif, etc.)。
次に dot ファイルを Scheme で書く方法ですが、以下の基本的な有向グラフの書式
digraph g { A -> B; B -> C; C -> A; }
を理解すれば、後は実直に Scheme のデータを当てはめて format 関数等で変換するだけです。
(string-append "digraph g {" (format "~a -> ~a;" (car node) (cdr node)) "}")
問題は、ノードを配置する順番によって出来上がる画像が変わってくる、ということです。
より見た目に分かりやすくするための工夫としては、相互にリンクするノード同士が dot ファイル上でも近接して出力されるようにすると良いでしょう。関連の強いものが画像の上でも近くに表示されるようになります。
また上述(特に例3)のスコアの概念を応用し、スコアの低いものが後に出力されるようにすることで、重力感覚に一致するような関係図を得ることができるでしょう。
圧縮アルゴリズムそのものを新規に考えたら高校生じゃなくても随分凄いだろ。既存の技術を組み合わせて実装するぐらいなら俺も高校生の頃にやってた。
HDDの中にあるファイルを片っ端から圧縮してみたら平均してPKZipの5%増しぐらいのサイズにはなってた。だから存在価値は無かった。
でもそれ危ないよな。ジョエルのおっさんもこう言ってる。
しかしポインタと再帰の明らかな重要性以上に重要なのは、これらの学習から得られる精神的な柔軟さと、これらを教えている授業からふるい落とされないために必要な精神的態度が、大きなシステムを構築する上で欠かせないということだ。ポインタと再帰には、ある種の推論力、抽象的思考力、そして何よりも問題を同時に複数の抽象レベルで見るという能力が要求される。そしてポインタと再帰を理解できる能力は、優れたプログラマになるための能力と直接的に相関している。
オールJavaのコンピュータサイエンス教程では、こういった概念を扱うための頭の回転の良さを持ち合わせていない学生をふるい落とせない。程度を下げた新しい授業はどうにか切り抜けられるが、Java会計アプリケーション以上に洗練されたプログラムを作れるほどには頭の出来の良くない卒業生たちを、Java 100%スクールが量産しており、その様を私は雇用主として目の当たりにしている。そういう学生はMITの6.001やイェールのCS 323を決して生き抜くことはできない。最近オールJavaになったデューク大や、私と友人がひどい目に合ったCSE121の言語をSchemeとMLからJavaに変えたペンシルベニア大の学位よりも、MITやイェールの学位に重きを置く理由がここにある。優秀な学生でもデューク大やペンシルベニア大を出た人は雇いたくないと言っているのではない。ただ優秀なのが誰なのかを見分けるのがすごく難しいのだ。かつては学生の出来がいいかどうかは、再帰アルゴリズムを数秒で書き出すことができるかとか、連結リストを操作するポインタを使った関数を、ホワイトボードに書くのと同じくらいの早さで実装できるか見れば良かった。しかしJavaスクールの卒業生たちについては、彼らが躓いているのが十分な教育を受けていないためなのか、それとも優れたプログラミング仕事をするために必要な脳の部分を持ち合わせていないためなのか、わからないのだ。ポール・グレアムは彼らをほげプログラマと呼んでいる。
16からプログラミングを始めた23歳
思えば最初からレベル2でのスタートだった。始めた当初からプログラミングが楽しくて仕方なかったのだ。
プログラミングを始めて3ヶ月ぐらいはC,C++を学び、Boost最強!とかと思っていた。パズルを解くのにはまる。
六ヶ月ぐらい経過したときには、MFCを使ってwindowsで色々作っていた。目に見える物が作れるのがうれしかった。
ふとWindowsAPIで直接組んでみたときにMFCの使いづらさを知った。
数ヶ月後、ソフトウェアレンダラとか、剛体シミュレーションとか作り始めた。OpenGLやDirectXにも手を出した。
ここら辺で一年ぐらい経過した。
いつの間にかmlやらschemeやらに手を出した。新しい地平を目にした気がした。
rubyやpythonにも手を出した。LLという新しいあり方を知った。
それでも完全に満足できなかったので新しい言語を作ってみた。
設計して、検討して実装した。とりあえずの最低限の機能をだ。
あまりの地道な作業に気が遠くなった。自分には言語を作るのが無理だと思った。
就職した。仕事をしてプログラマはプログラミングが好きじゃない人がいることに驚愕した。
今ではNEETをしている。
LV0 スクリプト言語?どうせAUTOEXEC.BATとかだろ?どうでもいいよ…
LV1 Perlはあんまり堅苦しくないな。ってかこのor dieって何なの?
LV2 流行の言語は綺麗だな。Rubyってのはなんか日本人多くて結構いいかも。
LV4 PHPも気が利くわりにドジっ子でかわいいな。LispとかSchemeとかHaskellもいい・・・
LV5 Pythonってワンライナー書けないのにWeb2.0言語扱いされててうぜぇ。Python死ね!
LV7 やべぇPython最高!Pythonとエディタさえあれば生きていける!
恋人にふつけるをプレゼントする Schemer の俺が来ましたよ。
# 鬼の首をとったかのように書いてごめんよ。
CommonLisp はよく知らないんだけれど、 Scheme だと #\( と書けば ( という文字を示すことになるし、マルチバイトな処理系だと ((((((( というようなシンボルも問題なく使えたりする(開きカッコが全角であることに注意)。
処理系によっては半角のカッコでさえシンボルに使える、かもしれない。実際、ある処理系では SRFI-17 に関係したコードに半角空白を含むシンボルがあったりする。
そういうわけで
(define ((((( xs) (if (null? xs) '() (cons (map (lambda (c) (if (eqv? #\( c) #t #f)) '(#\( #\( #\( #\( #\( |setter of hogehoge|))) ((((( (cdr xs)))))
というようにカッコが不揃い(に見える)コードも可能。まあ、デモ以外でマルチバイト文字をシンボルに使うことなんてないだろうし、文字リテラルはたまに目視でカッコをチェックしていて「あれ?」と思うぐらいだし、そもそも上のコードは意味のある処理をしていないんだけど。
そういえば Emacs は閉じカッコを打った時、対応する開きカッコを強調表示してくれますよ。
Lisp なんてやってないで HSP とかやるといいよマジで。 Lisper になるには最初に HSP を学ぶのが最も近道なんじゃないかと最近気付いたんだ。
super pre 記法ないのかよ! Web2.0 っぽいインターフェースでブクマコメント表示したりする暇があるならこういう基本的なところやれよなマジで(いや、コメント表示も便利だけど)。そもそも増田のシステムなんてほとんどはてブと共通かと思ってたよ。増田が出た当初、「適当に組替えただけで、うまいことやったなぁ」と感心していただけに残念だ。