以下のエントリ、の続きのようなもの。 blog.kolmas.tech このエントリで書いた通り、生成AI勃興の今におけるプログラマの役割は、変化する事はあり得ども無くなることはないと考えている。一方で、これからプログラミングを修めようとする人に対して、どのようなアプローチが望ましいのかについては、少し考える所もある。
元・非常勤講師
プログラミング遍歴後半や学習と感動に関するエントリでも述べたが、大学院生をしていた傍らで、学部新入生向けの情報技術・プログラミング入門的な科目の講師をしていた。全新入生をカバーするために一学期間に複数のクラスを開講する半必修の科目で、私のような情報技術分野の後期博士課程在学者がよく講師をしていた。教材は全クラス共通のものが元から用意されていて、それに基づいて授業をするのが仕事であった。ほとんどの受講者は、プログラミングの「プ」の字に触れたことすらないレベルの完全な初学者である。
当時のこの科目では、コンピュータやネットワークに関する極々基礎的な内容の座学に加えて、クライアントサイドJavaScript1を使ったプログラミング実習2があった。教材には練習問題も色々と用意されていて、授業時間中に練習問題で手を動かす時間を作ったり、一部は宿題にしたりした。授業時間中の実習は、机間巡視していると教室の全体的な理解具合が大雑把に分かるし、遅れ気味の人にはサポートも出来る。一方で、授業時間内で全てこなしきれないほどには練習問題の量があったし、またそもそも受講学生による授業内容の復習のため、また講師としては各学生の理解度合の詳細な把握もかねて、一部の練習問題を使ってほとんど毎週宿題を出した。
講師の謎眼力
さて、宿題を出したからには提出物の採点をする。提出されたプログラムが練習問題に指定された要件通りに動作する事を確認するのは勿論だが、それが正しく動作する場合もそうでない場合も、そのソースコードの内容まで確認する。私が受け持っていたのは一学期につき学生30人程度のクラス一つだけであるが、それでも地味に大変な作業ではある。それをしばらくやっていると、変な眼力が身につく。学生が自分でプログラミングしたのではなく質問サイト等の回答をそのままコピペして提出してきた時に、分かるようになるのである。明確な基準がある訳ではないのだが例えば以下のような事項について、これまでのその学生のプログラムの癖から逸脱した「良く出来ている」ものが突然提出されてくると、このセンサに引っかかる。
- 機能要件に関わらない部分の書き方が突然に洗練される。変数・関数の命名とかインデント・空白の入れ方とか、授業でも説明するのだが、初学者がそれらをいきなり綺麗にこなすことは、私の経験上、難しいように見える。
- 機能要件に対して、無駄に回りくどい解法でプログラムが作られている。例えば、条件分岐と繰り返しの説明が終わったタイミングで出題されたシンプルなFizzBuzz問題に対して、まだ講義で扱っていない配列を使ったプログラムを出してくるとか。
- 他にも、上手く明文化出来ないのだが、学生自身が新たに体得できたものではない何かが、何故だか見える。
もしこのエントリを学生が読んでいるとしたら、講義課題におけるソースコードのコピペはこのような理由で普通にバレるという事を警告しておく。そのようなバレそうな点を回避する努力をするくらいなら、最初から自分でプログラミングした方が早いし為になる。というか、そもそもその回避努力ができるくらいなら恐らく自分でプログラミングできる3だろう。
謎眼力vs生成AI
勿論、仮に上記のような点が引っかかっても、疑わしきは何とやら、コピペ元の存在確認が出来ない場合に不正として対応することはしない。とはいえ、そのセンサに引っかかったプログラムの特徴的な部分を抜き出してググったりすると、大抵はコピペ元4が見つかったものだ。他には、一学期の中で形成されていった仲良しグループ数人の中に良く出来る学生が一人いて、グループの残り全員がその一人の提出物をコピペしてくる、というパターンもあった。ただ、後者のパターンはともかく、前者のウェブ上に掲載されたプログラムのコピペの発見に関しては、私が非常勤講師をしていた時期5と今には大きな違いがある。即ち上掲のエントリでも触れた生成AIの勃興である。
いつも学期の初めには、コピペについて、引用元を明示しない複製として著作権法上の問題があるし、また上掲のようにバレるので、やるなという説明をしていた。無論、コピペしているばかりでは自分の身に付かないので、科目の履修の意味も無いという事も説明した。しかし、このうち前者の説明については、生成AIが普遍的に利用できるツールとなった今は、少し説明を変えないといけないのだろう。生成AIと著作権の話題は、社会全体としてまだ答えが無い複雑な問題である。バレる件については、上掲の理由は生成AIによるソースコードにも含まれうると思われ、その点で件の眼力により引っ掛ける事は出来るだろう。ただ、明確なコピペ元を特定するのは不可能になる。
当時受け持っていた科目においては、毎週の宿題だけではなく、学期末の試験や最終制作との組み合わせで成績評定していた。そのような複合的な評定基準を取る、即ち授業内容を学生が自分のものにできているかの評価を宿題だけに依存する必要がないと思えば、コピペを特定出来なくても評定はできる。また、少しやさぐれた視点では、コピペばかりで授業内容が身に付かなかった所で困るのはその学生本人でしかないのだから、勝手にすればという気持ちにもなる。大学ともなれば義務教育でもあるまいし、それで追々困った所で自己責任であろうと。
そもそもコピペ是非
とはいえ、やはり授業をやる側としては学生にはちゃんと身に付けてほしいと思う。上述のようにやさぐれてみつつも、身に付いていない学生ばかり本当に送り出してはカリキュラムの意義も無い。ただ、こう思った時に、今日プログラミングを学ぶ学生が身に付けるべきものは何で、それを身に付けるためには自分で手を動かさなければ駄目であるという事は、改めてきちんと理論武装していないといけないだろう。何せ入門レベルのプログラミング課題など生成AIが苦もなく片付けてしまえるのである。自分の手でプログラミングする事の意義が学生にとって分かりづらくなっているだろうと思う。
とはいえ、一概にコピペが駄目かというのは、入門を脱したプログラマの視点からは疑問符が付くかもしれない。何故なら我々、サンプルコードがあったらとりあえずコピペして動かすくらいの事は普通にしているだろう。もしくは、何かエラーが出た時にとりあえずエラーメッセージでググって、Stack Overflow6に投稿された解決策を試してみる、などした事が全くない人が居ようか。少なくとも私はどちらもした事がある。それこそ上掲の生成AIによるソースコード生成も、以前のエントリでも書いた通り、既にプログラマを助ける便利なツールとしての立ち位置は確立している訳であって。
その点では、上掲の著作権等の問題は別に考慮する必要はあるが、実践的プログラミングにおいてはコピペそのものが必ずしも悪であるとは言えない。ただ、それは勿論、自分のプログラムに必要なものが何か分かっていて、その必要なものをコピペしてきているという事も分かってやっているからである。逆に言えば、それを分からないで丸写し的に既存プログラムを持ってくるのは悪である。それは初学者にとっては何の身にもならないし、実践的プログラミングにおいても、その辺に転がっているコードを中身も分からず思考停止的に写してくるなど問題外である。
要件を噛み砕く能力
この「必要なものが何か分かっていて、その必要なものをコピペしてきているという事も分かってやっている」ようになるために必要なのは、言い換えればそのプログラムに対する要件を把握し、かつそれを細分化出来る事であろうと思う。
ここでいう細分化には例えば、このようなライブラリを使うとか、ここでこのようなアルゴリズムを使うとか、そういった大まかな切り分けが考えられる。もしくは、アルゴリズム実装のためにこのような条件でこの類の制御構文をここで使うとか、必要な変数はこれとこれであるとか、そういった細粒度の分解もある。フローチャートを書く、と言っても良いかもしれない。これはある意味、それが出来れば後はそこに利用するプログラミング言語の文法を当てはめれば良い、という段階である。私が、手続き型の考え方を持つプログラミング言語であれば知らないものでも少し勉強すれば書けると思っているのも、思えばこの点を押さえているからである。
もう少し深い所まで言及するなら、先に制御構文という語を示したのと重複する部分でもあるが、この細分化の過程において構造化プログラミングの考え方を理解している事は必要である。全くの初心者にフローチャートを書かせると、制御構造など存在しない、実際にコーディングするとしたらgoto文だらけになるであろう7フローチャートが出てきたりする。また、細分化の過程の中で、関数ないし類似する機能も押さえておく必要があろう。欲を言えば押さえたいポイントは他にも多いが、初心者という観点からは、まずはこの辺りだろうと思う。これくらい押さえておけば、既にあるプログラムを理解する事、また、そこから自分のプログラムに必要な所を組み込む事の下地としての最低限にはなると考える。
それは、上記の通り、また以前のエントリに書いた事にも通じる所として、生成AI勃興の今においてもプログラマに求められる能力であると考えている。逆に、ただ単に言われた通りのフローをコーディングするだけの仕事は、淘汰される方向にあると思う。
センスは実践で磨かれる
ではその能力をどのように身に付けるのか、といえば、結局は手ずから様々なプログラムを作ってみる経験が必要なのだと思う。今日日、前時代的な方法論ではないかという誹りを受けるのかもしれないが、私にはこれより良いものが思い当たらない。
先の「gotoだらけフローチャート」の事を例に挙げれば、そのようなフローチャートでは実際にコーディングする際に手詰まりになる事、またそこからフィードバックして手続きを構造化する事、の実体験が必要だろう。私の講師としての感覚において、一般的なプログラミング言語の制御構文で実現できるフローについて事前に説明していても、それだけで構造化されたフローチャートを描ける初学者は稀である。しかしそれでも、実際に手を動かしながら出来る出来ないと繰り返し考えていると、次第に構造化プログラミングの考え方が頭に馴染んでくる。
最終的には生成AIに代替されうる事であっても、習熟過程では自分で手を動かすべし、というある種の矛盾を孕む不思議な構図ではある。
余談① ー 構造化も生成AIでやってくれるが
構造化プログラミングについて述べたが、生成AIが出力するソースコードも、今時の高級言語を使う以上はその時点でそれなりに構造化されている。要件の処理フローへの落とし込み・構造化も実務的には生成AIに一定程度任せてしまえる。それでも尚、人としてのプログラマが構造化プログラミングを理解している事は必要である。さもなくば、生成AI出力のプログラムの構造を理解・把握する事は出来ないだろう。この分野における生成AIの利用において、それは必要な事である。
余談② ー そもそも要件定義の能力
プログラミングというよりもその上位工程にあたる事だが、要件の細分化以前に、大元の要件を明確化する事が当然必要である。これも、生成AIの存在の傍ら、人の役割であり続けるものだと考える。生成AIがコーディング部分の負担を減らしていく事は確かだろうから、これらの役割は一体化していく方向にあるのだと思う。
プログラムを書く事それ自体を仕事にした経験はないが、野良プログラマとして、自分が必要なプログラムの要件を自分で考えて、それを自分でプログラムを書く所までやる、という事をしている。そのため実は、要件定義とコーディングが分業されるという事のイメージが正直付かない。かの有名な「顧客が本当に必要だったもの」の絵は知っているが。