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。