世界を動かす技術を、日本語で。

Rustの学習曲線を緩やかにする

概要

  • Rust学習時によくある失敗を避けるための心構えや具体的なアドバイスを解説
  • 心を開くことコンパイラとの協調 が重要であると強調
  • 小さなステップ で学び、焦らず着実に理解を深めることを推奨
  • 正確さ自分でコードを書く経験 の重要性を説明
  • 既存の知識を活かしつつ、Rust固有の違いを受け入れる柔軟性を持つことを提案

Rust学習でよくある失敗と効率的な学び方

心を開くこととコンパイラとの協調

  • Rust学習 にはこれまでのプログラミング経験とは異なる 新たなメンタルモデル を受け入れる必要があることを認識すること
  • ライフタイム・所有権・トレイトシステム など、多くの新概念を学ぶ必要があることを受容すること
  • 学習速度 は知能や経験よりも 言語への姿勢 が影響することを理解すること
  • 借用チェッカー を「敵」ではなく「共著者」として捉え、 コンパイラの指摘 を素直に受け入れること
  • エラーや警告 は設計上の問題を示唆している場合が多いので、 設計の見直し を積極的に行うこと

Rustらしい書き方を身につける

  • 冗長さ を嫌わず、 型アノテーション による可読性やリファクタリングのしやすさを活かすこと
  • コードが 冗長・醜い と感じたら、 よりシンプルな解決策 を模索すること
  • clippy の全lint(pedantic含む)を有効にし、 指摘事項を徹底的に修正 すること
  • 抵抗は無駄 であり、早くRust流を受け入れるほど学習効率が上がることを認識すること

小さなステップで学ぶ

  • 最初はStringやclone(), unwrapを多用 し、後からリファクタリングすることを恐れないこと
  • ifやmatch などシンプルな構文から始め、慣れてきたら イディオム的な書き方 (.and_then等)に挑戦すること
  • async Rust は最初の1週目は避け、 所有権モデル の理解を優先すること
  • 新しい概念を一度に複数導入しない こと
  • Rust Playground やエディタで 小さなスニペット を書き、 動作確認・失敗体験 を積むこと
    • 例: 所有権の基礎を説明する短いコードを自作・検証すること

正確さと注意深さ

  • Rustでは コードの正確さ が必須であり、 いい加減な書き方 はコンパイルエラーにつながることを認識すること
  • 細部への注意力 が速い学習を促進すること
  • &やmutの付け忘れ を減らすよう習慣づけること
  • 有名なRustストリーマー(例: Tsoding) のコーディングを参考に、 細部への配慮 を学ぶこと

ショートカットや自動化への依存を避ける

  • ツールや自動補完 に頼りすぎず、 自分の手でコードを書く経験 を重視すること
  • 自分で書いたコードを説明できるか・設計意図を理解しているか を常に確認すること
  • 速く学ぼうと焦らず、地道な努力 を続けること

実践重視の学習姿勢

  • 他人の成功談を読むだけでなく、自分で大量のコードを書く こと
  • 成果物をオープンソース化 し、完璧でなくても公開すること
  • AIやLLMの自動補完をオフ にし、 自力でコードをタイプすること で理解を深めること
  • 標準ライブラリのドキュメントを読む習慣 をつけること

プログラミングの筋肉記憶を鍛える

  • 手書きでコードを書くことでミスを経験し、エラー出力の理解と直感を養う こと
  • コード補完に頼らず、Rustらしい書き方の感覚を身につけること

出力予測と問題解決力の強化

  • 「このコードはコンパイルできるか?」と予測しながら書く練習 をすること
  • 問題解決はまず自分で考え、解決できない場合のみ他人の解答を参考にすること
  • ripgrep等の高品質なRustコードを読む ことで理解を深めること
  • 苦手分野や避けているトピック を意識的に練習し、 弱点克服 に努めること

コードの破壊的テストと自作ライブラリの推奨

  • 書いたコードをあえて壊し、コンパイラの反応を観察・説明 できるようにすること
  • 学習中は他人のCrateに頼らず、自作実装を優先 すること
    • 例外: serde, anyhow等の主要ライブラリのみ活用すること

直感力の構築とビジュアル化

  • ライフタイムや所有権などの難解な概念は図で可視化 し、自己説明や他者説明に活用すること
  • excalidraw等のツール で手軽にスケッチし、理解を深めること

既存の知識を活かしつつRustの違いを受け入れる

  • Rustは馴染みのある言語の常識が通用しない部分が多い ことを受け入れること
  • 他言語との概念マッピング を活用し、理解の足掛かりとすること
    • 例:「traitはinterfaceに似ている」「structはクラスに近い(継承なし)」等
  • Rosetta Code等のリソース で他言語との比較学習を行うこと
  • 得意な言語のコードをRustに移植 し、既存知識を活かしながらRustを学ぶこと
  • 他言語のイディオムをRustで再現し、その違いを体験的に理解 すること

このようなアプローチを実践することで、 Rust学習の効率向上・挫折防止本質的な理解 につながる提案。

Hackerたちの意見

デイクストラの「プログラミングの規律」を読んでるみたいだね。あの道徳劇的なアプローチは当時必要だったんだよ、だって誰もこのことをどう考えればいいか分からなかったから。Rustの所有権についての説明は、ほとんどが長すぎるんだよね。見てみて [1]。基本的な概念はほとんどそこにあるけど、例の下に隠れてるんだ。 - Rustの各データオブジェクトには、正確に1人のオーナーがいる。 - 所有権は、1オーナールールを守る方法で移転できる。 - 複数の所有権が必要な場合、実際のオーナーは参照カウントされたセルでなければならない。そのセルはクローン(複製)できる。 - オーナーがいなくなると、そのオーナーが持っていたものも消える。 - 参照を使ってデータオブジェクトへのアクセスを借りることができる。 - 所有と参照の間には大きな違いがある。 - 参照は渡したり保存したりできるが、オブジェクトより長生きすることはできない。(それは「ダングリングポインタ」エラーになる)。 - これは借用チェッカーによってコンパイル時に厳格に強制される。これがモデルを説明しているんだ。それが理解できれば、すべての詳細はそのルールに結びつけられるよ。

概念のセットを、理解している人にとって正しくて完全に感じられるように要約するのは、理解していない人に説明するよりずっと簡単な作業だよね。もしこれを、共有呼び出しの言語しか使ったことがない人の前に置いたら、すぐに理解できると思う?ちょっと疑わしいな。

そして、Rustを知らない誰かがこのきれいで素敵な要約を読んでも、Rustについて何も知らないままだろうね。(「この言語のコンパイラには何か黒魔法があるに違いない」以外は。)

この説明は、所有権や借用についての定義がなく、金融資産管理のアナロジーに根ざしているように見えるので、私の頭には何も意味のあることを示していない。私はRustに詳しくないから、正直わからないけど、言葉の使い方が概念の習得の難しさに影響しているのかなと思う。アナロジーはしばしば両刃の剣だし、もっとストレートな記憶に関連した語彙を使う方が、別の視点からの提示として役立つかもしれないね。

一番大事な教訓はこれだと思う:所有権は簡単、借用も簡単。でも、言語を学ぶのが超難しいのは、関数がシグネチャを持たなきゃいけなくて、それが一緒になって参照がオブジェクトより長生きしないことを証明するからなんだ。また、参照されたオブジェクトは本当に必要な場合を除いて型に保存しない方がいい。そうしないと証明がすごく複雑になっちゃう。

それは所有権を説明しているんじゃなくて、動機付けているだけだね。それはそれでいいんだけど、(...) -> &'a [&'b str]みたいな関数シグネチャを読むのが難しいし、そういう関数を呼び出すコードのコンパイラエラーを理解して修正するのが大変なんだよね。

それじゃモデルの説明になってないよ。排他的/共有(または可変/不変)の借用の違いを完全に無視してるから。Rustはこういった借用を許可するためにたくさんの選択をしていて、それはこの簡単な説明や直感、常識からは導き出せないものだよ。例えば、エイリアス禁止のルールは直感や常識から来てるんじゃなくて、関数を最適化したいっていう欲求から来てる。借用の最も複雑な側面は省略ルールから生じていて、これが静かに間違ったことをして、うまくいくけど、うまくいかなくなったときにコンパイラーエラーがライフタイムパラメーターの問題を指摘することになる。省略ルールは直感的じゃないし、あなたの説明からは自明に導き出せるものじゃない。プログラマーの生活を少しでも簡単にしようとするために決定されたものなんだ。

もしかしたら俺の学習の限界かもしれないけど、こういう説明を追うのが難しい。カプセル化の説明についても似たような気持ちがあった:情報をあまり詳しく説明せずに隠せるって言われるけど、なんで?誰から?画面で見えるのにどうやって隠すの?ここでも、例えば「誰」がオーナーなのか理解できない。スタックフレームなの?LIFOの性質上、コール先のスタックが先に消えるから、コール先が戻るまで持っていても危険じゃないのに、なんでスタックフレームがオーナーシップをコール先に移したがるの?最適化のため?オブジェクトを早く手放せるように?オーナーはスタックフレーム以外の何かになり得るの?ミュータブル参照は一度しか渡せないのはなんで?もし一つのスレッドだけ使ってるなら、一つの関数が終わるのが保証されてるから、両方にミュータブル参照を渡すのは何の害があるの?実際に複数のスレッドを使ってる時に手を叩いてくれればいいのに。もちろん、これらのことには理由があって、理解するのはそんなに難しくないかもしれない。なんだか、Rustに入ろうとするたびに、こういうことを追いかけてしまって、少し後に諦めちゃうんだ。

不完全な感じがするね。例えば、借り手がいなくなったらどうなるの?

まだRustには手を出してないんだ、主に時間と需要のせいで。でも、ここ数年C++をたくさんやってきたよ。そのバックグラウンドからすると、これらのルールは素晴らしいと思う。ここ数年、C++を使いやすくするためにたくさんの努力がされてきたけど、それでもうまくやるのは難しいよ、スマートポインタを使ってもね。

俺はいつも、物理的な世界にあるオブジェクト、例えば本を使って説明してるんだ。直感的だと思うんだよね。俺は本を持ってる。所有してる。読めるし、余白に書き込むこともできる。ページを破ってもいいし、終わったら壊すこともできる。それは俺のものだ。俺はこの本を、読み取り専用で君や他の人たちに貸すことができる。改変はできない。誰も書き込めない、俺ですらもね。でも、みんなで読める。借りた人は、その本を他の誰かに再帰的に読み取り専用で貸すこともできる。あるいは、俺はこの本を君にだけ、読み書きできる状態で独占的に貸すこともできる。君以外は書き込めないし、君が借りている間は誰も読めない、俺ですらもね。ページを破ってもいいけど、本自体は壊せない。君は他の誰かに再帰的に独占的に読み書きできる状態で共有することもできる。彼らが終わったら、君が終わったら、それはまた俺の手元に戻ってくる。俺はこの本を君に渡すことができる。この場合、君の好きなようにしていいし、壊してもいい。もっと低レベルに考えれば、共有参照のアナロジーでもコンピュータで何が起こるかを説明できる。共有リソースにアクセスする時、何も本当に並行してるわけじゃない。ページを読むのに順番を待たなきゃならない。ハードウェアはキャッシュされたコピーを使ってこれを素早くやるんだ。もしページを破られたくないなら、余白以外は読み取り専用の本を渡せばいいんだ。

Rustは素晴らしいけど、謙虚にさせられる!内蔵のコーチがいるんだ:借用チェッカー!借用チェッカーが俺のことを離してくれなくて、エラーの連続だったから、ついに折れた。コンパイルエラーごとに、スレッドセーフな共有メモリのリングバッファの正しいやり方を教えてもらった。自分は知ってると思ってたけど、全然違った。CやC++には所有権のセマンティクスがないから、コンパイラがコーチしてくれないんだ。みんなRustを学ぶべきだよ。自分自身について何を発見するか分からないからね。

おすすめの学習パスはある?動画で一緒に冒険するのが好きなんだ。

「Rustは素晴らしいけど、謙虚にさせられる!」これは、レジスタやメモリをいじるのを避けるための抽象化と便利さなんだ。みんなそれぞれ自分の好きな計算プラットフォームを楽しむことができるし、特定のやり方を強要する必要はないよ。自分が正しいと思う高レベル言語に夢中になるかもしれないけど、みんながそう思うわけじゃない。自分を発見するのにプログラミング言語は必要ないよ。特定の言語やパラダイムに執着すると、対処すべきことを見失う可能性が高い。道具を正しく使うのではなく、ただ撫でているだけになってしまうんだ。

みんなRustを学ぶべきだ。これがポジティブな雰囲気の投稿に感じられるのは分かるし、誰かの楽しみを台無しにしたくないけど、自分のことを言うと、「みんなが~すべき」って言われると、特にプログラミング言語のことになると、警鐘が鳴るんだよね。

コンパイラーはそうでもないかもしれないけど、静的解析ツールはかなり進んでるよね。開発者がそれを採用するのはまだ夢のような戦いだけど、100%じゃなくてもいいから、少なくともビルドパイプラインではセキュリティツールを気にしないSecDevOpsの人たちが押し進めてくれないと、デジタルの埃をかぶるだけだよ。

借用チェッカーがマジでうるさくて、エラーが次々出てきたから、もう諦めたよ。奴にボンデージ駆動開発を教わることにした。

Rustに慣れるまでに何度か試行錯誤があったよ—その所有権モデル、ライフタイム、そしてenumやパターンマッチングの広範な使用は、最初は本当に難しかった。最初の試みでは、すぐに圧倒されてしまった。2回目は、あまりにも教条的になってしまって、最初の章から一行ずつ本を読んで、結局我慢できなくなった。でもその頃には、Rustがプログラミングやソフトウェアデザインをより深く学ぶ手助けをしてくれることを理解していた。3回目の挑戦で、やっと成功を収めた;前回の経験から得た基本的な理解を使って、小さなプログラムやスクリプトを書き直し始めた。必要に応じてギャップを埋めていった—イディオマティックなエラーハンドリングを学び、データを表現するために型を使い、パターンマッチングを活用するなどの技術を取り入れた。これらの試練を経て、Rustを学ぶことがプログラミングキャリアの中で最高の決断の一つだったと言えるよ。型、構造体、enumを事前に宣言してから、不変データやパターンマッチングを使って関数を書くというアプローチは、他の言語でコーディングする時でも適用するようになった。

俺も似たような経験があった。3回目の学習の時に、全てがうまくいって、いくつかのプログラムを書くのが効果的になったんだ。プログラマーとしての長いキャリアがあるにも関わらずね。どうやら、繰り返しが必要なこともあるみたい。「Dagger」っていうJVM用の依存性注入フレームワークも、理解するのに3回の「学習試み」が必要だった。ちょっと自分のことを言ってるかもしれないけど、何か少し複雑なことを学ぶことについて。

あなたの経験は、C++の開発者が初めてRustに触れたときに「借りるチェックと戦う」っていう観察と一致してるね。C++のイディオムをRustで使うとそうなるんだ。その後、Rustのイディオムを学び始めて、それをC++に持ち帰ると、借りるチェックがなくてもより堅牢なコードを書くことができるようになる。

ちょっと気になるんだけど、Rustの前にどれくらい他のプログラミング言語に慣れてたの?

たとえば、すでに文字列なのに to_string() を呼び出さなきゃいけないのはなんで?こんな直感に反する質問の答えを探さなきゃいけないから、Rustを真剣に受け止めるのが難しいんだよね。

C++はめちゃくちゃ複雑な言語だよね。すでに整数なのに、何かをintにキャストしなきゃいけないこともあるし。/s なんで人々が異なるテキスト表現の間で変換が必要だってことを受け入れるのがそんなに難しいのか理解できない。

言語が「文字列」型のユニークな概念を持っていないからって、真剣に受け止めなくていいわけじゃないよ。

文字列は時間オブジェクトみたいなもので、大抵の人や言語は、どう動くかのエッジケースをスキップした簡略版しか扱わない。残念ながら、ほとんどの言語からRustに移行するのは、この過渡期を急いで進めなきゃいけないんだ。

質問の言い回しがちょっと変だけど、面白いね。一つは文字列スライス(char*みたいなもので)、もう一つはStringか&Stringで、オブジェクトに近い感じ。

&strとStringが別物だっていうのが直感に反する理由がよくわからないな。C++でstd::stringがconst char*と違うのも直感に反すると思う?それとも&[u8]とVecはどう?

Pythonコミュニティは、プログラマーが複数の種類の文字列を知っておく必要があるってことを痛感したよね。個人的にはto_ownedを使ってる。私のコードを見てる人たちはRustを書かないから、ちょっとでも理解しやすくなるかなって思ってる。

逆の側では、この質問がされてないところに、こんなことがあるよ > "1" + 2 3 みたいな。そんな言語で重要なことをやってるなんて、完全に狂ってる。

Rustは新しいユーザーにとっていくつかの大きなハードルがある:- 他の言語とは非常に異なる。これは意図的だけど、障害にもなっている。- 非常に複雑な言語で、すごく簡潔な構文があって、まるで人が肘で打っているように見える。たった一文字で意味が完全に変わることもあるし、しかもこの構文が深くネストされているのが厄介。- 多くの機能は、それらの背後にある理論を深く理解しないと理解しづらい。これが複雑さを増している。型システムや借用メカニズムはそのいい例だね。型システムオタクでない限り、ほとんどの人にとってはただの意味不明な言葉だと思う。これも、コンピュータサイエンスの修士号を持っていない人には非常に不適切な言語にしている。最近のプログラマーのほとんどはそうだし。- よく使われるマクロがあって、さらに複雑さを増している。マクロの定義を知らないと、何が起こっているのか理解するのが難しくなる。マクロを持つすべての言語は、ある程度これに悩まされると思う。最近はLLMがここで大いに助けてくれると思う。私がRustを理解しようとしたときは、まだその選択肢がなかった。いつか再挑戦するかもしれないけど、今は優先事項ではない。でも、LLMのおかげで新しいことに挑戦するハードルは確実に下がったね。ユーザーのような言語の価値は確かに感じるけど、私が使っている言語(Kotlin、Python、TypeScriptなど)に対して抱えている問題を解決するわけではない。私は人生の中でほとんどの人気のある言語を使ったことがあるけど、Rustは学ぶのが特に難しいという点でユニークだね。

すごく使われているマクロがあって、いろんなことを難しくしてるんだよね。これがRustを学ぶときに俺を困らせた。使ったリソースが悪かったのか、マクロを早い段階で説明なしに紹介してきたんだ。

他の言語とは全然違う。それは意図的だけど、同時に障害でもある。人々が一般的に使っている多くの言語とはかなり異なるけど、大きな特徴や構文はどこかから来ている。例えば、> 型システムや借りるメカニズムは良い例だね。もしあなたが型システムオタクでなければ、それは平均的なPythonやJavaScriptユーザーにはただの難解な言葉に過ぎない。まあ、そうだけど、彼らは一般的に型が嫌いだからね。もしそれだけしかやったことがなければ、同じ問題を持つ同じ空間の別の言語を学ばない限り、あまり知識を引き出せないよ。

Rustの問題は学習曲線じゃなくて、構文の絶対的な醜さだよ。PerlとC++のテンプレートメタプログラミングが子供を作ったみたい。もう我慢できない。Pythonが一番好きで、Cはシンプルさの中の優雅さ、Goはまあまあ許せるかな。

Nimを見たことある?気に入るかもしれないよ。

Cはシンプルだけど、優雅とは言えないよね。名前空間がないことが思い浮かぶし、静的型付け言語なのに型システムがほとんど強制されてない(すべての型を宣言しなきゃいけないけど、時々すべてがintや*voidに落ち着く感じがする)。ビルドシステムも、プログラムをコンパイルするために別の言語を生成するために別の言語を学ばなきゃいけない(どちらも私の目にはシンプルでも優雅でもない)。null終端文字列も、現代のプラットフォームで文字列ごとに7バイト節約するために、Cはプログラミング界の危険で優雅でない構造を使ってる。エラーハンドリングも全然優雅じゃなくて、インバンドエラー値を返すか、グローバル変数を設定するか、両方か、ただ静かに失敗するかのどれか。標準ライブラリも危険な関数が散らばってるし、言語定義が未定義の動作に依存してるから、プログラムの重要なチェックがコンパイラーに無視されるか、プログラムがハードドライブを破壊するかを知るために700ページの高価な文書を読み返さなきゃいけない。Cはシンプルな構文を持ってるけど、絶対に優雅ではないよ。

趣味で言うと、特に構文に関しては好みを議論するのは無意味だよね。個人的にはRustの構文は気にならないけど、Goの構文はちょっと…変に感じる。特に型シグネチャは、句読点が嫌いな人が書いた長文みたいに見える。Cの型シグネチャは俺にはごちゃごちゃしたものに見える。これみたいなやつ https://www.ericgiguere.com/articles/reading-c-declarations.... は、俺にとってはデザインミスだと思う。そしてPythonは…「ああ、もう諦めた、Anyシグネチャを付けちゃえ」って感じになる。そういうのが好きな人もいるけど!みんなに合うわけじゃないよね。

あんまり見かけないアプローチなんだけど、最初に言語の一部だけを学ぶことに集中するのがいいと思う。例えば、俺のRustの本では、ライフタイムの教え方を省いてるんだ。ライフタイムを使わなくても、ちゃんと動くプログラムをいくつか作るのに必要ないからね。マクロも同じで(ただ、シグネチャが不透明だから初心者には難しいかも)。でも、copy()やclone()に頼るのは違うと思う。借用について最初から学ぶ方がいいよ、だってそれが言語の基本的な部分だから。

「安全な」RustはC++に比べて一般的にはシンプルな言語だよ。借用チェッカーのルールはクリーンで一貫してる。ただ、書くのはこれまでの人気のあるシステム言語に比べてシンプルでも直感的でもない。データ構造に明確な依存関係がある場合—例えば非循環グラフみたいな—は問題ないけど、自己参照データ構造をパフォーマンス良く書くのはC++やC、Zigに比べて全然簡単じゃない。一方で、「非安全な」Rustは全然シンプルじゃないけど、それがないと多くのプログラムが書けない。Cに似てるし、場合によってはそれ以上に厄介かも。ルールを破るのは簡単だし(エイリアスとかね)。生ポインタの操作はCやC++、Zig、Goに比べてエルゴノミクスが悪い。でも生ポインタはCSで最も重要な概念の一つなんだ。この部分は学ぶ上で非常に重要だから、目をつぶるわけにはいかない。Rustのオープンな問題についても話してないし、例えば:thread_local(まだ疑問)、カスタムアロケータ(まだナイトリー)、Polonius(ナイトリー、成功を願う)、パニック処理(カーネルレベルのコードでは受け入れられない)、そして「pin」は非同期や自己参照の問題に対するワークアラウンド(ハック)みたいに見える—多くの学習者がこれに苦労してる。Rustはいい言語だよ、間違いなく。でも、一時的なステップに感じる。学習曲線は解決しようとしているタスクの種類によって大きく変わる。一部のことはすごく簡単でストレートだけど、他のことはとても難しくて、最終的な解決策はC++やC、Zigに比べてシンプルでも直感的でも理解しやすくもない。MojoやCarbon(成功を願う)、そして多分Zig(まだ確信はない)みたいな言語はRustや他の言語から学んでる。どれかが今後数十年の間に次の主要な汎用システム言語になるかもしれないし、もっと学びやすい曲線になるかもね。

「生ポインタはCSで最も重要な概念の一つ」ってのはちょっと言い過ぎだな。最後に使ったのいつだっけ?

抵抗するのはやめろ。それが最も重要な教訓だ > Rustを学ぶには...を受け入れろ > 傲慢さを家に置いてきて > 敗北を宣言しろ > 抵抗は無駄だ。学ぶのを拒否すればするほど、苦しむ時間が長くなる > 自分が知っていると思っていたことは忘れろ... 今、オーウェルのテレスクリーンOSがRustで書かれていたことがやっと腑に落ちた。

でも、これは本当だよ。Rustを学ぶ時の俺の最大の間違いは、オブジェクト指向のパラダイムを無理やり押し付けようとしたことだ。それは…うまくいかなかった。もう「くそ、君が望むようにやるだけだ」と思った瞬間から、物事がスムーズに進んだ。

システムプログラマーとして、Rustは比較的学びやすいと感じたんだけど、問題は非システムプログラマーが初めてシステム言語を学ぼうとして「いや、それは危険だよ。いや、それは意味がない」と明示的に言われることかもしれない。もしフロントエンド開発者に突然Cを書かせたら、メモリリークを作ったり、未定義の動作を引き起こしたり、ゴミを指すポインタを作ったり、配列の終わりを超えたりするだろう。でも、彼らはプログラムがコンパイルしてなんとなく動くから「うまくいってる」と感じるかもしれない。もしCやC++で中級者やマスターのレベルに達していれば、Rustは学びやすいと思う(俺はそうだった)。概念が暗黙的ではなく明示的にされているだけなんだ(所有権、ライフタイム、トレイトと仮想テーブルの代わりに)。

これは良い洞察だと思うし、「あまり厳しくない言語から非常に厳しい言語に移行する」という点まで広げられると思う。1.0の頃に独学でRustを学んだ者として、高校レベルのJava 6を半年やった後、所有権システムのような概念で人々が報告する問題には一度も直面したことがない。しかもRust 1.0は現代のRustよりもずっと制限が厳しかったし、「The Book」の理解しにくいバージョンで学んでいたのにね。これは、俺やこのことについて話した他の初期のRust学習者が、プログラミング言語がどうあるべきかについての先入観がほとんどなかったからだと思う。だから、Rustによる制限は他のプログラミング言語と同じくらい「恣意的」で、何かを達成する「より良い」方法があるとは感じなかった。一般的に、JSやPythonのような人気のある言語は、使いたいパターンを十分に形作ることを許してくれるから、そこにフィットするんだ。少なくとも俺にとっては、RustやHaskellのような言語で、あまりにも異なる概念でこれを試みると、コードがかなり醜くなる。これがPLが「必要なことをしない」とか「制限を課す」という印象を与えることがあると思う。逆に、これは他の方向にも行くと思うし、ある種の嗜好が発展した結果かもしれない。

低レベルのプログラマーとして、Rustで一番苦労したのは型システムだったな。特にトレイトとトレイトバウンドがね。C++の経験があればもっと簡単に理解できると思うけど、俺が書いてたのはほとんどCで、Rustのいろんなことが全然馴染みがなかったんだよね。