😽

プログラミング学習においての写経の必要性について

2024/09/05に公開

これは YouTube Live で写経の必要性についてディスカッションするために、自分が用意した資料。

急いで書いたので色々雑。

https://www.youtube.com/live/jrM9fZQIgts

議論が終わったら追記する、かも。

争点

プログラミングの写経に意味があるのか。ないのか。

あるとしたら、その意味は。

ないとしたら、なぜ無意味なのか。

また、少し違った視点として、とくに学校教育の現場で、モチベーションが低い対象を前提として、写経を行わせる意味などもあるかもしれない。

語らない点

  • 個別の言語ごとの写経の向き不向き
  • 特定ツールの良し悪し
  • 個々のライブラリでは云々
  • 一般化できなさそうな N=1 事例

プログラミングの写経の定義

(同意できそうなところ)

完全に思考を停止した状態で、意味を理解せずに上からタイプする作業を写経と呼んではいない。なので、仏教的な意味においての写経・読経や、ヨーロッパの修道院で行われた聖書の写本的な意味合いからは(完全に無関係ではないが)あまり関係がないものとしたい。

写経(しゃきょう)とは、仏教において経典を書写すること、または書写された経典のことを指す。
写経は、印刷技術が発展していなかった時代には仏法を広めるためにされていた。また、複数の僧侶が修行・講義・研究するために写経をすることは必要なことであった。その後 [いつ?]、写経することに功徳があると言われるようになった。

https://ja.wikipedia.org/wiki/写経

本来の写経も思考を停止してたら意味ない云々みたいな言いたいことがある人がいるかもしれないが、今回はそこは争点ではない。念の為。

mizchi の写経に対する持論

まず前提として、個々人の脳の発達が違うんだから人それぞれとしか言えない。個々人の適性と、学習段階の2つの変数がある。そして、写経は常に万人に対して必要なものだとは思っていない。

そもそもの学習ポリシーとして、経験の集積から理論を演繹するのが得意な人、あるいは一貫した理論からその実践を繰り返すことで理論の精度を高めるタイプの人、またはその中間がいると思っている。

自分が写経の効果として認識しているのは、コードを手元のエディタに書き写す過程で、次の体験が得られるからと思っている。

  • 意味のあるキーワードを入力した際に、シンタックスハイライトがつく
  • 何を書いた時点で、エディタの補完がどのように効いていくのかが判明する
  • 何を書いたらエラー文がでて、どこまで書き終えたらそれが消えるのか
  • キーワードの共起確率の獲得。 export async functionfunction(){} は何が違うのか?
  • 応用的に、書き写す過程で小さく実行可能なブロックを理解したら、その段階で試しに実行してみる

これらの一連の流れを体感することに意味があると思っている。このとき、一文字ずつ、脳に刻み込むようにタイプするべし。

※これは IDE 環境を前提にしているところがあるかもしれない。自分は小さくフィードバックを受けるためにも、静的型付け言語の IDE 環境を使うべきだと思っている派

で、これは経験から演繹する人に対して効果が大きいのではないか、という仮説がある。

自分がたまに聴く misreading chat というポッドキャストで(うろ覚えで申し訳ないのだが)概念の獲得についてディープラーニングの微分になぞらえて「自らの経験の中から差分を認識すること」と説明されていて、腑に落ちたことがある。

https://misreading.chat/

写経の効果が弱まるケース

ただ、これが効きやすいのは学習初期の話で、プログラミング意味論を体系的に獲得した段階では同じことをする必要はないとも思っている。体系ができた時点で、プログラミング写経時に得られる効果は逓減していく。

逆に言うと、正しい概念さえ獲得すれば、プログラミング言語の構文を覚えている必要はない。2つ目以降のプログラミング言語の学習が高速化するのもこの理由。自分は毎日使ってる TypeScript でも switch 文の書き方が実はあやふやなのだが、それで困ったことはない。

これだけ動画メディアが普及した現在だと、写経を通さずに概念獲得を優先できる資料もある。例えば自分は ChatGPT の Transformer を完全に理解できていないが、次の動画で理解した気になれてる。

https://www.youtube.com/watch?v=KlZ-QmPteqM

ただ、的を得たメタファや動画で理解した気になっても、いざ実践すると手が止まることはよくある。この問題は写経や実践によって解決する(はず)。

実際のところ、実践と理論は両輪で、写経の効果は段階と適性で効果が決まる、というのが一般化できる限界だと思う。

理論を優先する他の例

Haskell プログラマと仕事した時、この言語では型シグネチャにモナドとして副作用が記述されるのだから、極論型以外のドキュメントは見る必要がない、と言われた。そして、そのコーディングの過程を見ている限り、確かに Hackage(コードから自動生成されたドキュメント) 以外はほぼ見ている痕跡がなかった。

https://hackage.haskell.org/package/aeson

同様の傾向は、Rust プログラマにも感じられた。 koba789 とペアプロした時、基本的に IDE の型情報と docs.rs しか見ていないように感じた。

YouTubeのvideoIDが不正ですhttps://www.youtube.com/watch?v=Cij3CUJmLXIn

経験上、このように体系立てた理論を獲得した人、またはすぐ獲得できる人には、写経の効果が薄い。この手の人はサンプルを経験して、そこから概念を演繹する必要がない。答えそのものを学習して、その精度が十分なら、脳内のエミュレータで完結する。

自分の意見: 写経はマストではないが、初期のコスパがいい

写経を絶対視するのは、自分が獲得した体系を説明できないから、「見て盗め」と言ってるように感じる。

自分は日本史が得意だったが、学習方法は歴史小説(坂の上の雲)やドラマ(大河ドラマ)を見て、ビジュアルイメージをもった状態で教科書を読み、それを自分なりにノートにまとめ直す(ここがある主の写経)。あとは忘却曲線を管理するのに、通学時間に一問一答をやる、といった感じだった。

自分の推奨する学習方法: REPL で高速に失敗する

せっかく対話的な REPL というインタラクティブ環境があるのだから、それを使えばいい派。

例えば Chrome 上で F12 を押して DevTools を立ち上げて、Console タブで JavaScript を書くだけで、すぐに結果が得られる。

> 1
1
> 1+2
3
> let x = 3;
undefined
> x += 1
4
> function add1(x) { return x + 1 }
undefined
> add1(2)
3

ただし、REPL 環境では構造化したプログラミングを学びづらい。基本的にワンライナーで書ける範囲のものしか学べない。

写経は実行単位が指定されているが、REPL はプログラミングの最小のビルディングブロックについて、高速にフィードバックを得られるので、一番コスパがいいと思っている。自分のケースで言うと、Python の REPL でプログラミングを覚えたと言っても過言ではない。

ただし、REPLを使うには、その「与えられたコードの最小単位で評価できるユニットは何?」という推論を常に必要とする。それを要求されているという自覚が必要。

REPL、というか Jupyter でしかプログラミングしてない人に起きがちな問題らしいのだが、Jupyter で書き散らすのに慣れた人が再利用可能な単位で関数を作ることができない、という相談をされたことがある。たしかにありそうだとは思った。

他、もっとメタい目線

  • コンパイラ目線の写経の無駄
    • 実行セマンティクスの評価戦略とは無関係にトップダウンで書いてるとこ
  • 執筆者目線
    • 行数を圧縮する都合、紙面や抽象化の都合で、まだ宣言してない関数の呼び出しを先に書かざるをえない

Discussion