3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

AIに「答えを言わないで」と頼んでRustを学んだ2週間の日記 ― 生成AI時代に、新しい技術をちゃんと身につけるためのメモ

3
Posted at

Sunset Study by the Lake.png

2週間前の日曜日から、Rust の勉強を始めました。

仕事では PHP と Python と TypeScript が中心で、Rust はずっと「いつかやる」リストに入っていたものです。今回、重い腰を上げたのには理由があります。

最近、新しいライブラリやフレームワークを触るとき、AI に聞けばだいたい動くコードがすぐ出てきます。それで仕事は回る。でも、1か月後に同じことをもう一度やろうとすると、何ひとつ覚えていない。そういうことが、ここ1年でずいぶん増えた気がしていました。

AI のおかげで「できる」ことは増えたのに、「分かる」ことは増えていないのではないか。

それを確かめたくて、ひとつルールを決めて Rust を学んでみることにしました。AI には、答えを言わせない。 今日は、その2週間の日記を、ほぼそのまま載せます。日記なので、ここから先は少し口調がくだけます。


10月11日(日) 1日目:ルールを決める

ルールは3つにした。

  1. AI に答えを聞く前に、自分の仮説を必ず1行書く。 合っていなくてもいい
  2. AI には「答え」ではなく「ヒント」を頼む。 「直し方を教えて」ではなく「どこを見ればいい?」と聞く
  3. 1週間後に、何も見ずに覚えていることを書き出す

AI の側にも、こういう使い方のための機能がそろってきている。ChatGPT には「学習モード」、Gemini には「ガイド付き学習」、Claude にも学習モードがある。Claude Code には「Learning」という出力スタイルがあって、これをオンにすると、Claude が全部を書かずに、大事な部分に TODO(human) という印を残して、そこを人間に書かせてくれる。

今回は Claude Code の Learning スタイルを使うことにした。

教材は公式の「The Rust Programming Language」(通称 The Book)。昔からの定番で、無料で読める。

夜、第1章と第2章の数当てゲームまで。ここはまだ平和。

10月12日(月) 2日目:最初の壁

さっそく所有権でつまずいた。

let s = String::from("hello");
let t = s;
println!("{}", s);

コンパイルすると error[E0382]: borrow of moved value: s と怒られる。

いつもなら、エラーをそのまま AI に貼って「直して」と言うところ。でも、ルール1があるので、まず自分の仮説を書いた。

仮説:let t = s; で中身がコピーされずに t に移ったので、s はもう空っぽ扱いになっている?

それから Claude に「この仮説は方向として合ってる? 答えは言わないで、合ってるかどうかと、次に読むべき場所だけ教えて」と聞いた。

返ってきたのは「方向は合っています。The Book の 4.1 節の『Move』と『Clone』の部分を読んでみてください。なぜ整数ではこのエラーが起きないのかも考えてみると、理解が深まります」という返事だった。

整数では起きない。言われてみればそうだ。そこから Copy トレイトの話にたどり着くまで、40分かかった。AI に直してもらえば10秒で終わる話だ。

でも、40分かけてたどり着いた「整数はスタックにあって、コピーが安いから Copy で、String はヒープを指しているから所有権ごと移る」という理解は、たぶん忘れない気がする。

10月14日(水) 4日目:イライラする

正直、今日はかなりイライラした。

借用のルール(可変参照は同時に1つだけ)で詰まって、仮説を3回書いて3回とも外れた。Claude のヒントも、今日はなんだか遠回りに感じる。「もういいから答えを言ってくれ」と、何度か打ちかけた。

途中で、心理学者のロバート・ビョークの「望ましい困難(desirable difficulties)」という言葉を思い出した。学習中に適度な困難があるほうが、そのときは遅く感じても、あとで記憶に残りやすい、という考え方だ。逆に、すらすら進む学習は、そのときは「分かった」気がしても、定着しにくい。

イライラしているということは、たぶん今、ちゃんと学んでいるということだ。そう思うことにした。

結局、4回目の仮説で当たった。ループの中で、ベクタへの可変参照を持ったまま、同じベクタを読もうとしていた。分かってしまえば、当たり前のことだった。

10月17日(土) 7日目:1週間テスト

ルール3の日。何も見ずに、この1週間で覚えたことを紙に書き出した。

書けたこと:

  • 所有権の3つのルール
  • ムーブとコピーの違いと、Copy トレイト
  • 不変参照はいくつでも、可変参照は1つだけ
  • Option と match で、null の代わりに「ないかもしれない」を表す

書けなかったこと:

  • ライフタイム注釈の書き方(読んだはずなのに、何も出てこなかった)
  • String と &str の使い分けの基準(なんとなくしか説明できない)

比べてみて、はっきりした傾向があった。自分で仮説を立てて外した部分は、全部書けている。 書けなかったのは、AI のヒントを読んで「なるほど」と思っただけで、自分の手で一度も間違えていない部分だった。

ここで思い出したのが「テスト効果」の研究だ。Roediger と Karpicke が2006年に発表した実験で、同じ文章を何度も読み返すより、読んだあとに思い出す練習(テスト)をしたほうが、1週間後の記憶がよく残っていた。思い出すという行為そのものが、記憶を強くする。

今日の紙1枚が、まさにそのテストだった。

10月20日(火) 10日目:「ハマりノート」を作る

1週間テストで書けなかったものを、どうやって覚え直すか考えて、小さな道具を作った。

ハマったこと、間違えたことを「質問と答え」のカードにしておいて、忘れかけたころに出題してくれる CLI だ。出題の間隔は、SuperMemo というソフトのために1980年代に考えられた SM-2 というアルゴリズムで決める。思い出せたカードは次の出題までの間隔がどんどん伸びて、忘れていたカードは翌日にもう一度出てくる。

この部分は Rust ではなく、慣れた Python で書いた。勉強のための道具づくりで勉強が止まったら本末転倒なので。

hamari.py
#!/usr/bin/env python3
"""自分の「ハマり」を、間隔反復(SM-2)で復習するための小さな CLI。

  python3 hamari.py add "所有権が移動した変数を使うと?" "E0382。clone するか参照を渡す"
  python3 hamari.py review      # 今日が期限のカードだけ出題する
"""
import json
import sys
from datetime import date, timedelta
from pathlib import Path

DECK = Path.home() / ".hamari.json"


def load():
    return json.loads(DECK.read_text(encoding="utf-8")) if DECK.exists() else []


def save(cards):
    DECK.write_text(json.dumps(cards, ensure_ascii=False, indent=2), encoding="utf-8")


def schedule(card, q, today):
    """SM-2:q は 0〜5 の自己評価。3 未満なら最初からやり直し。"""
    if q < 3:
        card["reps"], card["interval"] = 0, 1
    else:
        card["reps"] += 1
        if card["reps"] == 1:
            card["interval"] = 1
        elif card["reps"] == 2:
            card["interval"] = 6
        else:
            card["interval"] = round(card["interval"] * card["ef"])
    card["ef"] = max(1.3, card["ef"] + 0.1 - (5 - q) * (0.08 + (5 - q) * 0.02))
    card["due"] = (today + timedelta(days=card["interval"])).isoformat()
    return card


def add(question, answer):
    cards = load()
    cards.append({"q": question, "a": answer, "reps": 0, "interval": 0,
                  "ef": 2.5, "due": date.today().isoformat()})
    save(cards)


def review():
    cards, today = load(), date.today()
    due = [c for c in cards if c["due"] <= today.isoformat()]
    for card in due:
        input(f"\nQ. {card['q']}\n(思い出せたら Enter)")
        print(f"A. {card['a']}")
        q = int(input("自己評価 0〜5(5=即答、3=なんとか、0=まったく): "))
        schedule(card, q, today)
    save(cards)
    print(f"\n{len(due)} 枚を復習しました。残りのカードは {len(cards) - len(due)} 枚です。")


if __name__ == "__main__":
    if sys.argv[1:2] == ["add"] and len(sys.argv) == 4:
        add(sys.argv[2], sys.argv[3])
    elif sys.argv[1:2] == ["review"]:
        review()
    else:
        print(__doc__)

1枚のカードを、毎回の自己評価を変えながら出題させてみると、間隔はこう伸び縮みする。

回 自己評価 次の出題まで 次の出題日
1 4(少し考えて思い出せた) 1日 10月12日
2 5(即答) 6日 10月18日
3 4 16日 11月3日
4 2(忘れていた) 1日 11月4日
5 4 1日 11月5日
6 5 6日 11月11日

忘れたら容赦なく振り出しに戻る。でも、「やさしさ係数」にあたる EF は少し下がるだけで、ゼロからにはならない。人間の記憶も、たぶんこんな感じなんだと思う。

カードの答えは、AI に書かせずに自分で書くことにした。答えを自分の言葉で書く作業が、それだけで1回分の復習になるから。

10月24日(土) 14日目:2週間を振り返る

今日で2週間。The Book は第10章(ジェネリクス、トレイト、ライフタイム)まで進んだ。AI に全部書いてもらっていたら、たぶん倍は進んでいたと思う。

でも、進んだ量の代わりに、手元に残ったものがある。

2025年に MIT のメディアラボが、エッセイを書くときに LLM を使ったグループ、検索エンジンを使ったグループ、何も使わないグループの脳波を比べた研究を公開していた。LLM を使ったグループは脳の各部位のつながりが最も弱く、書き終えた直後でも、自分のエッセイの一節を正確に引用できない人が多かったそうだ。参加者は54人と少なく、査読前の論文なので、結論を大きく受け取りすぎないほうがいい。それでも、自分が感じていた「AI に書いてもらったものは、自分の中に残らない」という感覚には、そこそこ心当たりのある結果だった。

論語に、こういう一節がある。

学びて思わざれば則ち罔し、思いて学ばざれば則ち殆うし
(学ぶだけで自分で考えなければ、ぼんやりして身につかない。考えるだけで学ばなければ、独りよがりで危うい)

2500年前の言葉だけど、生成 AI との付き合い方の説明として、これ以上のものを知らない。AI から答えを受け取るだけなら「学びて思わざる」になる。かといって、AI も本も使わずに自分の頭だけで考えていたら「思いて学ばざる」になる。

今回の2週間でやっていたのは、たぶんその間を歩くことだった。まず自分で考えて、仮説を書く。それから AI に、答えではなく方向だけを聞く。間違えたら、それをカードにして、忘れかけたころにもう一度思い出す。

「習うより慣れよ」という言葉もある。AI がいる今は、この「慣れる」の部分を、つい AI に肩代わりさせてしまう。動くコードはもらえる。でも、手が慣れることはない。慣れるところだけは、遠回りでも自分の手でやるしかないんだと思う。

10月25日(日) 15日目:この記事を書きながら

この記事を書く前に、日記もノートも見ずに、1週間テストでは書けなかったライフタイムの説明を書いてみた。

「参照が、参照先より長く生きないことをコンパイラに保証するための注釈。注釈そのものが寿命を延ばすわけではなく、複数の参照の寿命の関係をコンパイラに伝えるだけ」

ハマりノートでは3回出題されて、そのうち1回は忘れていたカードだ。合っているかどうかを、今度は答えを言ってもらう形で Claude に確かめた。

「おおむね正確です」と返ってきた。

「おおむね」の部分が何なのかは、来週の自分に考えてもらうことにします。カードを1枚、追加しておきました。

3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?