プログラミング言語は思考の
道具だった
(形式言語)

AI がコードを書いてくれる時代になりました。
ChatGPT や GitHub Copilot を使えば、自然言語で指示するだけでプログラムが生成されます。
それなら、もうプログラミング言語を学ぶ必要はないのでしょうか。

私は最近、この問いについて考え直しました1
結論から言えば、プログラミング言語を学ぶ意義は今も変わっていません。
ただしその理由は、コードを書くためでも、AI の出力をチェックするためでもありません。
思考するためです。

関連記事

1. 形式言語としての強み

AI がコードを書いてくれる今、プログラミング言語を学ぶ必要はあるのでしょうか。

答えは明確です。
必要です。
ただしその理由は、AI が書いたコードをチェックするためではありません。
自分が思考するためです。

数学を学ぶとき、記号を使って思考します。
微分積分を自然言語だけで理解するのは困難です。
dy/dx、∫、Σ といった記号があるから、複雑な概念を扱えます。

微分を自然言語で説明するより、dy/dx と書いた方が明快です。
記号による思考が可能になります。
ベクトルの内積を言葉で説明するのは大変ですが、
a · b = |a||b| cos θ
と書けば一行に収まります。

自然言語には行間があります。
文脈に依存します。
同じ言葉でも状況によって意味が変わります。
それは人間同士のコミュニケーションでは便利ですが、厳密な思考には向きません。

複雑な構造を扱うとき、形式言語の力が発揮されます。
形式言語とは、曖昧さを排除するために厳密に定義された言語のことを指します。

プログラミング言語も同じです。
抽象的な概念を具体的なコードで表現することで、理解が深まります。

問題を理解するとき、プログラミング言語という形式言語を使うと、曖昧さが排除されます。
論理の飛躍が見えます。
矛盾が明らかになります。

2. プログラミング言語で初めて理解できたこと

私が最初に学んだプログラミング言語は C++、Ruby、Java でした。
その後、Python、JavaScript、TypeScript、Rust と触れる言語を増やしていきました。
振り返ると、新しい言語を学ぶたびに理解が広がっていった実感があります。

プログラミング言語を学ぶことで、多くの基本概念が身につきました。

データ構造では、配列、リスト、スタック、キュー、木構造、ハッシュテーブル。
アルゴリズムでは、探索、ソート、再帰、動的計画法。
これらを自然言語だけで理解するのは難しかったと思います。

2.1. ポインタと配列

たとえば、C 言語でポインタを学んだときも同じでした。
array[i] という一行は、インデックスによる直接アクセスという仕組みを端的に示します。

int value = 42;
int *ptr = &value;  // アドレスを取得
*ptr = 100;         // 参照先を変更Code language: JavaScript (javascript)

*ptr&value という記号は、参照の方向性を視覚的に表現しています。
実体と参照の違い、メモリ上のアドレスという概念。

これらを自然言語だけで理解するのは困難でした。
ポインタのコードを実際に書いて動かして、初めて腑に落ちました。

2.2. 関数型プログラミング

関数型プログラミングに触れたときは、さらに世界が広がりました。
例えば、JavaScript のラムダ式を見ると、関数も値として扱えるという発見があります。

const add = (x) => (y) => x + y;
const add5 = add(5);
console.log(add5(3));  // => 8Code language: JavaScript (javascript)

関数がファーストクラスオブジェクト、つまり他の値と同じように扱える存在であること。
高階関数という、関数を受け取ったり返したりする関数。
カリー化によって部分適用ができること。
これらは自然言語で説明されても、コードを書いて動かすまで本当の理解には至りませんでした。

2.3. 再帰構造

再帰を考えてみます。
再帰とは、関数が自分自身を呼び出す仕組みです。

二分探索木を実装したときも同じでした。
二分探索木とは、左の子が親より小さく、右の子が親より大きいという規則を持つ木構造です。

class Node
  attr_accessor :value, :left, :right

  def initialize(value)
    @value = value
    @left = nil
    @right = nil
  end
end

class BinarySearchTree
  def initialize
    @root = nil
  end

  def insert(value)
    @root = insert_node(@root, value)
  end

  private

  def insert_node(node, value)
    return Node.new(value) if node.nil?

    if value < node.value
      node.left = insert_node(node.left, value)
    elsif value > node.value
      node.right = insert_node(node.right, value)
    end

    node
  end
endCode language: CSS (css)

木構造。
左部分木と右部分木。
再帰的な挿入。
これらの概念は、コードを書いて実装することで初めて本当に理解できました。
図や説明文だけでは、実感が伴いませんでした。

3. AI 時代でも変わらないこと

ここまで書いてきて、ひとつのことに気づきます。
プログラミング言語を学ぶ理由は、コンピュータに命令するためではありません。
自分が考えるためです。

これは「コードを書くために考える」のではありません。
「コードを書くことで考える」のです。

3.1. コードを書くことで考える

AI に「ユーザー認証機能を実装して」と指示すれば、コードは生成されます。
でもそのコードが本当に必要な機能を満たしているかどうか、判断するのは人間です。

最初から完璧な要件定義があって、それをコードに落とし込むだけ、という開発は現実にはなかなか存在しません。
実際には、コードを書きながら、試しながら、動かしながら、徐々に理解が深まっていきます。

動かしてみて、うまくいかないとわかり、別の方法を試します。
そうやって何度も書き直して、最終的に純度の高いコードが残ります。

試行錯誤の過程で多くのコードを書き捨て、要件自体が明確になっていきます。
この過程を省略することはできません。

たとえば要件定義を考えてみます。
「ユーザーがログインできる機能を作る」という要件があったとします。
これを自然言語で詳細化しようとすると、どこまで詳しく書けばいいのかわかりません。

でもコードで書こうとすると、多くの疑問が浮かびます。

struct User {
    id: UserId,
    username: String,
    password_hash: String,  // ハッシュ化されたパスワード
    created_at: DateTime,
}

fn login(username: &str, password: &str) -> Result<Session, LoginError> {
    // ユーザーを検索
    let user = find_user_by_username(username)?;

    // パスワードを検証
    if !verify_password(password, &user.password_hash) {
        return Err(LoginError::InvalidCredentials);
    }

    // セッションを作成
    let session = create_session(user.id)?;

    Ok(session)
}Code language: JavaScript (javascript)

コードを書こうとすると、具体的な問いが生まれます。

パスワードはどう保存するのか。
ハッシュ化は必要か。
セッションはどう管理するのか。
エラーハンドリングはどうするのか。

自然言語で「ログイン機能」と言っているだけでは、これらの問いは生まれません。
コードという形式言語を使うことで、考えるべきことが見えてきます。

3.2. コードは思考の道具

新しいものを生み出すとき、コードを書く営みは思考そのものです。
この感覚を持っている人と持っていない人では、AI をどう使うかも変わってくるでしょう。
道具を使いこなすには、道具を理解する必要があります。
そして理解するには、自分で使ってみる必要があります。

プログラミング言語を学ぶことは、今も意味があります。
それは思考の幅を広げ、問題を見る目を養い、新しい何かを生み出す力になるからです。

  1. -杉本啓さん: 「コードはAIが書いてくれるから、人間は要件定義にシフトすればよいとか言っているひとは、本当に新しいものをつくる上で、コードを書く営為がどれほど重要か、まるきりわかっていないのだと思う。 コードは、まずもって思考のツールなんだ。」 / X