投稿者: freemikan

  • .NETをちょっと触った感想

     .NETをちょっとだけ触ってみた。きっかけは、Packtのライブラリを眺めていたら、新しい.NET 7の本がおすすめに表示されたことだ。.NET 6のころから、同じ本の前の版がおすすめに出てきていて、頭の片隅にその名前はちらついていた。それよりももっと前にから.NET Coreの名前は知っていて、クロスプラットフォームになってLinuxでも利用できるようになったことは前から知っていた。そうはいっても、基本はWindowsでVisual Studioを使って開発する環境だろうという先入観があるので、なかなか手を出そうという気にはなれなかった。今回も、本格的に取り組んでみようという気はまるでなくて、どんな感じか軽く味見してみるだけのつもりだった。.NET Coreに対する誤った先入観は、これまでの.NET Frameworkのサブセットであって、すべての機能を提供するものではなく、完全なものではないというものだった。そうではなくて、どうやら従来の.NET Frameworkに取って代わって置き換えてしまうロードマップが示されているようだ。そして、順調にその筋書き通りに進んできていて、もはや新規に.NET Frameworkをベースに開発を始めるような状況ではなくなってきている。とりあえず.NET FrameworkをmacOSやLinuxでも使えるようなオプション的な扱いではない。Windowsでも主流の開発プラットフォームとなっていくのだろう。もともと.NET Coreという名前で区別されていたけど、Coreの単語はなくなって、単に.NETだけに改名されたことからも、もう試験的な段階を終了して順次置き換えていく段階に来ていることが分かる。.NETが登場したのが大体2000年頃だっとすると、もうおよそ20年以上経過している。この時間はソフトウェア時間にするとかなり長寿だと言える。もっともWindowsやVisual Studioはもっと長寿ではあるが、それはソフトウェアというより製品として長寿であると捉えることができる。何にしても、この20年のという時間は十分に長く、ついに訪れた最も大きな転換期だと考えられる。

     ここまでで.NETがどうとか書いたけど、.NETの経験はほぼない。 経験もないのによくそんな偉そうに語れるなと、自分でも思わなくもない。なぜこうやって.NETを外観から眺めようとしているかと言うと、ただ大きな流れに身を任せたまま開発環境を乗り換えていくのは多少の危険が伴うからだ。逆に全く流れに乗らないというのもそれはそれで危険だ。少しは波に乗っていかないと、楽しくもないし、時代から取り残された古物になってしまう。やり過ぎはだめだ。大体、目に入ってくる、流布される情報は自然に発生したものではなく、何らかの意図が含まれている。大げさな広告には警戒する必要がある。何でもかんでも無警戒に新しいものに飛びついていったら、本当に自分がやりたいことは何なのかをすぐに見失ってしまう。たとえ広告に飛びついたとしても、もし、その対象が自分に合っていると判断できたのなら、それは悪いことではない。買い物をするとき、例えば新しいキーボードが欲しいとしたとき、店頭で買うにしろネットで買うにしろ、他の製品と比較したり、情報を仕入れたりして判断を下す。商品の情報には購入してもらおうという意図が含まれているし、店頭に並んでいるものも買ってもらおうと工夫して展示されているはずだ。それを全部否定する必要などまったくない。問題が発生するのは、判断を見誤らせるほどに過剰な広告が行われることだ。プログラミングに関連すると、昔だとJavaとオブジェクト指向は過剰だった。今ならPythonとAIやデータサイエンスがだろうか。これらの情報は、正しい判断力を失わせるだけの十分な誇大広告がなされているように思える。それでも、繰り返すと、判断力を失わずに冷静に接することができるのなら、全然悪いことではない。AIの技術やデータサイエンスがこれからのソフトウェアの領域で大きな位置を締めるようになっていく流れには逆らい難い。市場価値を高めるとか、自己ブランド化というくだらないものを無視しても、それらの技術を習得していることは、なかなかおもしろい経験になりそうだ。

     .NETに話を戻すと、そこまで過剰な広告は行われていない。どちらかというと控えめだと言っていい。これを使えばあなたはハッピーになれますとか、世界平和が訪れますみたいな怪しい文句は含まれていない。ちゃんと自己判断を下せるような情報だけを提供しているように見える。判断を開発者に委ねているように見える。今の時代に合ってはなかなか珍しいことにも思える。大量の新しい開発者を呼び込んで、一世を風靡するようなムーブメントを起こそうなどという意図はないだろう。警戒しておきたいのは、クロスプラットフォームになったことで、Windows以外のプラットフォームでの囲い込みを行おうとしているのではないか、ということだが、どうもそのような動きにも見えない。まったくないということはないだろう。誰にも使われないソフトウェアを開発したい企業などないだろう。しかし、Linuxのアプリケーション開発やWeb開発すべてを置き換えようなどという野心的な動きはないし、選択肢の一つして追加されただけに見える。むしろ、もっと積極的なサポートを期待する人も多いのではないだろうか。例えば、Windows.Formsに変わるクロスプラットフォームなデスクトップアプリケーションの開発環境などだ。もし実現してしまったらLinuxのデスクトップ環境に混乱をもたらすかも知れない。なので、あまり良いものではないかも知れない。それはちょっと保守的すぎるかも知れなが、そういう要因に加えて、企業によってもたらされる、言いすぎかも知れないが独占的な技術によってもたらされる変化は好まれないかもしれない。とにかく、一概に歓迎されたり排除されたり極端な反響をもたらすものではないようだ。あまり大きな反響がないのは、もはや、それほど革新的な技術というわけではないと言うのもあるのではないだろうか。.NETは言語を選ばない環境ではあるけど、中心になるはC#であって、それ以外の選択肢はオプション扱いだろう。C#が決して革新的な言語であるとは言えない。神の存在・不在を証明したり、世界平和をもたらしたりはしないだろう。そんな言語はこれまでも、おそらくこれからも存在しなかったが。

     肝心の開発環境を使ってみた感想はどうなのかというと、かなり良い感じだ。dotnetというコマンドラインインターフェイスを通して、プログラムのビルドや設定や管理を行うようになっている。コンパイラはこのdotetツールの裏側で仕事をする。もはやVisual Studioのような制約の多いソフトウェアに縛られることはなくなっている。いま主流となっている現代的なプログラミング環境のスタイルから大きな影響を受けた結果だと言える。Visual Studioは必須ではないが、もちろんサポートされているようだ。そして、その代替として、VSCodeに一極集中していく未来も見えるが、それは単にVSCodeが扱いやすく広く使われているから来る結果に過ぎないだろう。もし、VSCodeより扱いやすい開発ツールがあれば、自然とそれにシフトしていくことになる。

     今後、C#を中心にプログラミングをしたいとは全く思わない。しかし、.NETをツールボックスに入れておくことで、何かしら必要なときが来たとき引き出せるようにしておきたいとは思う。それに、なかなか楽しい。目眩のするような巨大なライブラリと言語仕様が組み合わさって絶妙なバランスで成り立っている。その中に飛び込んでみるのはなかなか新鮮な体験だ。

  • キーボードは日本語配列かUS配列か

    今日3本目の投稿。キーボードについて考えてみる。今、主に使用しているPCは2台ある。そのうち1つはUS配列で、もう一つは日本語配列のキーボードを使用している。この状況は良くない。ずっと日本語配列のキーボードを使ってきていた。そこそこ値が張る代物で、打ち心地も素晴らしいくてとても気に入っている。最近、といってももう1ヶ月以上経っているけど、新しいPCを購入した。そして、ひょんなことからUS配列のゲームミングキーボードが手に入ったので、それを利用している。打ち心地はそこそこだけど、無駄に光るのがなかなか良くて、しばらく使っていたらこれにも愛着が湧いてきた。そして、このUS配列のキーボードがメインとなった。このブログもそのPCから書いている。

     US配列にもだいぶ慣れてきた。最初はEnterや角括弧を何度も間違えていた。プログラミングでは多用するのでこのような基本的なタイプミスは思考が中断されて、効率が悪すぎる。さっさと買い換えればよかったのだけど、US配列のほうが良いところもある。@や引用符なんかの位置はUS配列のほうが良い。また、テキストエディタなどのキーバインドはUS配列が基本に考えられているので、そちらの方が自然に感じられる。そういう理由で、しばらく使ってみることにしていた。もうほとんど日本語配列のを使っていたときと同じような感じで使えるようになってきた。

    しかし、今度は逆の問題が発生する。旧PCで作業をするとき、びっくりするくらいうち間違える。丸括弧や引用符などは、間違えずに打てることの方が少ないくらいだ。この混在した環境はとても良くない。日本語配列かUS配列かという問題が些細に思える。プログラミングでもそうだが、例えば、インデントは4にするか2のどちらが優れているかよりも、 どちらかに統一して、少なくとも同じプロジェクトの範囲では、一貫してそのスタイルを使い続けることのほうが遥かに重要だ。キーボードもそうだ。打ち心地がいいとかよりもずっと重大だ。まず、どちらかに統一できることが大前提になる。どちらかに揃えることできることが可能であって初めてどちらの配列のほうが良いかについて考えを巡らすことができる。

     今、所有しているキーボードの殆どが日本語配列になっている。ラズパイ用のワイヤレスキーボードが2つある。それにラズパイ400も日本語配列で、これは交換不可能だ。あとはあまり使用しない古いノートPCもやはり日本語配列だ。また、US配列のHHKを1つ所有しているけど、PS/2端子なので変換器をかまさないと使えないので使用していない。もしUS配列に統一するとなると、少なくとも3台買わないといけない。そして、今ある3台が不要品になってしまう。どうがんばってもラズパイ400とノートPCはUS配列にできない。こういう状況を鑑みると、日本語配列で統一するのが素直な選択肢のようだ。それならば1台を買い足すだけですむ。

     本当にそれでいいのかちょっと迷いがある。まず、見た目の問題で、どうみてもUS配列のほうがシンプルだ。日本語配列の変換や無変換やカタカナがない分、無駄がなくてスッキリしている。プログラミングで多用するスペースキーがとても広く取られているので、安心感がある。変換と無変換はまだ活用できる。しかし、カタカナキーは無理がある。PCを使い始めてから一度も活用したことがない。CapsLockが重要な位置に置かれているの同じくらい不自然なキーだ。使いみちがないので無視すればいいという考え方もできる。しかし、やはり美的感覚から受け付けがたい。各キーについているひらがなの刻印も無意味な感じがする。かな入力は使ったことないし、将来も使う可能性は極めて低い。何度か言っているけど、@のような使用頻度の低いキーがホームポジションに近い位置にあるのも微妙だ。そして、プログラミングで多用する二重引用符が変わりに@が適正だと思われる位置に押しやられている。美的感覚からも、機能性の面からも、US配列のほうがずっと優れていると思われる。日本語配列を選択する理由となるのは、ただ入手しやすいことと、今ストックがたくさんあることのみで、キーボード本体の設計が理由となるものではない。

     なぜ今こんなにキーボードについて悩まないといけないかと言うと、おそらく、今回下した判断によって、今後数年、下手したら数十年の間ずっとそれを維持し続けることになるだろうからだ。先に書いたように、キーボードそのもののどちらが優れているかよりも、統一して使い続けることのほうがずっと重要だ。統一されているという前提があって初めて、どちらがいいかを選ぶことができる。統一されていればどちらでもいいというわけではない。プログラミングと同様に、悪いスタイルを強制されるのは苦痛なものだ。はじめから苦痛なキーボードを選択する理由はない。

     別に日本語配列が苦痛なだと思っているわけではない。今までもそんなふうに思ったことはなかった。しかし、ここしばらくUS配列を使ってきて、少し考えが変わってきた。1ヶ月程度ではまだ試用段階だったと考えても良い。決断を下せるほど使い込んだとは言い切れないところがある。それを踏まえて、現時点では、先に述べたように、見た目と機能の両方に置いてUS配列のほうが優れていると思っている。ここで、すべてのPCに対して統一するために、今所持しているキーボードに引退してもらって、新たにすべてに対してUS配列を用意するほどまでの優位性があるかどうかを判断しないといけない。

     どうも話がループしている気がする。先に進むことを考えよう。

     今使用しているUS配列のゲーミングキーボードはなかなか気に入っている。これを手放すのはちょっと惜しい。そして、旧PCに接続してある、ちょっと効果な日本語配列のキーボードも、打ち心地の良さから気に入っている。どちらか一方を選べと言われるとちょっと難しい問題だ。しかし、どうにかしてどちらかを除去しないといけない。もし、ひょんなことから新しくUS配列のキーボードを入手していなかったら、こんなに悩むことはなかっただろう。一旦、元の平和な状態に戻してみてはどうだろう。しばらくUS配列ばかりでやってきていたので、日本語配列でプログラミングする感覚を忘れかけている。旧PCで作業するとにタイプミスを連発する原因はそれしかない。一旦戻して、それでもまだやっぱりUS配列のほうが良かったと思えるようなら、US配列で統一する。別に日本語配列でも問題なければ日本語配列で統一するということにしよう。

  • 思考はどこからくるのか

     10日ぶりにブログを書いている。出だしはなかなか良かったのだけど、やはり続けるのは大変だ。それでもやっていこと思う。厳密でなくてもいいので、できるだけ1日1つを維持したい。今月はもう無理だけど、今日から連投することで数だけ稼いで帳尻を合わせたい。今日時点で12本欠落しているので、今月はあと5日として、30、31日はおそらく使えないので、残り3日で、およそ17本投稿しないといけない。1日に5、6本になる。可能だろうか。かなり大変な仕事に思える。何しろ文字数が多い。今4Kのモニターで表示していて、大体これで、編集画面で上から下まで埋めることを目安としている。どうやら3000文字くらいになるようだ。それが6本なので18000文字必要になる。コードにしたら、1行40文字くらいとして、450行くらい。コードと文章ではまったく質が異なるので、あまり意味はないが、雰囲気はそんな感じになる。不可能ではないような量だ。ただ、こればっかりやっているわけにもいかない。1本30分で、3時間程度で終わらせられたらいいなと思う。ちょっと厳しいか。

     今困っているのは、ネタがないということだ。そんなはずはないのだけど、思いついたやつを下書きにキープしていって、まだ10本程度しかない。もういっそなんでもいい。コーヒーの話とか、ダイエットの話とか、禁煙の話でもいいんではないだろうか。とにかく数を稼ぎたい。

     数を稼ぐというと、プログラムをコードの行数で見積もって水増ししているようで、悪い習慣なのだろうか。そんなことはないだろう。さっきも書いたけど、文章とコードは全く質が異なる。無駄に長いコードは悪質だ。短すぎてもいけないが、十分に読みやすく保守しやすいコードである以上の冗長さは取り除くべきだ。文章の場合そうとも言えない。すべての文章は何かしら文学的な性質を持っている。情報が単に表示されているだけでは良い文章ではない。読み手に伝達したいという意図があるから存在しているのであって、そのためには、文章を工夫して、強調したり、繰り返したりしないといけないことがある。物書きになりたいとは全く思っていないし、このブログでは完成された文章を書こうという目標は立てていない。

     このブログで何をやろうとしているのかというと、前にも書いた気がするけど、何を考えているのか自分でも分からない、思考を書き出すためだ。文章にして初めて自分の頭の中が見えてくるような気がする。大体、こうやって書いていることというのは、常にそういう風に考えているわけではなくて、文章を書きながら思いついたことを書いていっている。文章にすると陳腐にみえるようなことは排除していっている傾向がある。それなりに見栄えのする文章に作り変えている。それって偽物の思考じゃないのかと言うと、そんなことはないように思える。普段、何もしていないときはおそらく何も考えていない。何か活動をしているときには何かを考えているのだろうか。それも怪しい。プログラミングをしているときは多分プログラミングの範囲内でしか考えられていない。そこに落とし穴があるように思う。プログラミングは、それ自体が目的になることもあるが、本来は現実の問題を解決するためのものだ。目の前のコードに集中したり、プログラム自体に集中したりするあまり、視野が狭くなっている可能性がある。一度、距離を置いてやるべきことを見直す必要がある。頭の中だけで整理をするのは上級者向けだ。こうやって文章にしたり、なんか別のツール、マインドマップとか有名だけど、そんなんでも、何でもいいからちゃんとした形にすると良い。

     今さっきちらっと書いた、ここに書いているのは偽物の思考ではないかという疑念をもう一度考えてみる。確かに、文章にする前の段階では今ここに書いているようなことを考えたことがあるという自覚はない。ただ、思いつくままにキーボードを叩きながら出てくる文章を吐き出しているだけだ。現在進行形で文章が作られている。この文章はどこから出てきているのだろう。かろうじて言えるのは、他人によって強制的に書かされているものではないということくらいだ。本当だろうか。どこにも公開するのでもない、秘密のテキストファイルとして書いているのならともかく、ここは一応パブリックな空間で、理由はどうあれ、誰かに読まれることを想定しているはずだ。すると、読み手がどのように解釈するかということを含めて文章が生成されているところもある。とても人に言えないようなことを書いたりはしない。

     このブログの場合、何かを伝えたいという意思はほとんど含まれていない。単に人の目につくところに文章を置くことで、モチベーションを高めようと利用しているだけに過ぎない。それは過小評価しすぎかもしれない。おそらく人の目につくところに置くことで、多少はマシな文章を組み立てようという力が働くところも少なからずある。むしろ願ったりだ。文章の構成は人の読める程度にうまくできている方がいい。これは表現の違い、表面的なところでの話となる。思考そのものの出力である、文章の中身がどこから来るのかをまだ書いている本人が理解していない。だんだん、自分で書いている文章が偽物の思考なのではない、ということに自信がもてなくなってくる。誰が読んでも無難なように、本心を偽っているのではないかという気がしてくる。それは現実のコミュニケーションで人間が当たり前にやることだ。社会性を持った生物は、属するコミュニティで培った習慣に従って、さしあたりのない範囲で活動するはずだ。いきなり誰でも出会い頭にプログラミングの話をしたりはしない。こんにちはとか言うはずだ。そのような、常識とでも言って良い範囲に縛られたからと言って必ずしも偽物の思考だと結論づけることはできない。

     何か思いもよらない方向に話が流れてきた。書き始める前は全くこのような内容にしようとは思っていなかった。なぜこういう方向に話が進んだのか、なかなか興味深い。思考はどこからくるのか、など、典型的な哲学の領域ではないか。今までそんなことを考えたことはないのだが、不思議だ。こうやって文章にしていくことで、全く自覚していなかった、新たな発見があることは少し前から気づいていた。今回の場合で言うと、思考とは何かだ。本気でこのことを追求しようとはあまり思っていない。でも、せっかく気づいたことなので、気には止めておこうと思う。予め用意された入口、今回の場合は哲学になるのだろうけど、そこの戸を正面から叩くのではなく、こうやって自分で掘り下げて発掘するという行為は面白いかも知れない。

     何も期待せずに書き始めた投稿だったが、新しい、ちょっと高等な目的ができた。それは、文章化することによって、今まで気づかなかったことを採掘するということだ。ただ、これは最初から求めてはいけないようだ。書き続けていくことで自然と見つかるもので、そのときを見逃さずに捕まえられればそれでいい。

     

  • コードコンプリート (上) を読んで得たもの

     少し前に、コードコンプリート 第2版 (上)を読み終えた。この本を入手したのはもう随分前になる。ずっと放置したままだった。頭の何処かに、読みたいし、読まないといけない、という意識がずっとあった。それにも関わらず、なぜずっと読まずにいたのか。初めて目を通したときの、最初のいくつかの章のとっつきにくさが原因だったように思う。プログラミングの前段階、要求やアーキテクチャから始まるのだけど、まだプログラミングを始めたばかりの頃には、それらが一体何なのかを現実のプログラミングと結びつけることができなかった。そこをスキップしてしまえば、具体的なコーディングの話が始まって、それほどソフトウェア開発の経験がなくても読み進められる内容ではある。しかし、最初に躓いてしまって、読む気が失せたと言うか、まだ読めるだけの経験値が溜まっていないと判断して後回し後回しになってしまっていた。

     これまでこの本を読まずにいたことでどれだけの損失を出していたかを考えてみよう。読まなかったからといって、コードが全く書けなくなるわけではない。逆に、読んだだけですぐに効果が発揮されて、優れたコードが書けるようになることもない。そう考えると、読んでも読まなくても対して違いがないのではないかと捉えられなくもない。

     仮に、今まだプログラミングを初めて1週間目くらいで、何かの言語を使って簡単なプログラムが書けるような状態になったところとしてみる。さらに、能力的には平均にしておいて、なぜかこの本の内容を理解して吸収できるだけの驚異的な適正があったとしてみる。この架空のプログラマーがこの本を読んだときと読まなかったときで、どれだけコードを書く能力に差が出るかを比較してみる。

     まず、読んだ場合を検討してみる。まだ1週間目なので、ようやくifの使い方が身についてきたというところだろう。そして、ifを書くときに、どうやったら良い条件を作ることができるかというところにも意識が向いてくる頃だ。その状態でこの本を読んだところ、ifの条件をうまく作るための指針が書かれていて、その優れた理解力によって、なるほど、こうすればいいのかと知ることになる。さっそく実践に移そうとするだろう。しかし、まだプログラミング始めて1週間であるという縛りは有効だ。頭の中ではこうしたらいいと分かっていても、身体がまだ作れていない。単純に言うと、経験値が不足している。これからifを書くときには、この本の指針を思い出しながら、注意を払ってコードディングしてくことになる。それを繰り返していくうちに、意識せずとも自然と良いifが書けるようになってくる。

     次に、読まなかった場合を検討してみる。実験台になる架空のプログラマーは、先と同一の条件を備えた人物だとしよう。ifを書くときに、ややこしい条件を扱わなければいけない状況に遭遇したとする。先と同じ能力を備えていると仮定しているので、やはりどうやれば良い条件が作れるかに思いを巡らすことになる。しかし、指針が全く無いので、自分でなんとかならないかを試行錯誤することになる。その結果出来上がるコードは、この本に書かれているような優れたコードの性質を満たしていないかも知れない。最も優れたコードでないことは自分自身がよく理解している。だが、何とかして動作するようにしないといけないので、現状でできる最も良いやり方で妥協して先に進んでいく。その後も、何度もifを使うことになるので、その都度同じように試行錯誤しながら良い条件にならないかを模索していくことになる。そのうちに、自覚はできないかも知れないが、なかなか良いifが書けるようになってくる。

     前者は、先に目標を設定することができ、そこに向かって訓練していくというスタイルになっている。後者は、その場その場で目標を更新しながら、徐々に鍛え上げていくというスタイルになる。前者の優位なところは、最終的な目標に到達するまでの時間を短縮できるかも知れないという点だ。ダイエットをする場合に、最終的な目標体重を定めて、そこに向かって食事や運動を調整するほうが、効果が現れやすい。それは、レールが敷かれているからそこに従っていけばいいと言うだけではなく、目標を立てたのだから、達成できるように努力をするように意識が当たらくという精神論の効果もある。また、目標があると安心感が得られる。どこまで体重を減らせばいいのかわからないよりも、理想的な体重が分かっていた方が圧倒的に安心できるだろう。後者の優位な点と不利な点は、前者のちょうど反対だ。時間はかかるかも知れない、安心できないかも知れない。しかし、試行錯誤の中から自分で見つけ出したものを目標と定めて、それを繰り返していくことで、違った性質の経験値を得ることができる。単純な筋トレのようなトレーニングとは違った、発見的な経験、想像力を養うプロセスから、独特な能力を得ることができるかもしれない。

     もともとの問に戻ってみる。果たして、後者のプログラマーはこの本を読まなかったことで、より大きな損失があったと言うことができるだろうか。 まず、1週間目という仮定に現実味がない。1年目に読むとして、10年後の違いを考えてみよう。10年間読まずにいたプログラマーは、1年目に読んだプログラマーよりも損失はあっただろうか。全く同一の人物で、同じくらい量のトレーニングを行ってきたとするとき、10年目の違いはどこに現れるか。まず考えられるのは、読んだ方は、その後の反復トレーニングによって、目標の能力を完全に獲得しているという状況だ。読まなかった方は、目標そのものが絶えず変化していくので、安定した能力を獲得できていないかもしれない。しかし、目標を自ら変化させていくというまた違った能力が鍛えられていくことになる。時間的なところに目を向けると、読んだ方は、10年も書けずとも目標に到達してしまう可能性もあるだろう。その場合、また新たな目標を立てて、より高いところに進んでいくこともできる。もし損失があったとしたらそこではないだろうか。つまり、この本を入手した時点で読んでいれば、もっと早く良いコードの書き方の目標が定まっていて、そこに到達していたかも知れない。そして、もっと関心のある現実の問題を解決するソフトウェアを書くことに専念できたかも知れない。

     今回、この本を読んでみて思ったのは、それほどまでに新たな発見のようなものが得られたのではなく、これまでの経験と照らし合わせると、とんでもなく道を逸れて、変なところに来てしまったわけではないということだ。そして、ようやく入門者から一歩先に進んで初心者の手前くらいまでは来たかも知れないと、何か達成感のようなものを感じている。もし、1年目に読んでいたら、このような感傷的な感想は抱かなかったに違いない。そして、誰かに与えられた助言ではなく、自身の経験から獲得してきたことであるという事実は、なかなか貴重であるかも知れない。この本を読む一番の理由はそれじゃないだろうか。何か新しいことを身につけたり、いきなり優れたコードが書けるようになることを期待するのではなく、自分がどの方向に向かっているのか、今どのくらいの経験値溜まっているのかを確認するために読むことで、より先に奨めるようになる。

     しかし、まだ上巻なので、あと半分のこってるのに結論を出してしまうのはちょっと早い。でも、たぶんそんなに違った感想は持たないだろうとは思う。

  • 完璧なプログラミングを目指して

     コードコンプリートを読んでいる。そのサブタイトルが「完璧なプログラミングを目指して」なので、完璧なプログラミングとは何かを考えてみる。何かを目指すにしても、その何かが何なのか分からないのでは目指しようがない。

     プログラミングとはソフトウェアを対象とした領域の活動と考えられることが多い。だいたいプログラミングを仕事としていると言ったら、コンピューター装置の前に座って、コーヒーとキーボードを携えて不可思議な文章を打ち込んでいたりする姿が想像させられることが多い。こうした典型的なイメージのプログラマが扱う領域は、ほぼソフトウェアに限定される。せいぜいハードウェアとのインターフェイスまでだったり、ハードウェアを制御するためのソフトウェアだったりして、直接ハードウェアを製造するものではない。それどころか、現代の最上位のレイヤーで作業するプログラミングは、一切ハードウェアに感知することがなかったりする。厳密には、コンピューターに命令を出していたり、ディスプレイモニターに表示させる画面イメージを制御しているという意味でハードウェアに接しているということができるので、完全に切り離されているというわけではない。しかし、コンピューターやディスプレイモニターの電気的な特性を考慮しながらWebサイトやスマホアプリをプログラミングすることは稀だろう。

     このように、ハードウェアから切り離して、ソフトウェアの領域だけでプログラミングをできるようになっていることは、 抽象化によってもたらされている。現代の複雑なソフトウェアが成り立っているのは、ハードウェアを直接扱わずに、その上に多段に構築されたレイヤーの上で、問題の領域だけを扱えるようになっているところが大きい。もし、今でも直接マシン命令しか扱うことでしかプログラミングができなかったら、現代社会を支えるの多くのソフトウェア基盤はもっと貧弱なものだっただろう。マシン語でプログラミングをするのは開発効率が悪すぎて、複雑な問題を扱うソフトウェアを構築するには時間がかかりすぎる。現実の複雑な問題を解決するだけの複雑さをもったソフトウェアを構築すること自体が困難だったりしただろう。 

     そういうわけで、今の時代、プログラミングとは主にソフトウェアの領域だけの活動を指して言うことが多い。しかし、ハードウェアだけでもプログラミングを行うことは可能だ。スイッチをたくさん取り付けた回路を組んで、手動でそのスイッチのONとOFFを切り替えることで、ソフトウェアなしでも機械の動作を制御することができる。現実に、天井についているライトや、電気スタンドなんかは物理的なスイッチで動作する、ハードウェアだけで構築されたプログラムのようなものと見ることもできる。他には針時計、レコードプレイヤー、エレキギターなどもプログラムのようなものだ。電気的な動力をしようしないものある。楽器はすべて自然界の音に関する性質を利用した一種のプログラムだ。ここまで解釈を広げると、あらゆるものがプログラムに見えてくる。机、椅子は、人間の体型に合わせてプログラムされている。衣類とそれをしまうクローゼット、靴と靴べら、食器と箸、 鉛筆と消しゴム、などだ。別にペアであることを強調したいわけではなくたまたま思いついたから書いただけだ。これらは、現実の問題を解決するために生み出されたという点で、ソフトウェアのプログラムと共通している。そして、人工的に生み出されたものであるという点も共通している。異論は当然あるだろうが、これらをすべてプログラミングによって生み出されたものとし、そして、その活動をプログラミングとしてみなすなら、人工的に自然界に手を加えて、本来の姿形に何らかの別の法則を適用して便利なものを生み出す行為をプログラミングと呼べる。 

     では、プログラミングは人工的な操作を行うものかというと、まだ解釈を広げることができる。 まずは生命だ。生命はコンピューターよりも遥かに高度なハードウェアとソフトウェアを備えている。生体をハードウェアに見立てるなら、遺伝子はソフトウェアといっていい。遺伝子は人工的にプログラムされたものでは、通常はない。しかし、何らかの法則にしたがって、生命単体から子孫を通してその種の生存を制御しようとしている。生命を持たないものでも、プログラムのようなものがある。気象、地形などは、何らかの要因があって、雨が降っているとか、川が流れているというような現象を観測できる。他には、空は青い、東から日がのぼり、西に沈む、夜には月が出る。これらにはすべてなぜそうなっているのかという理由があり、従っている法則がある。これらの法則をプログラムとみなすことにしてみよう。そうしたプログラムを開発することがプログラミングだとすると、プログラミングによって宇宙を創造することができる。こういう存在を神とか創造主とかいったりする。

     ここでようやく完璧なプログラミングとは何か、という問に戻ると、それは究極的には完璧な世界を作るということになる。しかし、そんなことは全く現実味がないし、不可能でもある。そこで、シミュレーションという現実的な選択を取ることができる。世界を完璧にしようなどというだいそれた考えを抱かなくても、自分の好きな形に世界をシミュレーションすることで代わりができる。世界のシミュレーションはコンピューターゲームで実現できる。現実世界と全く同一のゲームというのは、やはり実現不可能という意味で現実味がないのと、面白くもない。逆に、現実で不可能なことを可能とする世界の方が面白い。大部分が現実に近いような仮想世界で、現実で不可能なことができるというのが望ましい。そして、今のゲームはそういう風な方向に発展してきている。これは自分の作りたいものとも一致していて、だからゲームプログラミングの修行をしているというところがある。

     結論を出すと、自分にとって完璧なプログラミングとは面白いゲームのプログラミングだ。いかにコードが優れていても、ゲームが面白くなかったら完璧とは言えない。では、面白ければどんなひどいコードでもいいのかというとそれは違う。ひどいコードのゲームは完璧ではない。完璧なゲームは完璧なコードによって生み出される。ひどい変数名をつかっていたり、ひどい関数名をつかっていたりするコードからは面白いゲームは生まれない。最終的には、読みやすく、誤りがなく、効率的で、保守しやすいコードというありきたりのところに行き着く。そのためには高い技術と豊富な知識と長い経験が必要となる。そんなのは幻想に思えるところもある。実際にどこまで到達できるかよりも、このくらい理想を掲げていないとすぐに堕落してしまう。それくらい完璧なプログラミングというのは難しい。

  • つまらないゲームを作り続けること

     三並べを作った。しかもCPUなし。一人で二役やらないといけないこのゲームは、もうゲームとすら呼べないのではないだろうか。GUIライブラリのデモとして考えればそうひどいものではない。それにしてもつまらないゲームだ。プログラミング中には色々考えるところがあって、Rustの練習にはなっているように思える。並行してゲームプログラミングの経験値まで稼ごうというのはちょっと欲張り過ぎかもしれない。三並べのような原始的なゲームで一体何の経験値が得られるのかのと軽く見てしまうと良くない。CPUを用意するのはそこそこ良い経験値になりそうだ。今回はやらなかった。どうせつまらないゲームだからと割り切って、GUIライブラリの使い勝手をテストするだけのような形で終えた。一度に完全なものを作る必要はない。10分の動画に収めるには情報が多すぎる。少しずつ発展させていく形にするのもよいだろう。

     とにかく、今回のはGUIライブラリの使い方とRustの練習としてはそこそこ良い経験値が得られたものの、ゲームの方は全然だった。こんな初歩的なゲームを作ることに何の見返りを求めているのか、繰り返しになるけど、そんな風に侮るのは良くない。こういう初歩的なゲームであっても、完璧に仕上げていくことを繰り返すのと、形だけ取り繕った中途半端な完成度のもので満足してしまうのでは、後々、大きな差になって現れる。実利的な立場からすれば、三並べを完璧に完成させたとしても、誰にもプレイされない可能性が高く、中途半端であって完璧であっても大した違いはなく、微妙な部分に多くの時間を割くよりもさっさと次の、面白くなるかもしれないであろう新しいゲームに取り掛かるのが良い。本当に夢中になって継続して作り続けられるゲームをやる方が良い経験になる。

     今思うのは、まだ本格的なゲームの制作に取り掛かるような時間帯ではない。まだ慌てるような時間じゃない。Rustをこつこつやって、ついでにゲームの経験値もためて、いずれは塵も積もれば山となっていることだろう。そういうわけなので、中途半端な状態のゲームを作り続けるのはこの方針にあっていない。面白いゲームを作るというのはちょっとハードルが高い。つまらないゲームを作り続けることの弊害として、つまらないゲームを作ることに慣れてしまい、感覚が麻痺してしまうことも見逃せない。だから、YouTubeに継続的に投稿していきたいという気持ちがあっても、あまりハイペースでつまらないゲームを作り続けるのは褒められたものではない。つまらないならつまらないなりに、完成度を高めておきたい。細かいところをきちっと作り切るつもりでやるのが良い。大体つまらないゲームは完成度が低い。三並べに完成度なんて求めるもんではない、というのは、また繰り返しになるのでもう言わない。

     それっぽく動くだけのゲームというのは、つまらないならつまらないなりに、完成されたゲームに到達するまでのどれだけまで到達しているのだろう。今回の三並べについては、半分もいっていないのではないかと思う。良くて30%、悪ければ20%くらいだ。それどころか、今回作ったのはプロトタイプくらいの水準に到達していないとも考えられる。プログラミングの常識では、プロトタイプのコードは捨てるのが正しい。プロトタイプのコードをもったいないと思って使い続けて本番用に流用してしまうのは、陥りがちな罠だ。もう一度、なぜRustでゲームを作って動画にして投稿しているのかというと、最大の目的はRustの練習だ。ついでにゲームも作れるようになれれば、といったところなので、これもやはり練習の一貫といえる。したがって、その成果として出来上がったものは、本番用のプログラムとは言えない。本番の前段階の試作品、つまりプロトタイプの領域にすら達していない。そもそも具体的な成果を求めていない。経験値こそが最大の報酬だ。この視点に立つと、完璧な三並べのどの段階まで到達しているか、という質問自体が成り立たない。あえて答えるなら0%ということになる。

     目的は練習だけど、完成度は高めておきたい、というのは矛盾を抱えている。練習用に作ったものに、それ以上の意味をもたせるのは無理がある。プロトタイプを使いまわすようなものだ。完成度の高いゲームを作ろうというのなら、最初から目標をプレイして面白い、リリース目的のゲームに設定する必要がある。それをやってしまうと、今度はRustの練習という、どちらかというと実験的なプログラミングの経験ができなくなってしまう。考えられる対策としては、リリース目的のゲームの制作と並行して、練習目的のゲームを作っていくことになる。これはなかなか大変なことに思える。今、練習用にやっているだけでも、ほぼすべてのプライベートなプログラミング活動に対するエネルギーをそこにつぎ込んでいる。これに加えて本番のプロジェクトを稼働させることは不可能に思える。並行処理が苦手なのはプログラミングだけでなく、現実でも同じのようだ。

     無謀な計画を立てるのではなく、とりあえず目の前のことに集中しよう。これまで同じようにRustの練習目的でゲームを作るのは継続していく。ただし、完璧までとは言わないまでも、できるだけ、そこに近づけるようにがんばることにする。でも、出来上がったものはあくまで練習用なので、使い回しのできるものだとは考えてはいけない。あとはどこでRustが使えるようになったかと判断するかだ。時間も有効に使いたい。いつまでも練習ばかりしていられない。

  • 行き詰まったときは

     昨日と今日は、RustのGUIライブラリであるicedを触っていた。なぜicedを選択したのか。しばらくSFMLを使ってきて、あまりRustらしいコードが書けていないことが気がかりだった。SFMLがC++のライブラリだということもあり、バインディングもオリジナルの使いやすさそのままにRustにポーティングされたようになっている。あまりRustらしい書き方を強制されることはない。これは良い面と悪い面がある。良い面は、C++での使い方を知っていれば、同じような使い方であまり迷うことなく始められるということ。悪い面は、良い面をそのまんま裏から見たもので、Rustらしい書き方をしなくても使えてしまうので、Rustらしいコードを書く機会を逃してしまうこと。今はRustらしいとはどんなものなのか分からない。Rustらしい書き方を身に付けたいにしても、どうやればいいのかわからない。SFMLを使うとどのようにも書けてしまうので、これまでC++で使ってきたのと同じように書いてしまうことが避けられない。今必要なのは、Rust流の書き方を強制することだ。SFMLは良いライブラリだけど、今は適切ではない。そう考えて、Rust製のライブラリを利用することにした。

     なぜゲーム用のライブラリで はなく、GUIライブラリにするのか。五目並べとかマインスイーパーのようなパズルゲームを作りたいと思っていて、それってGUIのウィジェット、例えばボタンなどを組み合わせてできそうだと思って、面白そうだと考えた。ちょっと息抜きに変なことがしたかった。RustでGUIプログラミングというのはなかなか新鮮で面白そうだった。ちょっとゲームとは別のことをしてみたいというのもあったかもしれない。ゲームプログラミングは比較的自由度が高い。そのため、どのような書き方でもできるとなると、Rust流の書き方をせずに、これまでの経験を引きずってしまう可能性が高い。GUIライブラリを利用したプログラミングというのは、最もライブラリに近いところでは、フレームワークが定めた範囲の中でプログラミングしないといけないところがある。そのフレームワークに従ったの書き方をしないといけない。通常はそのような制約は窮屈で、言語の可能性を下げることにもなるので、あまり良いものではない。しかし、Rust流の書き方を身につけるためという目的をもって見ると、何らかの制約がもたらされることはむしろプラスの方向に捉えられる。Rust製のライブラリなのだからRust流の使い方を強制されるだろう。そうすれば、どうしてもRust流の書き方をせざるを得ないことになる。これは願ってもないことだ。GUIのライブラリはおそらくゲームのライブラリよりも制約が多い。そこに目をつけた。

     ライブラリはいくつか選択肢がある。 GTKとFLTKが利用できて、使い勝手も良さそうだ。しかし、Rust製ではないので今回の目的にはそぐわないだろうからパスした。Rust製で人気がありそうなのは、icedとeguiだ。eguiはまだ試していない。icedはコンパクトで、割と簡単に覚えられそうな印象をもった。実際やってみると、ライブラリはコンパクトで大量に覚えることがあるというわけではないけど、基本動作が独特な感じになっていて、それを理解してしまわないといけない。Elmという言語のアーキテクチャに倣っていると書かれている。遠回りに思えるだろうけど、Elmのドキュメントを読んだほうが良さそうだ。

     icedを使用する上で困ったことは、ガイド的なドキュメントやチュートリアルがほぼないことだ。それなりの数のサンプルと、十分な量のAPIリファレンスはあるので、それを頼ることになる。今回はまず三並べを作ってみようとした。ボタンを3×3マスに並べて、それをクリックしたときにマスを選択したという風にしたいと考えていた。デフォルトのボタンはマスに見せるには無理がある見た目なので、変更したかった。参考になりそうなサンプルプログラムを探して、ボタンの見た目を変更するコードを発見したのだが、icedのリファレンスにある仕様と違っている。どうやらサンプルが使用しているicedのバージョンが古く、そのままでは利用できないようだった。しばらく時間を書けて、現在のバージョンのicedではどうやればいいかを調べた。その結果、ボタンの見た目を完全に変更することはできないという結論に達した。

     この結論は納得がいかない。ボタンの見た目を変更するなど、ありふれた要求に思える。こんなことすらできないGUIライブラリなどあるのだろうか。結論が間違っている可能性を捨てきれない。そこで行き詰まった。結論が正しいとして、ボタンの見た目を変更するのではなく、カスタムウィジェットがあるので、それを利用するか、結論が間違っているとして、また時間をかけて変更する方法を模索するか、板挟みになった。

     このように行き詰まったときに取ることのできるもう一つの方法は、しばらくその問題から完全に離れてしまうということだ。案外、割と単純なことを見落としていたり、勘違いしていたりすることもある。ちょっとリフレッシュすれば何か発見があるかもしれない。というのは楽観的すぎるだろうか。でも、やはりボタンの見た目が変えられないというのは受け入れがたいので、何かしら方法が見つかる可能性にかけてみたい。これを機にeguiを試してみるのもよいだろう。

  • 面白いゲーム

     昨日は何を作るか長々と書いた末にブロック崩しを作った。Pongのコードの大部分がそのまま使えて楽ができた。今はまだ、とにかく動作するものを作るということに意識が持っていかれて、他のことにまで配慮ができていない。他のことってなんなのかと言うと、2つ無視できないことがある。

     1つ目は、コードの質について妥協していることだ。昨日書いたブロック崩しでは、明らかに問題なところがあったのを認識した上で、とりあえず動作するからこれでいいかと完了にした。練習だしRustに不慣れだからこんなもんでいいだろうという気持ちもあった。何が問題だったかと言うと、ひどく重複したコードがあって、本当なら共通の処理なので関数にまとめ上げるべきだったのを、そのままにしておいた。同じことを繰り返さないというのはプログラミングにおいて大切な姿勢だ。その姿勢はコードの中にも現れる。重複するコードが出現するというのは、典型的な改善するべきポイントとなる。Rustに不慣れだからだめなコードを書いてしまうのではなく、手持ちの能力でも改善できると認識していながら放置していってしまうと、良いプログラミングの習慣を身につけるチャンスをわざわざ逃していってしまうことになる。コードを良いものに作り変えるプロセスには、リファクタリングと呼ばれる名称がついている。リファクタリングについて学んだり練習したりしたことはないのだけど、おそらく今回のコードの重複を取り除くという改善作業は、リファクタリングに該当するのではないかと思う。せっかくプログラムを作ってリファクタリングを適用できる、訓練できる機会があったのに、むざむざとそれを手放してしまうというのはなんとももったいない話だ。コードの質の妥協についてはだいたいこんなところだ。 

     2つ目は、ゲームが面白いかどうかを気にかけていないということだ。既存のゲームのクローンを作るのだから、それが面白いかどうかなんて関係ないと思っていた。練習のために作ったゲームなので、誰も、自分自身ですらもそれで遊ぶことはないと割り切っている。ゲームプログラミングそのものを訓練しいるのであって、ゲームのデザインは自分の仕事ではないと思いこんでいる。確かに、ゲームデザインは自分の本業ではないかもしれない。将来的には、何かしらこういうのを作りたいという要求がどこからか湧いてきて、それを忠実にプログラムすれば面白いゲームができるのではないかという、夢の世界に生きている。現実ではそんなことはありえない。要求のとおりにプログラムするだけで面白いゲームになるわけでもない。これはゲームでないプログラミングについても同じで、要求のとおりにプログラムしたら使い勝手の良くないものが出来上がるというのはよく知られた悲劇で、プログラミングの失敗例だ。

     既存のゲームのクローンを作るというのは、ある意味、要求の分析を行う訓練を行うことを放棄していることでもある。プログラミングそのものを訓練しているのだから、それでいいというのはちょっと違う気がする。プログラミングと要求の分析というのは完全に切り離されたステージではない。プログラミングをどう定義するのかは置いておいて、もし完全に切り離してしまったら場合のコードを書くステージは、プログラミングと呼ぶより、コーディングと呼ぶほうがより適切になる。そう考えた場合、既存ゲームのクローンをとりあえず動作させるというだけの行為も同様に、プログラミングではなく、コーディングというのが適切だ。将来的に、忠実にコーディングだけを行うようなことを生業としたいかというとそんなことはない。面白いゲームをプログラミングすることを生業としたい。

     要求というのは安定しないものだ。特にゲームに置いては、ある程度形になってきてから、ここはこうした方がいいと分かって、コーディングよりも前の段階に戻ってやり直すなど日常茶飯事となる。前に戻るのがコストが高いから妥協するとなったりすると、つまらないゲームがになってしまう。つまらないゲームは、研究対象として興味があるかもしれないというのを置いておくと、使いにくいアプリケーションのような役に立たないプログラムと同じだ。アプリケーションの最大の存在価値化は、便利かどうかというところにある。ゲームの最大の存在価値は、面白いかどうかというところにある。だから、必ずしも実践できなくてもよいのだけど、今作っているゲームは面白いかどうか、というのは常に頭の片隅にでも置いて置かなければいけない。クローンの元となるゲームが面白くないのなら、どうやったらこれを面白くできるかということも検討するべきだ。どうやっても面白くならないのなら、そんなことはあまりないはずだけど、それはクローンする価値がない。そもそもの要求が間違っていたということだ。

     常に面白いゲームを作らなければいけないというのは、ちょっと理想が高すぎるかもしれない。 Rustの使い方がままならず、練習をしている段階でさえもゲームデザインについても考えながらやらないといけないとなると、前も書いたかもしれないけど、二兎を負うものは一兎も得ずの状態になってしまう。そんなたいしたことではない。ちょっとした意識の配分の仕方による。例えば、今回のブロック崩しを例に取ると、ボールの軌道にXとYが反転するだけ以外に変化がないのはいかにも退屈だ。パドルの当たり具合によってボールの軌道や速度に変化があるようにすると、ずっと良くなる。こんな感じで、気がついたことを直していく習慣をつけていくのが良い。その分プログラムはごちゃごちゃしてきて、見通しが悪くなる。これは必ずしも悪いことではない。現実の問題を解決するには、そういう状況に耐えうるようにプログラムを設計しなければいけない。ちょっとした変化をつけるだけで、何がなんだかわからなくなるようなのは、設計が不十分である、複雑さに耐えうるだけのしっかりしたものになっていないからだと考えられる。

     だんだんハードルが高くなってきている気がする。まだやっとこさブロック崩しを作った、という段階で要求やら設計やら考える必要があるだろうか。文字数を稼ぎたかったので、少し話を膨らませて書いたところが多い。本当の話は単純だ。面白いゲームにしたいという気持ちを持ち続けること、それだけ。プログラミングしながらそれを覚えておけば、あとはついて回るだろう。ここはこうした方が面白くなる、だからコードを書き換える、そうするとコードが煩雑になる、だから基本から設計をやり直す、と自然にそういう流れになるだろう。この練習を繰り返すことは、Rustの習得という点においても、そんなに効率が悪いとは思わない。

     そういう方向でやっていこう。

  • 意外と作るものがない

     Rust練習のために丁度いいゲームがないか探している。1ファイルで収まるくらい小さくて、可能な限りシンプルなものが良い。ありそうでなかなか見つからない。よく挙げられるのが2Dのシューティングなんかだ。シューティングゲームはどの程度作り込むかによってプログラミングの規模に大きな幅がある。シューティングゲームに限ったわけではない。ただ、シューティングゲームは根底のゲームロジックはどれも同じだ。敵に弾を当てる、敵の弾を交わす、それだけなので、シンプルなゲームと言える。プレイして面白いかどうかなどは求めていない。ゲームを作ることが目的ではなく、プログラミングの練習ができれば良い。結果として何かを残したいだけだ。とりあえず動作すれば良い。

     シューティングゲームの名作だと、自分の中ではグラディウスが真っ先に思い浮かぶ。これのクローンを作るのはなかなか大変だ。練習のためのモチーフとしては複雑過ぎる。他に思いつく、もっとも有名なシューティングゲームはインベーダーゲームだろう。グラディウスに比べればシンプルだ。練習題材として十分にシンプルだろうか。少なくともPongよりは難易度に高いように見える。Pongは画面にパドルとボールという2つの要素しかない。インベーダーゲームは、自機、防壁、敵がたくさん、UFO、敵の弾、自機の弾、こんなにもたくさんある。必ずしもこれらを全部作らないといけないわけではない。Pongと同じくらいシンプルにするなら、敵が1体と自機で弾を打ち合うということもできる。なんなら敵は弾を撃ってこないようにして、1対1で、一方的に敵に弾を当てるだけとしてもよいだろう。これならPongより少しだけ要素が増えただけで、十分にシンプルといえるのではないか。ただ、これを作っても何かをやってやったという達成感が得られないのが残念なところでもある。PongはPongとして完成されている。インベーダーゲーム先に上げたような要素全部が入ってインベーダーゲームだ。一方的な1対1だともはやインベーダーゲームの名前で定着しているものとはまったく異なるので、完成されたゲームとは言えない。クローンを作ったとは言えなくなる。

     クローンを作ることにそれほど固執する必要はないだろう。絵のデッサンとは違う。絵の贋作を作ることにそれほど重きを置く必要もない。先日のPongも、オリジナルの特徴的な部分を抽出してそれっぽく見せたものに過ぎない。オリジナルのプレイ感やゲームを面白くするために工夫されている様々な調整が欠落していて、クローンであるとは言えない。目立つのは、パドルの操作にかかる慣性や、ボールを打ち返すときにパドルの状態によって軌道や速度に変化を与えるなど、ゲームに変則的な法則を取り込んで、プレイヤーにゲームの状態を予測させることで楽しみや快感をもたらす、そういったぱっと見は分からなくても、ゲームの面白さを決定する重要なところが欠落している。そういうのを作り込むのは、ゲームプログラミングの練習には重要とは言える。今はまだRustの基礎を練習しようとしていて、ゲームプログラミング自体にはに重きを置いていない。どうせ作るならゲームがいいかなという程度だ。なので、Pongあれで良かった。あのくらい簡単なものがちょうどいい。

     昨日書いたのだけど、ある程度の複雑さがないと、Rustの特徴を活かしたプログラミングをする必要性がなくなってしまう。1対1の一方的なシューティングゲームを作るとして、シンプル過ぎるのではないだろうか。たぶん、シンプルすぎるように思える。しかし、やってみないとわからないところでもある。一発で成果を得ようなどと考えず、何度か繰り返していって感触を掴んでいくのが良い。何度も繰り返していれば、だいたいどの程度の規模感なのかを予測できるようになって、Rustの練習としてどの程度有用かも把握できるようになっていくだろう。今はまだシンプルすぎることを懸念しすぎるような時間じゃない。とりあえず1対1のをつくって、次に敵を増やして、弾を撃ってくるようにして、と段階的に発展させていくとよい感じがする。Pongしたって、あれで完成とはせず、オリジナルはやったことないのだけど動画で確認できるような、それに近づけていくのも良い練習になりそうだ。

     だいたい1対1の一方的なシューティングが候補に見えてきた。他にもいくつかある。テトリスとか、ブロック崩しとかどうだろう。テトリスは原始的なバージョンであってもそれなりに複雑なプログラムになる。さらに面白くしようとすればいくらでもやることがある。現在でも活発にプレイされているような完成されたルールと拡張性を備えた奥の深いゲームだ。ブロック崩しは、対人戦がないからというのもあって、テトリスほど現役のゲームではない。その分、基本的なプログラムのシンプルさという点では軍配が上がる。複雑なゲームであると、完成させることからとりあえず動作させることに意識が持っていかれる。そしてRustの練習をするという目的から外れてしまうことがある。コードがとりあえず動かすためにやっつけ仕事になってしまうということがある。意識していればそんなことにはならないというのは当てにならない。長い時間コンピューターに向かっていると、早く終わらせて次に行きたいという気持ちが湧いてくるのは避けられないことだ。テトリスはそれなりに複雑なロジックがある。ブロック崩しはPongのちょっと複雑なバージョンといった程度でちょうどよい。テトリスの原始的なものはいろんな言語で作ったことがあるけど、そんなに成果が得られたという感じがしない。どうしてもとりあえず動作させることに意識が持っていかれてしまい。言語を注意深く観察することを降ろさかにしていたためと思われる。ブロック崩しはあまり作ってこなかった。テトリスとブロック崩しのどちらかにするとなったら、ブロック崩しが良いだろう。

     ここまでで、次の候補は、1対1の一方的なシューティングか、ブロック崩しとなった。当初考えていたのは三並べのようなパズルゲームだった。具体的には、Simon Tatham’s Portable Puzzle Collectionのクローンを作っていくことで練習にしようと思っていた。いたのだけど、こういうパズルゲームは、リアルタイム性がなくて、SFMLのようなライブラリとはあまり相性が良くない。典型的なメインループを中心にフレーム単位でゲームを回すという処理が必要とされない。不可能ではないし、特段難しくなるというわけでもない。そうなのだけど、これはGUIライブラリを使ってやってみたいと思っていた。GUIのフレームワークが想定する、おそらくイベントドリブン型のプログラムでやってみたい。なので、もう少しあとにとっておくことにする。

     もっとさくさく作りたいものが見つかるかと思っていた。意外と見つからない。Rustの練習のためという名目があるので、ちょうどよい感じになるかどうかを考えると、かなりの制約があることが分かった。一番良いのは楽しみながらやることだ。やらなければならないという負の感情を抱えたままやるよりも、楽しんでやったことのほうがずっと脳はよく記憶してくれそうな気がする。楽しむということでは、自分でオリジナルのゲームをデザインしてそれを作るというのがベストだ。まだそこの領域まで到達していないので、今はクローンをたくさん作って行くことで我慢しておこう。

  • Pongを作った感想

     Pongを作ってみた。Rustの動画を投稿したいと思って、何かしら作らないとネタがなかったのでとりあえずやってみたという感じだ。やってる最中は、こんな書き方でいいのだろうかと疑問がついて回った。そんなに難しいという感じではなく、CやC++で書くのとあまり違いはない。それもそのはずで、CやC++で書くときと同じ思考で書いている。結局の所、どの言語でも通用するような、公約数の部分だけを使って書いている。Pongのような単純なプログラムでは、熟練度が低いうちは、意図的にでもそのプログラミング言語の特性を強調しようとしないと、表に出てこない。どの言語でもかけるような解決法があるのなら、わざわざ専門的にならなくても、その方法を使えば良いというのは正しいやり方なのだろうか。

     Pongを単純なプログラムとみなすかどうかは微妙なところだ。とりあえず動くものなら簡単に作れるという意味では、単純であり簡単ともいえる。手の混んだ解決策を探さなくても、ストレートに書いていけば、とりあえず動くものは完成する。ライブラリが、今回はSFMLなのだが、低レベルな部分を吸収してくれて、高いレベルでプログラミングができるからそうなのだということは置いておいて、低レベルなところは無視する。SFMLの上に構築する基礎部分と純粋なゲームロジックだけに目を向けよう。そうしたとき、とりあえず動くものが作れるから、簡単だとなめてかかるよりも、どうやればよりRustらしいコードになるかを模索するのに、ちょうどいいくらいの複雑さを持っているように思う。しかし、Rustらしいとは何なのだろう。不必要に賢くなろうとすることは、良いプログラミングの姿勢とは言えない。しかし、Rustを全く知らない誰でも理解できる部分だけ使ったコードが、もっとも単純で良いコードになるのかというと、それは違うだろう。賢くなりすぎず、シンプルにしすぎない、この相反するような姿勢をバランスよく保つのがまず目指すところになる。もう少し具体的に言うことができればいいのだけど、思いつかない。シンプルという言葉はあまり適切でないかもしれない。プログラミングだけでなく、多くの分野でシンプルであることは好まれる。今言いたいのは、今回やったPongのように、多くの言語の公約数的な部分だけを使ってプログラミングすることを指している。反対に、賢くなりすぎるとは、使用する言語の秘伝のテクニックを多用するようなことを言う。シンプルすぎればコードは冗長になり、賢くなりすぎると冗長さは軽減されるが、理解するのに言語の詳細な知識を備えていることが条件になったり、直感的でなくなる場合がある。別の例えを使うと、最適化に対する警句が適用できるかもしれない。時期早々な最適化は諸悪の根源だという。時期早々な不最適化も避けるべきというのを聞いたことがあるけど、時期早々な最適化に比べればりは強くはない主張だった。これらの警句を賢くなりすぎることとシンプルすぎることに対応させると、ちょうどよい感じに思えなくもない。賢くなりすぎずに問題を解決できるならそれ以上はやらないほうがいい。しかし、あまりに非常識なRustにそぐわない方法を取るべきではない。

     だいたい目標が見えてきた。これから目指すところは、賢くなりすぎない程度にRustらしいプログラミングを身につけることだ。Rustらしいとは、漠然と思い浮かべているのは、トレイトを活用したジェネリックなプログラミングだったり、並行処理や非同期処理を活用したプログラミングだったりするのかもしれない。こういうのには憧れるが、Pongにはオーバースペックなので、出番はもともとなかったように思える。もし無理矢理にでも使っていたら、それは賢くなりすぎたという結果に終わっただろう。もしトレイトや並行処理を多用してRustを活用している気になりたいのであったなら、それに見合った問題に取り組むべきだ。この問題を自力で見つけ出すというのは、経験が不足しているうちはなかなか難しいことに思える。現段階ではそれらを身につけられていないからこそ、練習したいのでそういった問題に取り組みたいのだが、どういった場面に最も適合しているのか、例えば、この問題はトレイトを使えばうまく解決できるなどといった具合に判断ができない。取りうる手段は2つ思いつく。1つ目は最適な解決策なのかどうかに関係なく、無理やりにその手法を適用させてしまうことだ。これはさっき言っていた、賢くなりすぎることだ。目的は練習のためであると明確であり、事前に賢くなりすぎていると自覚しているのであれば、弊害はそれほどないだろう。練習であると割り切って数をこなしていけば、適用するべき場面のパターンのようなものが見えてくる可能性がある。ただし、これはあくまで練習であって、本来やるべきでないことをやっているということを常に忘れてはいけない。そうしないと、無意識に賢くなりすぎてしまう癖がついてしまう危険性がある。2つ目は、誰かが、Rustの達人たちが用意してくれたフレームワークで問題に取り組むことだ。例えば、Rust製のWeb開発のためのフレームワークや、GUIライブラリ、ゲーム用のライブラリなど、決められた枠組みの中で、型にはまったプログラミングを要求するものがある。その要求されるプログラミングはRustらしいものであると期待ができる。そういったものの利用して問題に取り組めば、問題の性質に関係なく、フレームワークが要求するやり方でやらなければならないので、否応なしにRustらしいプログラミングを体験することができる。思いついたのはこの2つだ。どちらか一つだけに絞らないというわけではなく、併用していくのが良さそうだ。

     Pongを作っただけにしては、こうして今後の心構えというか方針がはっきり見えてきたことは、大きな収穫だった。作っている最中にも作り終えたあとにもこんなことを考えていたわけではない。こうやって文章に書き出しているうちに出てきた。今の練習のサイクルは、①何か作る、②動画にして投稿する、③ブログに書き出す、となっている。時間はかかるけど、学習効果はそこそこな気がする。といってもまだ目的を取り違えているところは否めない。本来は、Rustを使いこなせるようになることや、プログラミングの学習をすること自体が目的というわけではない。ゲームを作ることが目的だ。しかし、1回だけの大作を作るのではなく、継続的にゲームを作り続けるというのが健全なあり方だろう。そのためにはどうしてもプログラミング自体が目的になったり、学習して熟練度を上げていくということ自体が目的になったりするものだ。したがって、学習することそのものに対して熱意を抱くことは恥じるべきものではない。かといって、誇るべきことでもない。学習の過程をスキップして直感だけでプログラミングができる人も稀にいるようで、そうした人と比較したときどちらが神に愛されているかといえば、後者かもしれない。そうした人に向かって、あなたは学習を実行しないから恥ずべきだと告げるのは滑稽だ。色んな方法がある。たかがPong、されどPong。

  • 動画投稿について考える

     1ヶ月とちょっとぶりに動画を撮って投稿してみた。今日は書くことがないのでそれについて書いてみることにする。以前raylibを使ってみるというテーマで30本ほど撮った。どれも1時間超えのプログラミング実況といった内容だった。何も準備なしでやる自信はなかったので、予め、一度コードを書いてから、それをもう一度実況を交えながらやり直すといったものだった。raylibの機能に焦点を当てたかったのだが、成り行きでゲームを作る方向にシフトしていった。1回やったことをもう一度繰り返すのと、確実に何をやっているかを確かめながらコーディングするということで、学習効果はそこそこ高かったのではなかったかと思う。それで目的は達成できていた。そこそこの成果が得られたと思っている。

    今回はRustでゲームを作るというテーマで撮っていく。すでに3本アップロードした。前回のように、すべてを実況するのではなく、その日その日の要点だけをアップしていくというものにするつもりだった。前回のは長すぎて、密度が低すぎると反省しているからだ。今日の3本のうち、最初の1本は良かった。15分で終われた。これはいける、と思ったのだけど、2本目は30分、3本目は1時間と、結局前と同じになってしまっている。これは良くない。明日から修正していかないといけない。どうやったら短時間で必要なポイントだけ記録することができるだろう。コーディングを実況というタイプの動画だから、どうしても長くなってしまうのだろう。コーディング実況は録画でやってもあまり面白みがない。やるならライブ配信の方が面白そうだ。しかし、ライブ配信は敷居が高い。まず、誰も見てないのにライブ配信するというのがちょっとしんどい。これまでの録画してきてアップロードしたものは、再生回数を稼ごうなどという気はまるっきりなかった。そのはずだったのだけど、あまりに再生されなさすぎなので、残念な気持ちがまったくないと言ったら嘘になる。自分でページを開いてしまうとカウントされてしまうので開かないようにしていたので正確な数がわかる。1本につき大体5回といったところだろう。再生時間は1分未満がほとんどだ。本音をいうと、100回とは言わないが、30回はほしいところだ。

    不本意ではあるが、なぜ再生されないのかを考えてみよう。喋りが良くない、声が良くない、内容よくないといったところだろう。一言でいうとつまらないからだ。アイコンがデフォルトのままだしチャンネルページの見栄えも良くないし、タイトルや説明に情報が少なすぎて検索にもかからないだろう。不運にも動画を開いてしまった人はこいつは一体何がしたいのだろうと不審に思うに違いない。何をしたいか、自分でもよく分かっていない。動画として残すことで、そのために行ったプログラミングを定着させる効果が見込めると思っていたのだが、だんだん動画を完成させることの方に意識が持っていかれる。確かに多少の効果はあるだろう。しかし、もっとも良い手段とはかけ離れている。もっとも良い手段とは何だろう。現実のプログラムを書くことだ。ゲームを作ることがゲームプログラミングの能力を向上させる最高のプロセスではなかろうか。その過程を取り繕ったように動画に仕立て上げることに本当に価値はあるのか、疑問だ。前回のraylibの動画から得られた教訓は、そのようなことに時間をかけるくらいなら、さっさとゲームを作れ、技術をみにつけろ、ということだ。今回も同じようなことをやっていたら、まるで成長していないということになる。今日やってみてそれに気づけたことだけでも良かった。

    実をいうとさっきまで、この投稿を書くまではそうは思っていなかった。これからしばらく、Rustが使えるようになるまで、同じようなサイクルでこつこつアップロードしていこうと考えていた。たった今、こうやって振り返ってみることで、それに気づけた。このブログは特に目的もなく始めたのだけど、かなり自省を促す効果があるようだ。 これは続ける価値がある。YouTubeはどうだろう。何か得るものがあるだろうか。さっきも書いたけど、その日行ったコーディングを繰り返すことによって、プログラミングを定着させるという効果は見込めるものの、もっと良い手段は他にもある。ゲームプログラミングができるようになりたいならゲームを作るのが一番良い。今日の動画をアップロードするまでに準備なども含めて費やした時間は、おおざっぱに5時間くらいではないかと思う。この間に何ができただろう。これからもこのように時間をかけていていいものだろうか。

    だんだんと動画を投稿し続けることが否定的な方向に向いてきた。学習効果だけを期待すると、良いものとは言えないことが明らかになってきた。しかし、それだけが理由でやってきたわけではなかった。動画を取り終えてアップロードしたときの、やってやった感、達成感はなかなかのものだ。数時間の作業の見返りとして得られる達成感は中毒性がある。それにもし再生回数までついてきたらもうどハマリしてしまうだろう。もしかしてドハマりする前に気づけてよかったのかもしれない。もうちょっと冷静になってやるべきだ。動画を投稿するのは楽しいだろうかと言われると、そこそこ楽しいと思える。それは良いことだ。過酷なトレーニングの合間の僅かな楽しみとして、ちょっと趣味としてやるだけなら、悪くない。ただ、全力で、半日や1日かけてやるようなことではない。ゲームの完成を動画の投稿と同一にしてしまうべきではない。もし続けるならもう一度やり方を見直す必要がある。

    完全にやめてしまうのはちょっと惜しい。せっかく見つけた密かな楽しみなので、も少しやってみたい。理想は、1日30分くらいの時間を確保して、その時間内にすべての作業を完了させることだ。30分ではその日の成果をリプレイすることは不可能だろう。また、そんなものの需要は皆無であることはもう前回のシリーズで身を持って知っている。動画の長さは重要で、10分程度でないといけない。その時間では実況コーディングは不可能なので、もうやらない。その日作ったゲームのコードに解説を加えて再考するというのはどうだろう。これなら10分程度で終わるのではないだろうか。振り返ってみることで定着を測るという目的にもあっているように思える。悪くない、しばらくこの方針でやってみよう。ライブ配信はどうだろう。今はやる価値がなさそうだ。もう少しうまく喋れるようになってからのほうがいいように思える。練習としてやるのはありだけど、それ以外の成果は期待しないほうがいい。まずRustがまだ全然馴染んでいないこの状態でやるのは、無謀に思える。ということでなしだ。学習過程をオープンにするというのは新鮮で試してみたい気もする。しかし、中毒性が高そうで、前と同じ罠にハマってしまいそうだ。危険なのでやめておこう。

    だいたい方針が決まったので満足した。

     

  • 急がば回れ

     Rustで少し書いてみた。やったことは、SFMLを使ったゲームプログラミングの本を読みながら、C++で書かれたコードをRustで書き直すといったことだ。まだRustでどのように書けばいいのかわからなかったので、何かしらガイドになるものが欲しかった。題材はゲームがいいだろうというのと、SFMLのRustのバインディングが公開されている、SFMLの本を選んだ。オリジナルのSFMLのAPIとは異なるところが多々あって、思うようには書けない。それはまだ想定内なので何も問題ではない。懸念しているのは、C++のコードをそのままRustに書き直すということで、間違ったRustの使い方をしてしまうのではないかということだ。読んでいる本は、C++のクラスをベースとした設計、要はオブジェクト指向のような設計になっている。継承を多用していないのであれば、データ型とメソッドでそのまんま書き直すことができる。それが問題に思える。まだ、Rustらしいといえばいいのだろうか、よいRustのコーディングスタイルを身につけていないので、こういうときはこう書くべきだというのが何もない。何もないからこそ、下敷きになるものが欲しくてC++のコードが手に入るSFMLを選んだのだけど、もしかしたら逆効果なのではないかという気がしてきた。SFMLのRustバインディングを使うことは、それほど悪い選択肢ではない。問題なのは、C++をそのまんま書き直すということでRustを身につけようとしていることだ。今はまだまっさらの白紙に色を塗るような、あるいは吸収力の高いスポンジのような状態であって、今からインストールする習慣は何の抵抗もなく受け入れてしまうことだろう。良い方向で考えれば、高効率で身につけることができる。悪い方向で考えれば、良いか悪いか判断ができず、間違った習慣までもすんなりと受け入れてしまう。また、間違った習慣のためを記憶してくために、空間を無駄に消費してしまう。

     プログラミングの学習は、反復と修正を繰り返すプロセスだ。かならずしも良い方法、グッドパーツだけを回収することだけで上達するものではない。間違った方法を経由することもあり、しばらくしてから間違っていることを認識して、これは間違いだったと身体と頭に刻むことで、同じ間違いを繰り返さないようになっていく。実験的なプロセスとも言える。だから、一度に正しい方法だけを選択するよりも、失敗も数多く経験することによって学習を繰り返しながら身につけていくのも有効な手段だと言える。通常はそうだ。しかし、今はちょっと状況が違う。

    刷り込みというのがある。今はまだ卵から孵ったひな鳥のような状態だ。この状態で見たり触れたりしたものは、たとえ姿かたちがまったく違っていたとしても、同じ巣にいる親鳥を親として認識してしまう。これはもしかしたら危険かもしれない。SFMLを選択したのは、本があるからといのもあるが、もう一つはC++で慣れているからというのがある。まずRustそのものになれるために、練習として何も考えず書き直すということで、文法を身につけようという算段だ。文法だけを身につけることができるのならば、これは悪くないように思える。しかし、余計なものまでついてくる。C++でこう書くところはRustでこう書けばよいのか、という情報だ。これはC++とRustの公約数だけを使ってプログラミングすることを意味する。今は孵ったばかりのよちよち歩きの状態で、この状態でそのようなプログラミングをやり方を覚えてしまうと、まさに刷り込みの効果により、これからもそういうやり方から離れられなくなってしまう可能性がある。修正が難しくなってしまう。SFMLの資産を有効活用できないのは残念だが、諦めたほうがいい。初期投資をけちって、大きな機会を損失出してしまうことになりかねない。

    SFMLを使うことに問題があるわけではない。SFMLのRustバインディングは、たぶんRustのイディオムに適合するように書き直されているだろうから、姿かたちのまったくことなる親に対する刷り込みが起こるということにはならないかもしれない。それでも、C++が頭にあるので、それを振り払うのを意識を持っていかれる点は無視できない。もしかしたら、それはまだ許容できるかもしれない。一番まずいのは、C++で書かれた本をRustに書き直すという学習方法だ。Rustの何の経験もない状態でこれを行ったら、確実に刷り込みが起こる。非常に残念だが、今回はこの方法は諦めざるを得ない。もう少し経験を積んで、良いか悪いかの判断くらいできるようになってからにした方がいい。

     今日はそういうことをやっていたのだけど、早い段階で気づけたのはラッキーだった。最初良さそうに見えた方法が、実はあまり良くなかったというのはプログラミングではよくあることだ。学習方法にも同じことが言える。もっというと、何かしらの方法を選択しなければいけないという状況においては、分野を問わず似たようなことが発生するのかもしれない。なので一度立ち止まって、本当にこの方法は正しいのだろうかと自問してみることは大切かもしれない。急がば回れ、とはこういうときに使うのかと学んだ。

    それで、どうやってRustを身につけるかをもう一度考えてみよう。ベストはRustを使ったゲームの本があると良い。Packtのライブラリを見ると、一応あるにはある。ただ、それはWebAssemblyとタイトルがついている。これはちょっと手に負えない感じがする。難しいとかじゃなくて、むしろ、WebAssemblyはやりたいくらいなのだが、まだRustがままならないうちにWebAssemblyに手を出すのは時期尚早ということだ。一度小規模なプロジェクトを経由してから手を付けるのがいいだろう。それ以外にはゲームの本は見当たらない。ここは本かゲームかどちらかを諦めよう。二兎を追う者は一兎をも得ずという警句もある。本を選択する場合、言語解説中心のものは今は良いだろう。オライリーのを読み終えたばかりなので、まずはこれを血肉にするために、リファレンスとしてオライリーのを活用しながら、プログラムを書くのが良い。白紙状態からプログラムを書くというのは流石に効率が悪いので、プロジェクトベースで解説を行う本があると良い。Packtのライブラリに2冊ほど良さそうなのがあるので、それが選択できる。ゲームを選択する場合の方法は、Rust純正のゲーム用ライブラリを使って、その環境の中でゲームを作るというものだ。ライブラリはいくつか選択肢がある。そのライブラリの利用方法を学びながら、Rustのプログラミングスタイルを定着させようという狙いだ。まだ二兎を追っているような気がしないでもないが、大丈夫だろう。ゲーム専用のフレームワークでなくても良い。汎用的なGUIライブラリであれば、シンプルなパズルゲームなどは作ることができる。

    大体今後の方針が固まってきた。本をベースにプログラムを書くのと、Rust純正のライブラリを利用してゲームを書くのどちらかだ。同時進行は可能だが、一緒くたんにしてはいけない、別々に進める必要がある。

  • OOP離れについて考える

     今後Rustに移行するにあたって、オブジェクト指向プログラミングの世界からどうやって離脱するかを考えておきたい。Rustはオブジェクト指向を採用していない。これは良い知らせだ。オブジェクト指向にはずっと馴染めないでいた。C++では、それが可能だからという理由でお付き合いをしていただけで、可能ならもっとシンプルな方法を取りたかった。C++にとってオブジェクト指向は重要な要素であり、また有用であることを否定することはできない。現実の問題を解決するときに、特に設計段階においては、強力なツールとなる。プログラミングを始めたばかりの頃は、これが唯一のC++の使い方だと思いこんでいて、必死になってその技法を身につけようとしていた。それを今でもずっと引きずっている。C++は別のプログラミング方法もサポートしている。現に標準ライブラリはオブジェクト指向をベースにしたものになっていない。オブジェクト指向は自分に合わないというのは割と早い段階で気づいていた。だから、バッサリと手を切ってしまって、別のプログラミングスタイルを身につけることにしても良かった。だけど、それはできなかった。C++がオブジェクト指向を全面的にサポートしている以上、何を書くにしても常につきまとう。何を書くにしても、例えばHello Worldを書くだけにしても、常に頭の片隅にはオブジェクト指向がある。これはもう強迫観念と言っても良い。もう10年くらい前になるだろうか、突然、少なくとも自分には突然に思えたのだが、関数型言語が注目浴びるようになった。このときは嬉しかった。もしかしたらオブジェクト指向をもうやらなくてもいいのかもしれない、と思った。今そのようなキャンペーンは終了したのか、さほど関数型言語が取り上げられることは少なくなってきたように思える。自分の中でも落ち着いてきた。しかし、今でもやはりHaskellのような言語を使えるようになりたいという思いは消えていないし、今も学習を継続している。本当は、関数型言語は突然現れたのではない。昔からずっとあったものだ。ただ、視界が狭かったから見えてなかっただけだった。もし、最初にオブジェクト指向に疑念を抱いたときに関数型言語が目に入っていたら、その時点で乗り換えることができていたかもしれない。そう話は単純でないかもしれない。C++をどうしてもやらなければいけない理由があった。ゲーム開発で利用される言語だったからということを真に受けて、それしか選択肢がないと思っていた。もし、ゲーム開発でもっとも利用される言語がHaskellだという情報があったら、とっくにHaskellに乗り換えていたことだろう。

     これは10年以上前の話だ。現代では、まだ圧倒的な優位にあるのは変わりないが、ゲームプログラミングならC++一択だというほどではなくなってきている。それでもC++を使い続けている理由の一つに、言語に対する執着や愛着というものがある。一方でオブジェクト指向に対する嫌悪感もある。その相反する感情が入り混じって、どうにもすっきりしない状態がずっと続いていた。C++ではオブジェクト指向を採用しなくてもいいという逃げ道がある。そこへ逃げればよかったのだけど、それもできなかった。オブジェクト指向を採用しないプログラミング技法についてのガイドラインがイマイチ不明であったため、なかなかものにできなかったからだ。簡単な方法がある以上、そちらの方へ流されてしまうのは仕方がないことだ。C++を使うけどオブジェクト指向は絶対採用しないという強い意思がないと、STLのような素晴らしいライブラリを発明するのは無理だろう。普通の人間にはなかなかできないことだ。良いガイドラインがないといったけど、Boostライブラリのような優れたライブラリのドキュメントは結構あるものだ。ただ、オブジェクト指向を採用しないアプリケーション開発についてのものはそんなに見つからない。ゲームプログラミングにおいては、書籍とかだとまず何かしらオブジェクト指向的な手法を使っている。そういったものをすべて無視して、独自の技法を編み出してやらないといけないというのは、自分の熟練度じゃちょっと厳しい。もしかしたら、そこを模索して考えだすのが楽しいのかもしれない。今から始めてもいいけど、今までやらなかったのだからこれからもやらない可能性がある。いや、きっとやらない。

     オブジェクト指向をやりたくないからC++をやめるというのは、極端な選択だ。それだけが理由ではないが、もしRustがオブジェクト指向を中心に据えた言語だったら、たぶんそれほど魅力を感じなかったのは間違いない。Rustがオブジェクト指向を完全に排除しているわけでもないように思える。先日、GTKのRustバインディングであるgtk-rsをいうのを触ってみたのだけど、それはオブジェクト指向をベースとしている。GTKはGObjectをベースにしたちょっと特殊なライブラリであるので、参考にはならないかもしれない。しかし、可能だということだ。ただ、これは、Cでオブジェクト指向が可能といっているのとさほど違いはなく、Cを使うときにオブジェクト指向を意識するかというと、通常はしない。それと同じことで、Rustを使うときにオブジェクト指向を意識するかというと、たぶんしなくて良いと踏んでいる。C++を使うときオブジェクト指向を意識するかというと、おそらく悟りでも開かなければ、どうしてもしてしまう。Rustも、データに関連付けられたメソッドを中心に何かを行うというのはあまり変わっていない。さらに、継承、多態、カプセル化といった要素も含まれているように思える。しかし、従来のオブジェクト指向とは随分異なっているように見える。何より、Rust自身がオブジェクト指向言語だと公言していないので、きっとそうなのだろう。

     オブジェクト指向から離脱したあとに何が残るか、まだ分からない。関数型言語であれば、きっと関数型言語のプログラミングスタイルを身につけることに没頭すれば良くて、分かりやすい。Rustの場合はどこへ向かえばいいのかまだ良くわかっていない。登場して10年と少しといったところで、最近急激に成長した言語で、ユーザー数も多く、そこそこのノウハウが蓄積されているだろうから、まずはそういったところを吸収していくのが良さそうだ。プログラミングスタイルを身につけるのはいいとして、もう一つ重要なのが、設計手法だ。オブジェクト指向による設計を諦めるということは、何かしら別の方法をまた身につけないといけないということになる。問題をクラスに分割して、サブルーチンに分割して、といった手法があまり通用しなくなるのではないか。もっとも、設計についてちゃんとした訓練をしてきたわけでもないので、それほど失うものはない。これからまたリフレッシュしてやっていけばいいだけだ。

  • Rustでなにか作る

     「プログラミングRust 第2版」を読み終えた。これでRustを使い始める準備はできた。スタート地点には立てたのではないだろうか。記憶は風化していくものなので、ここで満足せずに継続的にプログラムを書いていくことが求められる。どんなプログラムを書いていくのがいいのだろうか。Rustはシステムプログラミングの分野でCとC++を置き換えることを考えられて作られた言語だ。なので、システムプログラミングをやることがRustを知るには最も良い方法となるのだろう。最近の動向では、システムプログラミングとは呼べないような色んな分野で活用されているようだ。例えば、WebAssemblyやマイクロサービスによるWebアプリケーションとかでの活用だ。他にも、GTKは公式のバインディングが提供されていたりして、デスクトップアプリケーションでの活用も、実際にどれだけ利用されているのかは置いておいて、進んできている。ゲームもそうだ。「プログラミングRust」では、システムプログラミングとは何かというのが書かれていて、その中にゲームも含められている。ゲームは比較的速度が求められる。おそらく、どんなゲームというわけでもないだろう。ここで想定されているのは、最新のグラフィックスハードウェアの性能を限界ギリギリまで引き出そうとするような、一部のトップタイトルのことを指しているのだと思う。1日で書けるようなクラシックでシンプルなゲームをシステムプログラミングと呼ぶことはないのではないかと思う。今作りたいのはそういうシンプルな練習用のゲームだ。そういうゲームにRustの安全性は過剰だし、効率性はオーバースペックなように思える。本当にRustが必要とされるのは、やはりシステムプログラミングなのだろうから、システムプログラミングを題材としてトレーニングしないとRustの真の性能を引き出すことはできないかもしれないし、良いプログラミングのスタイルは身につかないかもしれない。でも、そんなに構えて、こうあるべきだ、とかならなくてもいいかもしれない。まずはシステムプログラミングにも、そうではない、普通のプログラミングにも当てはまる、公約数の部分のプログラミングを身につけることを目標にするといいだろう。ちょっと回りくどい。わかりやすく言うと、今までやってきたことをRustに置き換えてやっていって、徐々になれていくということだ。その一環として、シンプルなゲームを作っていきたい。

    新しいことにもチャレンジしたい。さっき書いたWebAssemblyは興味がある。Rustじゃないとだめなのかどうかは知らない。ただ、Rustの本でそういうのを見かけたというだけ。今の時代、ゲームの最大のプラットフォームはスマホだろうけど、次点でWebが来るのではないだろうか。ゲームの規模や特徴にもよるけど、シンプルな練習用の2DゲームにPCやPlayStationなんかは大げさ過ぎる。そういうのが存在していても、あまりプレイしたいという気にはならないだろう。プレイしてもらうことが目的ではないのでそれはそれでいいかもしれない。しかし、誰にもプレイされないゲームというのは虚しいものがある。Webはそういう心配はあまりない。つまらないゲームでもページを開くだけでプレイできるというのは、考えられる最も手軽なプレイ環境ではないだろうか。積極的に面白いゲームを探している人でなくても、何かの弾みでついそのページにたどり着いてしまうということが考えられる。経緯はなんであれ、作ったものが使ってもらえることは嬉しいもので、次のステップへの弾みになる。今の時代、よっぽど目を引くようなルックスをしていて、プレイヤーを誘致するような仕掛けがされていないと、わざわざダウンロードしてきてPCの記憶領域の一部を専有するようなインストール手順を踏んでまでしてプレイしようという気にはならないものだ。それにWindowsもMacも持っていないので、Linuxユーザー向けのゲームとなるとさらにプレイしてもらえる可能性は低くなる。スマホもインストール手順をふまないといけないし、記憶領域を必要とする点ではPCと変わりないのだけど、圧倒的にユーザーが多い。老若男女問わず、多くの人が利用しているプラットフォームだということで、インストールの面倒さを帳消しにしてくれる。でも、スマホの開発をやりたいとは全く思えない。今の所Rustでやるのは無理だろうし、そうでなくても、予め決められた環境の中で、一定の手順を踏んで組み立てているだけのような感じで、プログラミングの占める割合が低い、という先入観がある。決められた枠内でというと、Rustも制約が多く、自由な環境を重視するならRustを選択する理由にはならないのではないかということも言える。Rustは安全性のために制約を課し、スマホは便利なデバイスを利用するために制約を課すという違いは同質なものとは言えない。プログラミング言語のほぼすべてが、プログラマーに何らかの制約を課す。ifはこう書かないといけないとか、そういう取り決めがなければ、何もすることができない。CPUのレベルに至ってもそうだ。このビット列はこのように解釈するという決まりがなければ、CPUは何もすることができない。Rustによってがんじがらめにされるというのは、その延長だと言える。プログラマーの自由な精神活動を妨げるようなものではない。なんか大げさなことを書いてしまったようだけど、 ただ単にスマホにはあまり興味がないというそれだけのことだ。

    スマホをやらないとすると、PCかWebAssemblyなんだけど、どっちもやればいいだろう。まず基本はPCだろう。利用できるライブラリが豊富にあるので、学習にも向いている。このプラットフォームで十分に経験値をためてから、WebAssemblyに移るのが良さそうだ。PCはLinuxのマシンしかない。なので、プレイしてもらうという考えは捨てて、レベル上げのためだけにやるということになる。競技プログラミングとかやるのとあまり違いがない。モチベーションを維持できるかどうかが問題となるだろう。何かしら外部にアピールして自己欲求を満たす仕組みを用意しないと、継続するのは難しそうだ。単純なのはGitHubのようなところでソースを公開するとか、YouTubeでライブ配信するとかそういう手段がある。そういうのはPCでもWebでやるにしても同じことなので、早めに手段を確保してしまうのがいいだろう。しかし、目的を違えてはいけない。ゲームを作ることあるいはプログラミングそのもの目的であって、それ以外は付属的なものに過ぎない。

     

  • Rustと並行プログラミングについて考える

    昨日はRustに乗り換える計画について書いた。そんなに書くことないかなと思っていたのだけど、書き始めると意外と指が動いてそこそこの文量を確保することができた。もう今の段階で書けることは書き切った感がある。それでももう一度書いてみることにしてみようと思う。書き始めればなんとか文字を埋めることができるかもしれない。今、オライリーの「プログラミングRust 第2版」を読んでいて、残すところあと2章となった。今日はこの本でおそらく一番難しいところと思われる、並列性と非同期プログラミングの章をなんとか読み切った。記憶が風化しないうちにそれらのことについて書くのが良いのかもしれないけど、さすがに経験不足のため、何も書くことがない。Rustの並行処理のサポートは充実していて、並行プログラミングについて学ぶにも良いプラットフォームになっている。もし、C++で並行プログラミンの経験を十分に積んでいたら、書くことはたくさんあっただろう。何の経験もない自分でも、Rustのマルチスレッドの扱いは、言語の方向性とぴったりと合致して、自然な感じで統合されていることに感動すら覚える。そういう感覚的な、これは良いとか難しいとか感触を確かめることはできたのだが、言語化できるほどは体得できていないので書くことができない。具体的にどういうケースでマルチスレッドを採用したほうがいいとか、非同期処理にしたほうがいいとか、そういうのがない。

    並行プログラミングは自分の中でボトルネックとなっている部分でもあると思っている。こいつをなんとかしないとこれ以上先に進めないのではないかとすら思っている。マルチスレッドもごく小さな範囲に閉じ込めて、他のどこにも影響が出ないようにしたような、限られた利用の仕方くらいならなんとか扱えるかもしれない。それだけできれば、現実、なんとかなってしまうようなケースがほとんどという状況にある。もしくは、並行プログラミングなど全く必要ないというケースが大半だ。これで悪循環が生まれる。並行プログラミングができない、したがって、並行プログラミングを扱う開発はできない。しかし、並行プログラミングができなくても達成可能な案件はたくさあるので、そういったものをこなしていけばいい。結果、いつまで立っても経験を積むことはできず、並行プログラミングを身につけることはできないままになる、というサイクルに陥る。この悪循環を断ち切るには、積極的に並行プログラミングを身につけるトレーニングをするしかない。

    並行プログラミングのトレーニングが必要なことは分かった。では、具体的にどういうことをすれば良いのだろうか。プログラミングにおいて、わかりやすく、効果も期待できるトレーニング方法は、実際にプログラミングをすることだろう。さらに、実験的なプログラムではなく、ちゃんとした実用性のあるプログラムであればなお良い。実用性のあるプログラムというのはなかなか難しいかもしれない。そんなに大したものを考えなくても良い。他人が使って便利だと思うものでなくても、自身の日々のタスクを効率化してくれるような、小さなものをたくさん作ってみるところから始めるのがいいだろう。実用性というものの解釈を広げて、作って楽しいものとか、遊んで楽しいもの、要はゲームをつくればいい。ゲームには並列化するような要素がたくさんあるのではないだろうかと思う。これまでは、ゲームを作るときに並列化するかどうかなど検討もしなかった。そこを意識的に、どうやったらこれを並行処理させることができるだろうと、考えていくことにする。おそらく、無駄に複雑化して間違った設計になってしまうこともあるだろうけど、そうやっていかないと、最初から可能性を捨ててしまうといつまで立っても並行処理を行うかどうかの判断力もつかないし、プログラミングもできないままになる。例えば、小規模なミニゲームなんかでは、伝統的なシングルスレッドのプログラミングモデルで十分達成可能なことがほとんどだ。並行処理でなければどうしても達成できないことなどあまりないので、意識してやらないと永久に打順は回ってこない。

     そういことで、これからしばらく、おそらく来年は並行プログラミングを身につけることを目標にやっていこうと思う。言語はC++からRustに移行することを念頭に置きながらやっていくことになる。これは並行して進めていく計画なので、一種の並行処理といえなくもない。C++の標準ライブラリには並行処理のサポートが含まれている。比較対象として療法を同時にやっていくのも悪くなさそうだ。目標はRustに移行することなので、Rustを基準にしながら、C++のプログラミングも並行していく、これもまた並行処理と言えなくもない。こうしてみると、現実でも、人間の脳も並行に何かを行うができるようになっていて、割と自然に効率良くできるようになっているようにも思える。こじつけだけど。比較対象はC++に限定する必要もないだろう。現代的なプログラミング言語やそのライブラリには何らかの形で並行プログラミングをサポートするツールが提供されている。それらに広く手を出してみることでも、成果は得られそうだ。例えばGo言語にはgoroutineというのが言語に備わっている。以前Goをやっていたときは、その存在を無視していた。もうGoに対する関心は薄れてしまったのだけど、改めてそこに着目して、並行処理に特化して学んでみるのも悪くない。

     あと、並行プログラミングのアルゴリズムを学ぶ必要もありそうだ。 アルゴリズムはライブラリが提供するものとして、軽視されがちなところがあるけど、基本的なアルゴリズムを学ぶことによるコーディングスキル上昇値はかなり高い。逆に、重要だけどしばらくは学ばなくても良さそうだと思うのは、OSに近い低レイヤの部分だろう。Linuxカーネルがどうやってスレッドを管理しているかとかは、興味はもちろんあるけど、しばらくは保留しておく。言語とライブラリによって提供される、表面にまずダイブして、徐々に下に潜っていく、トップダウンのアプローチが良さそうだ。

    最初は並行プログラミングについて書こうと思っていたわけはなかったのだけど、書き始めたら結構指が動いたので、今回はそのまま続けてしまった。その結果、だいたい今後の方針が固まってきた。来年は並行プログラミングの1年になるようにしよう。

  • Rustに移行することを考える

    昨日はなんとか文字数を稼いで、それっぽい投稿に仕上げることができた、たぶん。今日は何を書こうか良いアイデアがない。それで、今Rustの本を読んでいるのでそのことについて書こうかと思う。まだ本を読んでいるような学習中の段階で、実際に何か開発した経験があるわけでもないので、思い込みや勘違いも含まれるだろうけど、それもいいだろう。

    今読んでいる本は、オライリーの「プログラミングRust 第2版」というものだ。第1版は数年前に読んでいる。その時からRustにメインでしようする言語を乗り換えることの可能性を考えていた。長いことC++を使ってきたけど、C++が完璧な言語だと思ったことなどなく、いろんな欠陥を抱えているということは認識していた。それでも、近年の標準仕様のアップグレードによって、良い方向に向かってきているようにも感じていた。仕様が膨れ上がっていって習得するのが大変になってきているという問題はこの際考えないでおこう。もし十分に学習と訓練ができて、正しいプログラミングが習得できるならば、C++は悪い選択肢ではないと思っていた。

    しかし、この本ではC++、それにCが抱えている重大な欠点を明らかにしている。それはCとC++だけの問題ではなく多くの言語に当てはまることなのだろう。他の言語では問題にならなくても、CとC++だけは、現実でシステムプログラミングで使用される特別な言語であるから、そのような欠点は無視できないということだ。システムプログラミングと呼ばれる領域で開発をしたことがないので、この本を読むまでそういった視点でC++を眺めたことはなかった。この本が指摘しているCとC++の欠点は、説得力があり、納得できるものだった。それは何なのかと一言でいうと安全性ということになる。CとC++では、どうしても解決できない本質的な問題を抱えている。それを解決するためには、抜本的に言語を見直して、CとC++のシステムプログラミングに適した性質を引き継いだ上で、さらにまだどの言語でも採用されたことのないような、革新的なアプローチが必要となる。Rustはそれをやってのけている。

    Rustの安全性は無償で手に入るわけではない。安全性を担保するために、厳しい制約をプログラマーに課している。 そのため、がんじがらめのルールの中で仕事をしないといけない。それって楽しいのだろうか。楽しくないかもしれない。でも、C++で書いていたときだってそれは同じことだった。奇妙なルールやあまり簡単ではないテクニックや注意を身につけるために、膨大なトレーニングを必要とする。もうかなり長いことC++を使ってきていると思っているのだけど、全く終わりが見えない。Rustのがんじがらめのルールは、C++でプログラマーが自主的に身に付けて、正しくプログラミングすることを期待していた部分を、言語の方で強制してしまうためのものとも言える。C++は、自分で自分を強制的に安全なルールに従うようにするのに対し、Rustは、言語がプログラマーを強制してしまう、という違いではなかろうか。どっちのアプローチが優れているかは分からない。少なくとも、システムプログラミングにおける安全性という面では、Rustの方に軍配が上がるように思える。

    Rustは安全だというのが、C++を捨ててRustに乗り換えることを検討するようになった理由なのかというと、ちょっと違う気もする。先に、C++は一向に終わりが見えないといった。もしかしたらRustはそうではないのかもしれないという淡い期待があるからだ。プログラミングの旅には終わりはないだろうとは思う。しかし、使用する言語にすら全く終わりが見えないってどうなのだろうと考えてみたくもなる。Rustには厳しいルールがあるが、それは一度習得してしまえば、そして経験を積めば、自然とプログラミングできるようになるのではないだろうか。C++で正しいプログラミングをするために、終わりのないトレーニングで身に付けたことというのは、もしかして、Rustによって強制されるルールの範疇ではないのだろうか。Rustでは、無知あるいは不注意を原因とした、正しくないプログラミングが排除されるため、積極的に言語の終わりのないトレーニングを要求される状態から解放されるのではないだろうか。その夢のような境地立てるかどうかを試してみたい。 

     どのような、一見簡単と言われる言語であっても、何かの目的を達成しようとすると、その目的に相応の難しさというのはつきまとう。しかし、それはプログラミングで解決しようとしている問題に備わっている難しさであって、言語によるものなのかどうかというのは別問題になる。また、ある問題はこちらの言語の方が簡単で、別の問題はあちらの言語の方が簡単ということは普通にあることだろう。Rustの場合、専門はシステムプログラミングということになる。システムプログラミングに特化して設計された言語であるなら、その領域でC++より優れたパフォーマンスを発揮するというのは、ありうることだ。システムプログラミングではRustはC++より簡単ということになるのだろうか。そもそもシステムプログラミングが簡単なものではないので、簡単と表現するのは適切ではないだろうけど。

    自分の場合、今、最も関心のあるのはシステムプログラミングではない。OSを作りたいとか(夢には見るけど)、クリティカルなリアルタイムのシステムを作りたいとかはない。アプリケーションのプログラミングの方をやりたい。もっというとゲームプログラミングだ。ゲームエンジンを開発したいわけでもなく、ゲームそのものをプログラミングしたい。それでもRustは良い選択肢となるのかどうか、分からない。Rustは汎用プログラミング言語としても優れているのだろうか。その辺がよく分からない。まだ決断はできてないけど、来年はおそらくRustに移行する方向で活動をしていくことになるのではないかと思っている。C++を完全に捨てるわけでもない。最新の仕様にも興味があるので追いかけたりはするだろうし、巧妙なプログラミングテクニックなんかを身につけるのも楽しいものだ。しかし、空間も時間は無限ではない。興味のあるものすべてを集めていったらいっぱいになってしまう。本当に必要なものを見極めていかないといけない。

  • Hello, ブロガー!

    ポエム風なブログを書くことにした。

    去年は1年間日記を継続して書き続けることができた。まさか1日も空けずにできるとは思わなかった。それはそれで、また続けていくつもり。ちょうど1年経過して、今日は12月1日と区切りも良いので、新しいことを何かやってみることにする。

     題材はプログラミングにする。というか、それしか書くことがない。プログラミングのポエムになる。技術的な話題ではなく、何かしら思うことを書いていく。特に目的はない。プログラミングのことについて文章を書こうとすると、つい作業ログや備忘録のようなのものになってしまう傾向がある。今回はそういうのを意識的に避けていく。何かの活動は行うとして、それに対して感じたことなんかを書くようにしていきたい。

    まずは、今年の残り12月は、毎日継続することだけを目標にしよう。かと言って、数行程度のものではなく、ある程度の文字数で埋めたい。一方で、こんなことにあまり時間をかけたくないというのもある。1日の終わり頃にさくっと書き殴るぐらいのクオリティでいい。頭に浮かんだことをとにかく文字に書き出すといった習慣を定着させてしまいたい。一度身に付けてしまえば、そんなに負担にならないだろう。まずは最初が肝心だ。そういうことを書きながらこの投稿も文字数を稼いでいる。こんな感じで進めていきたい。

    とにかく文字数を稼ぐというのは良い案なのだろうか。なんかコードの行数でプログラムの規模を測るようで無意味な基準にも思える。これだけ文字を書いたのだから、それなりの文章力が身についているはずだ、ということにはならないだろう。しかし、文書を書くトレーニングを受けたことのない身としては、とにかく書くというのはそんなに悪くないことのように思える。ここでやりたいのは、情報を伝えるということではなく、この場を借りて自分が何を考えていたのか整理したい、あわよくば文章を書く能力をアップさせたいといったことだ。目的はない、といったけど、そういう下心がないわけでもない。

    もうちょっと文字数を稼ぎたい。しかし、徐々に書くことがなくなってきている。こういうときはどうするのが良いのだろう。これから先もこういうことはありそうだ。ここで止まってしまうと、モニターとキーボードの前でぼーっとして、時間だけ経過してなかなか進まないという状態になる。物書きになるつもりは全くないが、生業にしている人もおそらくそういうのを乗り越えていかないのではないだろうか。ソフトウェアのドキュメントなんかは、先に書くべきことが決まっているので、良いドキュメントを書くのは大変だが、あまりこう何を書けばいいのだろうというような状態にはあまりならない。ポエムとなると、何を書いてもいいというのが逆に制約になってしまう。

    ブログは何度か挑戦したことがある。どれも長くは続かなかった。今回は続くという保証もない。しかし、今回はちょっと違うことがある。こんなに無意味で長い文章を書いてはこなかったということだ。投稿を文字で埋めると、こんだけ書いたんだ、という間違った充足感を得ることができる。これは次の投稿への景気づけになるし、続けていけば段々とブログ自体に愛着も湧いてくる。ここで目的がないといったことに意味がある。目的がないので間違った方向に進んでもそれは間違いではない。ただ、結果として価値のある情報を持たいない長い文章を考えるスキルと、思い浮かんだことを即座にキーボードを通して吐き出すことのできる、条件反射的なスキルが身につく。

    それって何か意味あるの、という疑問もある。狙いとしては、ここで止まってしまうのではなく、価値のある情報を文章で表現できる能力につなげていきたい。これは今書きながら思いついたことで、別にそれが目的でこのブログを始めたわけではない。ただ、こういう感じでだらだらと長い文章をかけるようになれば、真面目に、役に立つ記事を投稿したいとなったとき、自分が抱えている情報をすぐさま公開できるようになっていくのではないだろうか。それはまた別に訓練が必要になる。なんでもいいから書くというのと、余計なものを書かず、的確に文章を構成して、それなりに見栄えのするような文章にするというのは、また違った技術になるかもしれない。

    結構書いたのでだいぶ満足した。ここまで無意味な投稿を続ける気はない。題材はプログラミングなので、これからはもう少し内容のあるものになるかもしれない。