長くなったので先に三行でまとめておこう。
- コピペするプログラマが生まれるのは教育の問題ではないか(仮説)
- 文法は学んでも処理の流れから考えることは教わっていない(根拠)
- ロジックを訓練するには脳内プログラミングが良いのでは?(提案)
少し前に私のMediumで、こんな記事を書いた。タイトルが言葉足らずだったおかげで、少し話題になった。「量産型プログラマを撲滅したい」
今回の記事では、この中で書いたコピペするプログラマがなぜ生まれるのか、どうすれば良いのか、考えてみたい。
目次
どうすれば見分けられるのか
書いたプログラムを説明させてみれば、その人が、ちゃんと考えて作れる人か、コピペでしか作れない人か、すぐにわかる。自分の書いたプログラムの流れを説明できるということは「わかって書いた」ということだ。わかっていなければ説明できない。
「わかって書く」という一見すると当たり前のことができない人もいる。この判定は何も難しいプログラムである必要はない。
英語で書かれた文字列中に含まれる英単語の個数を単語ごとにカウントする(参考)
こんな程度のプログラムでも構わない。
これを作ろうとする際に、どこから手をつけるか。考えて作れるプログラマは、最初に自分の頭でプログラムがどういう流れになるか考える。もし、問題が大きければ、頭で考えられるサイズに分割する。
コピペしてしまうプログラマは、まず手を動かそうとする。もしかすると、最初からググってしまうかもしれない。参考になるプログラムを探して、似たようなものを持ってきて、コピペしてしまう。
この程度の問題ならば、検索すれば全く同じ問題と答えがセットで出てくるので、それで作れてしまうかもしれない。だが、説明させてみれば、説明できないだろうし、動かなかった時に、手詰まりになってしまう。
ちなみに熟練したプログラマになると、考える時間が非常に短く、コンピュータからのフィードバックと共に作っていくため、まるで考えずに手を動かしているように見えることがある。まぁ、どんな世界でも、見てるだけなら簡単そうに見えるものだ。
コピペは本当に悪なのか
プログラム内に似たコードが散在するのは、保守性を下げるので、単純に良くない。だけど、ただコピペがすべて悪という訳ではない。文法をすべて覚えている訳などないし、今やライブラリは膨大にある。
だから、覚えていない文法の書き方や、ライブラリの使い方などは、使い方のサンプルコードを真似して、コピペして使うこともあるだろう。それは、ベテランだって変わらない。
違いは、コピペするにしても、そこに貼り付ける理由があるかどうか。プログラムの流れはわかった上で、使い方や表現がわからないところだけコピペをする。
それなら中身がわかっていなくても、使い方がわかっているから応用もできるし、リファクタリングできるし、自分の書いたところの不具合やエラーも、自分で解決できるはずだ。おそらく。
コピペのためのパターン認識
問題は、コピペで作るような作り方しか身についていない人でも、同じ言語とフレームワークで経験を積めば、それなりのパターン認識ができるようになって、動くものができるようになってしまうことだ。
しかし、パターン認識とコピペで作られたプログラムはコードレビューをするときに非常に困る。読めないのだ。スッと上から順に読むことができないプログラムになる。意図の読めないコードになっているからだ。
なぜ、この変数名にしているのか。なぜ、このタイミングで変数を宣言するのか。なぜこう分割するのか。。。そもそも書いた本人にも理由がないのだから、読む方も意図を汲み取れるはずもない。
なまじ動くし、動作テストも通ってしまうものが作れてしまうと、そこから中途半端にリファクタリングするのも難しい。いっそゼロから作った方がシンプルに作れるのに・・・そんなコードが出来上がる。
なぜコピペするようになってしまうのか
果たして、こうなってしまうのは、そんな風にコピペで作ってしまうプログラマ本人の資質やセンスの問題なのか。いや、その人のプログラミングの習得方法に問題があったのではないだろうか。
もとからの頭の良し悪しではなく、知識の有無でもない可能性がある。良い大学を出て、色々な本を読んで勉強してる人でも、プログラムを自分でゼロから作れない人もいる。
もちろん、コピペで作るように教わって、コピペで作っていくうちに、たまたまセンスがあり努力がする人なら、コピペしたままでなく色々と試すことで動作の原理原則を自分で見つけて、意図を込めて考えてプログラミングできるようになるかもしれない。
しかし多くの現場で考えて作ることを期待していないのだとしたら、本人たちも、コピペで作ること以上に意識を働かせることもないだろう。もしくは向上意欲のある人なら、そんなコピペの仕事は嫌なので、もっと違うことができるように努力して、マネジメントなど別の職に移るだろう。
プログラミングに対する認識の間違いが、こうした問題を生み出しているのではないだろうか。その問題の根っこは何か。
その一つは、コンピュータは曖昧なことは判断できず全部ロジックが必要で、必ず上から読み込む順番にしか処理ができないこと、プログラムに正解はなくて色々な書き方ができるということ、それらを知らない。教わってないからではないか。
そう考えると、プログラミングの基本的な考え方がなく、経験だけで習得したのだとしたら、パターン認識とコピペで作るようになったとしても、不思議ではない。それで作れるようになったのは、むしろすごいことではないか。プログラマとしてはダメなんだけど。
文法は教えても、文章の書き方は教えてない
多くの書籍や、特に最近の学習サイトでは、プログラミング言語を教える際に、その文法を教えることはあっても、プログラミングの仕方を教えることがあまりない。
プログラミングができる人が新しい言語を覚えたり、初心者が文法を覚えるなら良いかもしれない。だけど、それは暗記だ。そこに書かれた通りに打ち込めば、こう動きますよ、というのを繰り返しているだけで、文法を覚えることはできても、プログラミングできる力は鍛えられていかない。
それは、まるで日本語や英語の文法を教えているけれど、文章の書き方は教えていないようなものだ。それでは、似たような問題ならば解けるけれど、自分の思いを綴ることなどできないだろう。
書いてある通りに手を動かすだけでは、出来るようになったとは言えないし、文法や書き方を暗記したところで、学習サイトが出す問題は解けても自力でプログラムを書くことはできない。
あまり考えることもなく手を動かすことだけを求められる現場では、それで通用するかもしれない。マニュアルとルールが指示書があって、その通りに作るだけの仕事なら出来るようになるだろう。だけど、何か新しいものを作りたいのなら、文法を覚えただけでは難しい。
プログラミングの仕方を身につけるには
では、文法を覚えるだけでなく、プログラミングの仕方を身につけるには、どうすれば良いか。とても小さいプログラミングの仕方を分解すると、こうなる。
- 作ろうとするプログラムの仕様を把握して理解する
- どう確認すれば良いか考える(テストコードまで書ければベスト)
- プログラムの流れ(ロジック)を考える(日本語でも良い)
- ロジックをプログラミング言語に従ってコーディングする
- (動作確認をした後にコードを読みやすくリファクタリングする)
もちろん、もっと大きなシステムになったり、複雑なアーキテクチャの上で作らないといけない場合は、また変わってくる。そう単純ではないと思うかもしれないが、本当の本当に単純化すれば基本はこうだろう。
この中で、3のロジックを考える部分が抜け落ちているから、コピペしてしまうのではないだろうか。では、ロジックを組み立てる力、すなわち「プログラミング脳」を鍛えるにはどうすれば良いか。
プログラムの流れを先に考えてから、プログラムを書く癖をつける。まずは日本語でも良いから、処理の流れを書くようにする。処理の流れとは、ロジックのこと。ロジックを考えないと、コーディングしてはいけない縛り。ロジックは、日本語で書いても良くて、筋が通っているかどうかが大事だ。
もちろん、これは訓練のためで、現実的なプログラミングになると、コンピュータと二人三脚で作っていくことになる。少しずつ、コードを書いて、少しずつ試して、動く状態を維持しながら、拡張させていくのが良い作り方だ。もちろん、頭の中で、少しずつどう動くか想像してから書いていく。
そして、頭の中で考えるだけでなく、コンピュータで実行させて、それが正しいことを確認しながら作っていく。一度にドカンと書いて、一気に実行させてみるようなやり方は、あまり良いやり方ではない。コンピュータがミスをすることはない。ミスをするのは人間だ。だから、コンピュータで確認しながら作る。
実際は、3,4を小さな単位で繰り返しながら作っているが、それでも3のロジックを頭の中で作ることは必要なのだ。
頭の中のコンピュータを鍛えよう
プログラミング脳とは、頭の中にコンピュータがあるようなものだ。自分の頭の中のコンピュータでうまく実行させられるロジックが出せたら、あとは手を動かすだけになる。
ロジックから考えるプログラミング脳ができれば、プログラミング言語が変わっても、ある程度プログラミングは出来る。ロジックの作り方には種類があって、それがパラダイムと呼ばれるものだが、その話は今回は割愛する。
ソースコードを読むときも、頭の中のコンピュータが活躍する。読みながら本物のコンピュータの代わりに、頭の中で順次処理をしていく。実際に変数に何が入って、関数を呼び出せば、そちらに飛んで、引数には何が渡って、繰り返しの中でどう変化していくのか、実行される様子をイメージする。
それが本当にコードを読む、意図を汲み取るということだ。表面をなぞるだけではない。プログラムのソースコードは、コンピュータの実際の動きを抽象化したものなので、脳内コンピュータで具体化するのだ。
良い文章を書くには良い文章に触れなければいけない。プログラムも同じことだ。ただし、表面を読むだけではだめで、自分の頭の中で実行させてみることだ。表現を真似るにしても、実際の動きを理解していないと真似はできない。
頭の中のコンピュータは訓練で鍛えることができる。その処理速度、記憶容量が増えれば、ある程度の大きなプログラムのロジックでも頭の中で作ることができるようになる。最初は本当に小さなプログラムから初めてみるべきだ。小さなプログラムでさえロジックで説明できないなら、なおさらだ。
また、自分が書いたコードを有識者に見てもらうことも、もちろん良いだろう。自分の頭で考えて作ったものならば、レビューされると、もっと良いコードが染みてくるだろう。頭の中のコンピュータの精度を高めることができる。
コピペで作ったものをレビューされても、納得感はないから、またコピペで再現されてしまう。少なくとも、ダメなパターンとして蓄積されて、似た書き方は避けるようになるかもしれないが、良いコードが書けるようにはならない。
プログラミングを学ぶ最初に身につけること
頭の中のコンピュータは、処理をさせればさせるほど、鍛えられていく。そんな脳内プログラミングをすることが、ロジックから考える訓練になるだろう。こればかりは、1度やれば良い訳ではなく、繰り返さなければ身につかない。
訓練の題材としては、アルゴリズムを作るような問題を解いてみるのも練習になるだろう。今どきは世の中にたくさんのライブラリがあり、アルゴリズムを自分で組むことはないし、必要もない。だけど、頭の中のコンピュータを鍛えるには良い。あえて、ソート(並び替え)など自分で書いてみるのだ。
車輪の再発明をする必要などないし、しないほうがいいと教わるだろう。だけど、練習のためには作ったって良いのだ。小さなプログラムでも、全部一人で自分の頭で作る経験をした方が鍛えられる。
コピペで作る経験をいくら積んだとしても、コピペがうまくなるだけだ。そして、新しい技術や仕事に出会ったときに、またパターン認識から始めるので、効率が良くないし、どこかで限界がくるだろう。
ロジックから考えられる「プログラミング脳」があることが、その先の成長曲線が大きく変わってくるのではないか。最初の最初に覚えることは、フレームワークの知識ではなく、ここなのではないか。
・・・という仮説。今、初心者を育てながら、この仮説の正しさを実証しようとしており、手ごたえを感じているところです。
合わせてこちらも、ご覧ください。「これからプログラミングを学ぼうとする君へ」
***
【ソニックガーデンキャンプのご案内】
私たちソニックガーデンでは、プログラミングスキルを磨きたい方、エンジニアとしてより一層成長したい方向けに、仲間と一緒にゼロからWebアプリを制作する「ソニックガーデンキャンプ」を実施しています。
これは講師が手取り足取り教えるスクール形式ではなく、参加者同士がコミュニケーションを密に取り合いながら開発・学習を進めていく形式です。
自分だけでは成長に限界を感じていたり、どうすればエンジニアとして働けるかわからず悩んでいる方がいたら、ぜひチャレンジしてみてください。
ソニックガーデンキャンプ → https://camp.sonicgarden.jp/