# はじめに
どうも、わたしです。
最近、というかここ数年、タイムラインを眺めていると、「プログラミングを始めました!」「LLMでアプリを作りました!」みたいな投稿を頻繁に目にするようになりました。それ自体はとても素晴らしいことだと思いますし、新しく何かを始めようとしている人を否定するつもりは毛頭ありません。
ただ、その後の様子を眺めていると、どうにも釈然としない気持ちになることが多くあります。
「動きません」「エラーが出ます」「分かりません」「何もしていないのに壊れました」、そういう質問が、携わるコミュニティで、Twitterで、Discordで、GitHubで、毎日のように流れてきます。それ自体は別に良いんです。分からないことを聞くのも大事だと思いますから。
問題は、その質問に何の情報も含まれていないことや、そもそも自分の手元で起きていることを、自分で確認すらしていないことです。
タイトルは少しばかり煽情的かもしれませんが、自分自身も普段から書いては消し、書いては消しを繰り返している身として、向いてないと切り捨ててしまう前に、もう少し言いたいことがあります。そんな話を、つらつらと書き散らしていきたいなと。
# エラーメッセージは目の前にあるのに何故か読まれません
世の中には、エラーが出た瞬間に、画面の前で固まる方々が一定数いらっしゃいます。
固まったまま、5分、10分、酷い時には30分。エラーメッセージは画面の真ん中にずっと表示されているのですが、その本文を読んでいる気配がありません。読んでいたら、その後の口から「分かりません」という言葉が出てくるはずがないからです。
Connection refused, Permission denied, Module not found, Unexpected token.
これらは何かの呪文ではなく、コンピュータがあなたに対して、丁寧に問題を教えてくれている、とてもありがたい案内です。
エラーメッセージを読むというのは、別に難しいことではありません。Connection refused 127.0.0.1:5432と書いてあれば、「ローカルの5432ポート宛接続が拒否された」と読めばいいだけですし、5432はPostgreSQLのデフォルトポートなのでPostgreSQLが起動していないか、接続情報が間違っているか、そのあたりに当たりがつきます。1分もあれば原因に辿り着ける問題に何を無駄な時間を費やしているのでしょう。
「英語が読めません」と言う方もいらっしゃいますが、refusedをリフューズドと読み下せれば、それだけで意味は推測できますし、どうしても分からなければ翻訳ツールに通せば済む話です。あなたが普段スマホで観ている海外動画の字幕、あれだって機械翻訳でしょ?同じです。
そして、信じられないかもしれませんが、エラーメッセージを読まない方々は、何度プログラムを実行しても出続けるエラーに対して、毎回最初から驚きます。「またこのエラーが出ました」と言うのですが、そら当然です。書かれていることに対処しない限り、何回実行しても同じエラーが出ますし、コンピュータは、あなたの祈りとかには反応しません。中身を変えず同一の試行を繰り返した挙句、違う結果を望むのはとても愚かなことです。小学生ですらやりません。
エラーが出るというのは本来ありがたいことです。間違っている箇所を教えてくれるものですから、感謝しながら読んで直せば済みます。逆に、エラーも出ずに動いている、けれど結果が間違っている、という状況の方が、遥かに恐ろしく感じます。エラーは敵ではありません。
# 「こう動くはずなんですけど」って、それあなたの感想ですよね
これも本当によく見かけるパターンで、本当に心底嫌いです。
曰く、「私は、ここはこういう風に動くはずだと思ってるんですけど、動かないんですよ」と。
そうですか。それで、あなたの思いと実際の挙動、どちらが正しいと思います?
答えは決まっています。動いていないのなら、あなたの思い10割10分が間違っています。
ところが、自分の認識を譲らない方が一定数居るようで、「いや、ここはこう動くはずなんですよ」だとか、「でも、こういう風に書いたんですから、こう動くはずじゃないですか」みたいなことを平然と言ってのけます。すごい自信家ですよね、感心します。でも実は違うんです。あなたの認識と、コンピュータの実際の挙動がズレているんです。修正すべきは、コードでも、ライブラリでも、コンピュータでもなく、傲慢なあなた自身です。
思いをベースに議論しても、コンピュータは1nmも動きませんし、コードを動かすのは、そこに書かれている事実です。実際に出力された値、実際に走った行、実際に発生したエラー等々。それらだけが、原因の手がかりであって、あなたの思いは、原因の特定に役立ちません。
デバッグの第一歩は、自分の思いを一旦脇に置くことでしょう。「ここは絶対こう動いているはず」と思い込んでいる箇所こそ、printでも console.log でも dbg! でも構わないので、実際の値を出力して確認してください。殆どの場合、あなたの思い込みは外れています。本当に、本当に、外れています。騙されたと思って私を信じてください。
ちなみに、デバッガを使ったことがない方も、かなりいらっしゃるようですが、VSCodeでもJetBrains系IDEでもブラウザのDevToolsでも、ブレークポイントを置いて、ステップ実行して、変数の中身を覗く、ということができます。これを覚えるだけで、デバッグの効率が劇的に変わります。printデバッグも悪くはないのですが、ちゃんとしたデバッガを使えるようになっておくと、人生の何割かを取り戻せます。暇なら覚えておきましょう。
# 詰まったら考えるより先に手を動かそう
エラーメッセージを読みました。それでも原因が分かりません。さて、どうしましょうか。
ここで多くの方が、画面の前で固まる作業に戻ります。けれど、それでは何も解決しません。考え込んでも、コンピュータは何も教えてくれません。
ここでやるべき事は、手を動かして状況を観測することだけです。
怪しい箇所の値を出力する。リクエストの中身をダンプする。条件分岐の手前で実行を止めて状態を覗く。データベースに直接クエリを投げて状態を確認する、みたいな。動いているはずと思っている部分が、本当に思った通りに動いているか、ひとつずつ確かめていく必要があります。
考えてから手を動かすのではなく、手を動かしながら考えるべきです。これは、おそらくベテランの方も全く同じことをしています。違うのは、観測の精度と、観測する場所を絞り込む速度だけです。経験を積むと最初に怪しいと睨んだ箇所が当たる確率が上がっていく、というだけの話に思えます。
さて、「闇雲に試して動いたら、それで本当に直ったと言えるんですか?」と言われてそうです。良い指摘です。実際、闇雲に値を変えていたら偶然動いた、というケースは、本質的な問題の解決には至っていません。
しかし、観測した結果から「ここの値が想定と違っていた」と特定できれば、それは立派な原因究明です。観測のないトライアンドエラーは博打ですが、観測のあるそれは、ちゃんとしたデバッグであると考えます。
考え込まないでください。手を動かしてください。コードは、あなたの思考の中ではなく、メモリ上で実際に動いています。
# 「LLMに聞いたら違うことを言ってきました」
そんな事を言うくらいなら、はなから私なんかに聞かずとも、永遠に一人寂しくLLMとイチャついてればいいと思うのですが、最近特に増えたのがこのパターンです。
「LLMに聞いたらこう書けばいいって言われたんですけど、動きません」
そうですか?うんうん、すごいでちゅね〜!それで、あなたはその実装を読みました?
LLMが生成したコードは、それなりに動きます。それなりに、です。ライブラリに破壊的な変更があれば動きませんし、APIが廃止されていれば動きません。そもそもLLMの学習データに無かったマイナーなライブラリだと、平気でハルシネーションを起こします。実在しない関数を、自信満々で提案してきたりしやがります。
それを確認もせずにコピペして、挙句、動かなかったら「LLMが嘘をついたんだ!!!!」と憤慨するのは、些か筋違いです。
LLMは便利なツールですが、便利なツールを使うために必要な能力は、依然として人間側に求められています。これは、Stack Overflowが流行った時も、Qiitaが流行った時も、ChatGPTが流行った時も、Clineに全部賭けたときも、Cursorが流行った時も、ずっと変わっていません。
LLMに頼ること自体は何も悪くありませんし、私も普段からLLMにかなりの出力を強要しています。GeminiにもOpusにも毎日お世話になっています。ただ、LLMが出力したコードは必ず自分で読みます。読んで理解して、おかしいところがあれば修正します。これをやらない人間がLLMを使うと、ただのコピペ職人が爆誕します。それも、自分が何をコピペしているかすら分からない、史上最悪のコピペ職人が、です。
ちなみに、LLMに「このコード動きません」と投げて、LLMが返してきた修正をまたコピペして、それでも動かない、というループに陥っている方も散見されます。それを何時間も繰り返した挙句、LLMはダメだと結論付ける。残念ながら、ダメなのはLLMではなく、あなたの頭です。
LLMはあなたの状況を完全には理解していません。あなたが理解した上で、適切に指示を出す必要があります。
以前にも別の記事で書きましたが、LLMがどれだけ優秀になっても、使う人間の側に何もなければ、出力される成果物も同様のものでしょう。
# 自分が何をしたいのか整理して
これも本当によく言われます。やめてくださいね。
「○○がしたいんですけど、どうすればいいです?」
その○○が、抽象的すぎてなんと言うかものすごくふわっとしている。
「Webサイトを作りたいんだけど〜」
どんなサイトを?静的サイトですか、動的サイトですか?認証認可は必要ですか?どんなコンテンツを載せたいですか?利用者は何人を想定していますか?運用のコスト感は?収益化したいですか、趣味ですか?
これらはあなたが答えるべき質問です。わたしが答える質問ではありません。
目的を整理するというのは、プログラミング以前のごく当たり前の力です。これができないと、コードを書く以前に何を書けばいいかすら定まりません。そんなんじゃお話になりません。
これはエンジニアリングの問題ではなく、もっと手前の自分の思考を整理して言語化する国語の問題です。プログラミングは思考を厳密にコンピュータが理解できる形に翻訳する作業ですから、思考が曖昧なままではそもそもコードに翻訳することすらままならないことは自明でしょう。
紙でもメモアプリでもLLMでも構わないので、自分が何をしたいのかを書き出してください。やりたいこと、やるべきではないこと、分かっていること、分からないこと等々。整理されていない要望をぶつけられても、こちらは何も答えようがありません。
そして、もうひとつ。課題文を読めない方も本当に多いです。
例えば、業務でちょっとしたツールを依頼する場面で、「Slackに来たメッセージのうち、特定のキーワードを含むものをスプレッドシートに記録してください」と伝えたとします。これは、「Slackからメッセージを受け取る」、「キーワードでフィルタする」、「スプレッドシートに書き込む」の3つの工程に分解できる、ごく単純な依頼です。
ところが、これが分解できない方は、依頼文を一塊のまま受け取って、最初の一歩で固まります。「何から手を付ければいいんでしょうか」と相談されるのですが、お渡しした依頼文には既に手を付ける順番が書いてあります。一文として読むのではなく、要素ごとに区切って読んでください。それだけで、何をすればいいかが見えてきます。
これはもうプログラミング以前の、国語の問題です。
それすらできないようであれば、小学生のお勉強からやり直すことを推奨します。
# 大きい問題に挑む前に小さい問題に分割して
「○○を作ってください」という課題が出たとします。例えば、社内向けのちょっとしたダッシュボード、みたいな。
ここで、できない方は、いきなり全部を一気に書こうとして、数時間悩んだ末に画面の前で固まる作業に戻ります。「データ取得をどう書いて、それをどう加工して、どうUIに表示して、認証はどうして、エラー処理はどうして…」と、全てを同時に考えようとして、結局1行も書けないのです。
わたしならこう書きます。
var dashboard = new Dashboard();
var data = await dashboard.FetchDataAsync();
dashboard.Render(data);3行、終わり。これでダッシュボードが完成です。
「いや、それじゃ動かないじゃないですか」と思われるかもしれません。その通りです。動きません。Dashboard とかいう存在しない抽象クラスを呼んでいるだけですから、当然です。
しかし、これで全体像は捉えられます。あとは適当にDashboardクラスとFetchDataAsync、Renderの中身をそれぞれ実装するだけです。中身もいきなり全部書こうとせず、同じように存在しないメソッドを呼んでおいて後から埋めていきます。これを繰り返していると、いつの間にか動くものが出来上がっています。
トップダウン設計と呼ばれたりもしますが、名前はどうでも良くて、要するに、自分が一度に考えられる範囲まで、問題を細かく細分化するということです。難しい問題を、難しいまま扱える人は、ごく一部の天才だけであって、私を含む殆どの無能は、問題を1ファイルに1,000行で書ける程度の小ささに分解しないと解けません。
勉強すれば難しい問題も解けるようになると期待されている方もいらっしゃるかもしれません。残念ながら、勉強しても難しい問題は難しいままです。賢くなるのではなく、問題を小さくする技術を身につけるべきです。これは才能の話ではなく、訓練の話なので、正直誰でも身につけられるかと思います。
# 動的型付け言語を選ぶ前に考え直しませんか
ここから少し、私の個人的な好みが強く入ります。先に断っておきますね。
私は動的型付け言語が好きではありません。PythonもRubyもJavaScriptも、業務では書きますが、好きでは無いです。理由は単純で、書いた本人が何を扱っているか分からないコードを、後から他人が読んで分かるはずがないためです。
巷では「Pythonは書きやすい」だとか、「JavaScriptは手軽」だとか、馬鹿の一つ覚えのように永遠と言われています。確かに、書き始めるまでのハードルは低いでしょう。しかし、それは短期的には楽であるというだけの話であって、長期的には負債が積み上がります。
引数が何の型か書かれていない関数。返り値が状況によって変わる関数。エラー時にNoneを返したり、空文字を返したり、例外を投げたりする一貫性のない設計。これらは、動的型付け言語特有の問題ではありませんが、動的型付けの環境では検出されないまま放置されやすい傾向にあります。
そして、そういうコードを書いた本人は、3ヶ月後には何ひとつ覚えていません。私にも前科があります。
これからプログラミングを始めるのであれば、最初から型のある言語を選んでください。GoでもRustでもKotlinでもSwiftでも、TypeScriptでも、好きなものを選べば良いと思います。動的型付け言語から始めて後から型に移行するのは苦痛でしょうし、最初から型に親しんだ方が遥かに早いかと思われます。
# 質問とか
環境, やりたかったこと, やったこと, 起こったこと, 試したこと, 仮説
このあたりが揃っていれば、回答する側は、スムーズに原因を絞り込めます。逆に、これらが何ひとつ揃っていない「動きません」だけの質問は、回答できません。回答できないというより、回答する前の調査だけで時間が溶けて、結果として誰も答えなくなります。私ならムカついて返信しないこともあるかもしれません。
「初心者なので〜」と前置きする方もいますが、初心者かどうかは関係ありません。初心者であろうと、そうでなかろうと、項目を埋めることはできますし、初心者ほど丁寧に書くべきです。慣れている人なら省略して伝わることも、初心者の場合は丁寧に書かないと伝わらないためです。
これは偏見ですが、質問が下手な人は概ね実装も汚いです。例外もあるかもしれませんが、私の観測範囲ではほぼ相関しているように思います。質問を組み立てることは、(本質的に)状況を分解して構造化する作業であって、それがプログラミングそのものであるためです。質問が組み立てられないということは、思考が組み立てられないということと同義で、思考が組み立てられなければ、コードも書けないでしょう。当たり前です。
# 「ググれ」が冷たく聞こえるのなら申し訳ないですが
わたしは以前、ggrksは最大限の優しさだと書きました。今でも、その考えは変わっていません。
技術的な質問に対して「自分で調べてね〜」と返すのは、決して冷たいわけではありません。
答えるのが面倒くさい訳ではないと言ってしまうと大嘘になるのですが、「あなたが自分で調べれば、もっと正確で網羅的な情報が手に入りますよ」の意であり、「私が中途半端に答えるよりも、検索した方が確実ですよ」という意味であり、「自身で調べる力を身につけた方がしあわせになれますよ」という意味でもあります。
これを冷たいと感じる方は、自分が答えを与えてもらえる立場だと思い上がっているのかもしれません。しかし、私はあなたの家庭教師でも、メンターでも、サポート窓口でもありません。私はとても優しいので聞かれたことにはなるべく答えるようにしていますが、それを当然のように要求されるのは、少し違うように思います。
ついでに、ググる行為自体にも割とスキルが要ります。「ECONNREFUSEDが出たんだけどどう治すの?」みたいな雑な自然言語ではなく、「ECONNREFUSED 127.0.0.1:5432 postgres:18.3-alpine」のように、自分の環境に近い具体的なワードを並べる、英語で検索する、公式ドキュメントを優先する、GitHubのIssuesを見る、Stack Overflowは新しい順に並び替える等の工夫が必要です。
ググれと言われて冷たいと感じる前に、自分のググり方を一度見直してみてください。それだけで、解決できる問題の幅が多分広がるかと思います。
# さいごに
正直、プログラミングなんてものはどんなに馬鹿でも時間さえかければできるようになります。
これは、別に綺麗事として書いているのではなく、私自身がソースです。
私自身、地頭(笑)が良いタイプでも、論理的思考力が突出しているタイプでもなく、どちらかと言えば落ちこぼれ側の人間です。覚えたての頃に書いていたコードなんて、今読み返すと冗談みたいに酷いものですし、未だに簡単なバグで数時間詰まることもざらにあります。
何とかコードを書いて、何とかお仕事を頂いて、何とか運用できているのは、ただただ触っている時間がそれなりに長いからというだけでしょう。そこに特筆すべき才能なんてものは介在していません。
なので、自分には才能がないからという理由で諦めるのは、的外れだと思っています。あなたに無いのは才能ではなく、ただの時間です。退屈な作業を、何百時間、何千時間と積み上げる時間が足りていないだけです。
逆に言えば、これを積み上げる気が無いのなら、永遠にできるようにはなりませんし、「いつか分かるようになる」だとか、「コツを掴めば」みたいな、そういう商材屋の好きそうな胡散臭い魔法はありません。触った分だけ出来るようになります。
それが面倒だと感じるのであれば、それは多分、あなたがプログラミングをそこまで好きではない、というだけの話です。それは別に悪いことではありません。世の中には、プログラミング以外にも、楽しい営みがいくらでもあります。プログラミングが特別な何かだと思い込むのは、業界の人間の自意識過剰でしょう。
何とかしたいと思うのであれば、何とかしてください。何とかしたくないのであれば、別に何ともしなくて構いません。
埋蔵金探しとかも新鮮で楽しそうですよ。
それでは。

