14. Pythonista 向けの読み替えとコード例

14.1. この章で学ぶこと

  • Mojo の位置づけの再確認

  • Pythonista がつまずきやすい点

  • ownership・compile-time・trait の読み替え

この章は、Python 経験者向けの補足です。 コードを見ながら、Mojo が Python とどこまで似ていて、どこから違うのか を整理します。

まずは次の3つを押さえると読みやすいです。

  • 最初の見た目はかなり Python に近い

  • でも中身はコンパイル言語寄り

  • ownership と compile-time がわかれ目になる

14.2. Python との違いの地図

この章では、Python 経験者がつまずきやすいポイントを、コード例を通して確認します。

Python の感覚

Mojo での読み替え

名前がオブジェクトを指す

誰がその値を所有しているか

関数は何でも受け取れる

read / mut / var でシグネチャに意図を出す

例外は実行時に伝わる

raises でシグネチャに明示する

型ヒントは補助的

[] はコンパイル時情報・コード生成に直接効く

duck typing

trait で必要な能力を宣言する

以降は、この読み替え表の各行をコードで確認していきます。

14.3. ownership と value semantics

Mojo を学ぶときの大きなわかれ目がここです。

14.3.1. 基本

  • 値には owner がある

  • owner の寿命が終わると値は破棄される

  • 参照はそのあいだだけ安全に使える

  • GC なしで安全性を目指す

ref value_ref = list[0]

Python では、変数は「オブジェクトへの名前」と考えることが多いです。 一方で Mojo では、誰がその値を持っているか をより強く意識します。

つまり、

「名前がオブジェクトを指す」というより、 「誰がその値を持っているか」 を意識する世界

と考えると入りやすいです。

出典: Ownership

補足: 最初は少し重い考え方ですが、安全性と性能を両立するための土台です。

14.4. read / mut: 関数シグネチャが意味を持つ

def add(mut x: Int, read y: Int):
    x += y

def main():
    var a = 1
    var b = 2
    add(a, b)
    print(a)  # 3

この例では、引数の役割がシグネチャに出ています。

  • read は読み取り用

  • mut は書き換え用

ここで大事なのは、その関数が何をするかを、引数宣言の時点でかなり読める ことです。

Python では、破壊的かどうかを名前や説明に頼ることが多いです。 Mojo では、それをシグネチャに出しやすいです。

出典: Ownership

補足: 「Python よりシグネチャが多くを語る言語」と理解するとよいでしょう。

14.5. mut の実務的な意味: コピーしない更新

def mutate(mut l: List[Int]) raises:
    l.append(5)

def main() raises:
    var values = [1, 2, 3, 4]
    mutate(values)
    print(values)  # [1, 2, 3, 4, 5]

この例では、mut によって 破壊的に更新する ことが明示されています。

ポイントは次の通りです。

  • 更新することがわかりやすい

  • 不要なコピーを避けやすい

  • 意図が API に出る

これは地味ですが、実務ではかなり重要です。

出典: Ownership

補足: 性能が大事なコードほど、コピー回数や aliasing の制御が効いてきます。

14.6. var^: ownership transfer

def take_text(var text: String):
    text += "!"
    print(text)

def main():
    var message = "Hello"
    take_text(message^)
    # print(message)  # ここでは使えない

ここでは、所有権の移動がはっきり出ています。

  • var は受け取る側が ownership を持つ

  • ^ は呼び出し側から ownership を渡す

  • 渡したあとの元の変数は使えない

これは Python にはあまりない感覚です。

ここで大事なのは、この値はもう自分では使わない、と明示できる ことです。 そのぶん、コンパイラは危険な使い方を防ぎやすくなります。

出典: Ownership

補足: システムプログラミング言語に求められる安全性の中核にある考え方です。

14.7. compile-time parameters

def repeat[count: Int](msg: String):
    comptime for i in range(count):
        print(msg)

def main():
    repeat[3]("Hello")

出力:

Hello
Hello
Hello

この例で大事なのは、[] が実行時引数ではないことです。

  • [] は compile-time input

  • () は runtime input

  • comptime for でコンパイル時に展開できる

つまり、見た目は関数呼び出しでも、コード生成に直接効く情報を渡している ということです。

出典: Parameters

補足: Python の型ヒントよりも、性能戦略に近い仕組みです。

14.8. type generic + value generic

def repeat[
    MsgType: Writable,
    count: Int
](msg: MsgType):
    comptime for _ in range(count):
        print(msg)

def main() raises:
    repeat[2](42)
    repeat[3]("mojo")

この例では、2種類の parameter が出ています。

  • MsgType は型 parameter

  • count は値 parameter

どちらも compile-time specialization に効きます。

ここで大事なのは、型だけでなく値までコンパイル時に持ち込める ことです。 これが、固定長配列や SIMD、GPU 寄りの処理と相性がよい理由のひとつです。

出典: Parameters / Generics

補足: ここでも、Mojo が typed Python ではなく compile-time 指向の言語だと見えてきます。

14.9. traits / generics

def all_equal[
    T: Equatable & Copyable
](ref lhs: List[T], ref rhs: List[T]) -> Bool:
    if len(lhs) != len(rhs):
        return False
    for left, right in zip(lhs, rhs):
        if left != right:
            return False
    return True
print(all_equal([1, 2, 3], [1, 2, 3]))
print(all_equal(["hello", "world"], ["hello", "world"]))

この例では、trait 制約が その型に必要な能力 を表しています。

  • Equatable は比較できること

  • Copyable はコピーできること

つまり、T は何でもよいわけではなく、必要な能力を持っていなければならない ということです。

ここで大事なのは、generic が型安全のためだけでなく、 具体的なコード生成にも関わる ことです。

出典: Generics

補足: Python の duck typing よりも、必要な能力を先に言語側で宣言する感覚に近いです。

14.10. この章を一文で言うと

Mojo は最初は Python に近く見えるが、本質は ownership・compile-time・trait を土台にした別の言語です。

14.11. まとめ:読み替えのポイント

仕組み

対応する Python の感覚

Mojo での違い

read / mut

引数の in/out 区別

シグネチャで明示

var / ^

代入・コピー

所有権の移動

[] parameter

ジェネリクス・型ヒント

コンパイル時入力・特化

trait

Protocol / ABC

コード生成にも効く

raises

例外のある関数

シグネチャで型として明示

「似ているのは文法であって、値の考え方やコンパイル時の仕組みはかなり違う」 ― この一点を押さえると、以降のコードが読みやすくなります。