プログラマー脳 ③ コーディング中の混乱 ③ / コードを速読する / 文法を素早く習得する

全然関係ないけど、先日覚えた、storybook の構文の再現から始める

import '../HogeComponent';

export default {
  title: 'fuga/HogeComponent',
  Component: HogeComponent,
  ArgTypes: {
    peko: {
      description: 'あいうえお',
    },
  },
}

const Template = (args, { ArgTypes }) => ({
  components: { HogeComponent },
  setup() {
    return { args };
  },
  template: '<HogeComponent v-bind="args"' />,
});

export const Default = Template.bind({});
Default.peko = 'ペコ';

どんなもんだろう。

確認してみたところ、最終行が違うな。

Default.args = { peko: 'ペコ' };

としてやれば良い。

そりゃあそうじゃ。

Chapter 1 コーディング中の混乱を紐解く

1.2.3 ワーキングメモリとプログラミング

  • ワーキングメモリは、脳のプロセッサ
    • 長期記憶 → HDD、短期記憶 → RAM
  • ワーキングメモリが担うのは、脳内でのコードの実行
    • トレース という
      • 実際の動きをなぞるから、トレースか

1.3 それぞれの認知プロセスが協調的に動作する仕組み

1.3.1 認知プロセスの相互作用の概要

これまで見てきた 3 つの認知プロセスが図解されている。

自分の認識と異なっていたのは、短期記憶の在り方。

今目にしたばかりの情報群から、必要な情報を掬うためにフィルタを掛けた結果が、短期記憶。

変数名などがこれに該当するということなのだから、この図の通りになるだろうに、なぜか自分は、この他にももう少し長い間保持される記憶までこのカテゴリに含まれると勘違いしてしまっていた。

その理由は恐らく、短期記憶がコード中で扱われる例として、toBinaryString といったような関数が例に出されているのが自分の中でしっくり来ていないからだろう。

1.3.2 プログラミング作業に関係する認知プロセス

本章のまとめ

Chapter 2 コードを速読する

本章の内容

  • 脳が新しい情報を認識可能なパーツに分割する仕組みを解明する
    • 知りたい
  • 言葉やコードのような情報を分析する際の、長期記憶と短期記憶の連携の仕方の発見
  • コードを処理する際のアイコニックメモリの役割を検証する
    • new word キタ
  • コードをどのように記憶しているかが、コーディングレベルの(自己)診断のために利用できることの説明

  • コードは書かれるものである以上に理解されるものである

    • その「理解される」、つまりリーディングに焦点をあてているのが本章
      • なお、コードスニペットを速読する練習をすれば、コーディングスキルが改善されるとのこと

本章を読んだ後には、

  • コードを速く読む方法が理解できている
  • コードリーディングのスキルを向上させるためのテクニックを理解できている

2.1 コードの速読法

  • 「プログラムは人間が読むために書かれ、機会が実行するのは、そのついででなければならない」という文が有名
  • 現実には、プログラマは読む練習よりも書く練習ばかりしている、とのこと
    • 自分は以前、読むのが大嫌いだった
    • 今はそうでもないというか、むしろ、学習目的で積極的に読んでいるような気もするけど

Java の 二重配列を覚え、再現した

2.1.1 今、あなたの脳内で何が起きたのでしょうか?

まあ、Java は分からないので、JavaScript に変換してしまったのだけど

2.1.2 再現したコードを見直しましょう

再現したコードは、長期記憶由来の部分と短期記憶由来の部分に分別できるよね、とのこと

確かにそうだ

と言っても、for 文の各条件がセミコロン区切りであることは正しく認識できておらず、カンマ区切りにしてしまっていたのだけど

JS でわざわざ for 文を書く機会が少ない、という言い訳はできるが、こんな基礎的なものをちゃんと覚えていないのも問題ではある

temp 変数を用いた配列の要素のスワップは、42 Tokyo で何度もやったので、長期記憶由来だ

なお、再現にあたってはコメントを書く人もいる、とのこと

自分には、前回読んだ時も今回も、そのような発想はなかったものの、脳内でやっていたこととしては一緒だな

2.1.3 2回目のコード再現の振り返り

これはやらなかった。

「こちらの方が文脈に欠けているから覚えにくい」というオチを覚えていたので。

2.1.4 なぜ馴染みのないコードを読むのは難しいのか?

  • コードを記憶するのが難しいのは、短期記憶の容量が限られているから
    • 7 ± 2, あるいは 2 つから 6 つ
  • 短期記憶が可能な期間は 30 秒ほど

2.2 記憶のサイズ制限を克服する

6 文字以上再現できていたのは、どういうことか、1 つのカタマリとは何なのか、の分析

2.2.1 チャンキングの威力

  • 「チャンク」という言葉を初めて使ったのは、チェスの盤面の記憶の実験を行った研究者
    • オランダの数学者
  • その実験の結果
    • よくある盤面の再現は、達人の方が一般的なプレイヤーよりも優秀
    • めちゃくちゃな盤面の再現は、達人も一般的なプレイヤーも等しくできていなかった
  • よくある盤面の記憶法について
    • 一般的なプレイヤー → 1 コマずつ覚える
    • 達人 → 長期記憶に保持された情報を多用していた
      • 盤面のパターン名と結びつけたり
      • 自分が過去にプレーした盤面と結びつけたり

《演習》

  • 知らない言語の 12 文字よりも、アルファベットの 12 文字の方が覚えやすい
  • 無意味なアルファベット 12 文字よりも、同じ 12 文字の "cat loves cake" の方が覚えやすい

コードでも同様、とのこと。

そして、チャンク化しやすいコードの書き方を教えてくれる、とのこと

2.2.2 熟練プログラマーは初心者よりもコードを上手に記憶できる

熟練のプログラマでも、不慣れなキーワード、構造、ドメインの概念を扱う際には苦労する

2.3 読めるコードよりも見えるコードの方が多い

  • 情報が短期記憶に到達する前に、感覚記憶と呼ばれる場所を通過する
    • 五感がそれぞれ有する記憶領域
      • そんなものが存在するのか。確かに以前読んだけど、認識から抜けていた
      • 僕が弱そうなところだ
    • この感覚記憶が、アイコニックメモリ
    • プログラミングの文脈では、視覚に関して説明するとのこと
      • 安心した
      • と言っても、これも自分は弱いけど
      • 英単語だと、触覚や聴覚での記憶があり、同じ対象をそうした複数の側面から認識するよう心がけていたことで自分は上手くいったのだと思う
      • とは言っても、実際のプログラミングでも、口には出せるじゃんね。僕にとっては、視覚に限定しない方が良さそう。口に出したら触覚でも認識できるし

2.3.1 アイコニックメモリ

  • 本のページを見続けた後で目をつぶると、ページの輪郭が視覚的な記憶として一時的に残る、とのこと
    • 自分は全然残らない。苦手だ
  • アイコニックメモリに格納された情報の全てが短期記憶によって処理されるわけではない
    • ここでまずフィルターが掛かるという話だろうか
  • 「コードをざっと眺める」練習が、コードの最初のイメージをつかむのに役立つ、とのこと
    • まあ、いつかやってみても良いのかもな。例えば、Rails の、同じ種類のファイルをいくつか見る、など
    • 自分が一昨日に storybook の構文を覚えた時に行ったことも、同じではある

2.3.2 何を覚えているのかではなく、どのように覚えたか

初級者は、英単語をそのまま連ねて覚えがち

上級者は、自分で意味ごとにグループして覚える傾向がある

自分は初級者のやり方でやってしまっていた。

試しに上級者のやり方でやってみたところ、そちらの方がずっと覚えられた。

デザインパターンを利用する》

→ 効果が大きいっぽい。 なるほど、確かに、これも一種の長期記憶だからな。

自分で「このコードはあのパターンだな」などとカテゴライズできると強そう

《コメントを書く》

良し悪しはありそうだけど、チャンク化しにくい長々としたコードブロックには、コメントによる区分を与えるのも手かも

《ビーコンを残す》

  • ビーコン
    • コードの内容を理解するのに役立つプログラムの部分
    • 例えば、変数名に root などと使えば、いかにも木構造っぽい
    • 単純なビーコン複合的ビーコン に分けられる

2.3.3 チャンク化の練習

この本では「意図的な練習」という言葉を多用する

意味は、漫然と量をこなすのではなく、特定の分野での上達を目的として集中的に練習する、というもの

自分がやるべきことのように思う

ステップ 1:コードを選ぶ

ステップ 2:2 分間で覚える

     3:再現

     4:どこが再現できてどこが再現できなかったのかを見比べ、分析

本章のまとめ

  • 短期記憶できるチャンク数の限界は小さいので、この容量制限を克服するため、長期記憶と協調する
  • 長期記憶に十分な知識がないと、単純な情報に頼らなければならなくなるので、すぐに短期記憶の容量の限界を迎えてしまう
  • コードを覚えて再現する作業により、自分に定着していない分野を洗い出せる

Chapter 3 プログラミング言語の文法を素早く習得する方法

《本章の内容》

  • プログラミング言語の文法を記憶するための技術を選ぶ
    • おもしろそう
  • 文法を忘れないためにどんなことができるのかを整理する

    • 自分は今のところ、「覚える!」と意識することがまず功を奏している
  • どれだけ長期記憶に保存されているかが、コードをトレースする速度を左右する

  • この章を読めば、以下が得意になる
    • プログラミングの知識を長期記憶に留める
    • うまくチャンク化する
    • コードをうまく読み進める

3.1 文法を覚えるためのテクニック

自分は、英単語の意味を覚える際、「英 → 和」だけでなく「和 → 英」もできるようになることを重視していたな

プログラミングでも、「書けないけど、読めば何となく分かる」という状態を脱却するために、書く練習をするのが重要そう

3.1.1 割り込みがワークフローを混乱させる

  • 「調べれば分かるからそれで良い」という意見の人もいるだろうが、その「調べる」作業により、ワークフローが中断してしまい、コンテキストスイッチの切り替えに苦労する
    • 苅宿さんみたいに、自分宛じゃない情報は後でまとめて見るようにした方が良いかも
      • 自分の性質を考えると、非常に難しそうだけれども…

3.2 フラッシュカードを使って文法を素早く覚える

勧められている方法の例は、次のようなもの。

「基礎的なリスト内包表記」 ↔︎ numbers = [x] * y

なるほど。

と言うか、同じ要素を複数個持つ配列って、こんな風に作れたんだ。

ChatGPT で調べて初めて知った。

他には、Array.new(y, x) という方法も教えてくれた。

第一引数は、配列のサイズで、必須。第二引数はオプショナル。

まあ、でも、[x] * y の方が直感的で良いな。

3.2.1 フラッシュカードを利用するタイミング

次のアプリが勧められている。

  • Cerego
  • Anki
  • Quizlet

ひとまず、Anki を入れてみた。

カードとして、冒頭の storybook のものと、先程の、Ruby での配列の生成方法との 2 つを追加してみた。

3.2.2 フラッシュカードのセットを拡張する

新たなカードを追加する最適なタイミングは、ある概念を検索しようとしたときです。

なるほど。

3.2.3 フラッシュカードのセットについて考える

3.3 物忘れを防ぐには

3.3.1 なぜ我々の記憶は失われてしまうのか?

《階層構造とネットワーク》

  • 人間の記憶は、フォルダ構造ではなく、ネットワーク構造

3.3.2 間隔をあけて繰り返す

フラッシュカードは、覚えたと思ったものでも長い期間で反復し続けるのが大事

3.4 文法を長く記憶に留めるには

  • 記憶を強化するための2つのテクニック

    • 想起練習
    • 推敲
      • 新しい知識を既存の記憶と積極的に結び付ける
  • 思い出そうとすることが重要

    • 完全な答えを知らなくても、頻繁に思い出そうとした記憶は、簡単に見付かるようになる

3.4.1 情報を記憶する 2 つの形態

  • 長期記憶から情報を取り出す際に、2 つのメカニズムが存在
    • 貯蔵強度
      • どれだけ強固に保存されているか
      • 学べば学ぶほど強くなる
    • 検索強度
      • 思い出すのがどれくらい簡単か

貯蔵強度は増加する一方。

しかし、検索強度は低下していく。

思い出そうとすることで、検索強度が上がっていく。

3.4.2 情報をただ見るだけでは不十分

3.4.3 情報を覚えることで記憶が強化される

知らない文法をその都度調べるなら、脳はその文法を覚える必要があるとは認識しない。

結果として、検索強度は低いままになる。

これは悪循環を生み、いつまでも調べ続けることになる。

3.4.3 能動的に考えることで、記憶を強化する

長期間に亘って練習を行う以外にも効果的な方法がある。

それは、学んだばかりの情報について考え、振り返ること。

このプロセスを 精緻化 と呼ぶ。

これは、複雑なプログラミングの概念を学習する際に、特に効果的。

スキーマ

  • 思考とその関係が頭の中で整理されたもののこと
  • なお、脳は、スキーマ化のために事実を歪曲化さえする
  • 自分は、この精緻化が弱いかも。と言うのは、新しい知識を、既知の何かと結び付けて覚えようとはあまりしないから。

ある程度集中的に読み進められて良かった。

でも、もっと時間を確保しないと、来週の木曜までに読み通すのはキツそうだな…。

次回は 4 章 『複雑なコードの読み方』から。