プログラミング

新言語「Mojo」に可能性しか感じない件

title_image
tsucci

みなさんこんにちは、こんばんは、tsucciです。

What's Mojo?

Pythonの簡潔な構文と、C言語並みの処理速度を併せ持つ、新しいプログラミング言語で、主にAI開発の分野での活躍が期待されています。

Pythonを書いてて思うこと

  • 型注釈がおまけ(ちゃんと静的構文解析して欲しい)
  • 動的型付けがつらい
  • 遅い(マルチスレッドって何?おいしいの?)

Mojoを書いて思ったこと

  • JavaScript→TypeScriptに移行したときのような感じ
  • Pythonをそのまま静的型付けにしたような感じ
  • 性能は、Playground環境じゃあまり感じられず

Mojoを触ってみた

Mojoはコンパイル言語なのですが、現在コンパイラは配布されておらず、Jupyter NotebookでPlayground環境が提供されています。

※開発途上の言語なのでシンタックスハイライトが微妙なのはご容赦ください。

letとvar

TypeScriptではお馴染みですね。

  • let: イミュータブル(不変)、再代入不可
  • var: イミュータブル(可変)、再代入可
def add(n1, n2):
    let added = n1 + n2
    # 再代入不可なのでエラー
    added += 10
    print(added)
add(3, 4)

おぉ、ちゃんと警告されますね。

error: Expression [1]:7:11: invalid mutation of immutable value 'added._value'
    added += 10

fn定義

関数定義(def)に対して、JavaScriptのstrictモードのような挙動を与えるようです。

  • 引数が暗黙でイミュータブルになる
  • 引数への型指定が必須になる
  • ローカル変数の暗黙的な宣言が無効化される
  • etc

型チェック

個人的に一番感動したのがこれです。

fn add(n1, n2):
    let added = n1 + n2
    print(added)
add(3, 4)

ちゃんと警告が出ます。

error: Expression [1]:5:8: 'fn' parameter type must be specified
fn add(n1, n2):

型推論もしてくれます。

# IntとIntの和がIntであることは自明なので戻り値の型指定は不要

fn add(n1: Int, n2: Int):
    let added = n1 + n2
    print(added)
add(3, 4) # 7

struct

Go言語やC++ではお馴染みの構造体ですね。

struct types are similar in many ways to classes. However, where classes are extremely dynamic with dynamic dispatch, monkey-patching (or dynamic method “swizzling”), and dynamically bound instance properties, structs are static, bound at compile time, and are inlined into their container instead of being implicitly indirect and reference counted.

https://docs.modular.com/mojo/notebooks/HelloMojo.html

class(クラス)では動的なディスパッチやモンキーパッチが可能だけど、struct(構造体)ではできないよということみたいです。

Pythonは動的にメソッドを追加できるけど、

class Person:
    def __init__(self, first_name, last_name):
        self.first_name = first_name
        self.last_name = last_name

def greet():
    print("Hello, world")

p1 = Person("John", "Doe")
p1.greet = greet
p1.greet() # Hello, world

Mojoでは、struct定義で実装していない処理を書くとエラーになる

from String import String

struct Person:
    var first_name: String
    var last_name: String
    
    fn __init__(inout self, first_name: String, last_name: String):
        self.first_name = first_name
        self.last_name = last_name

def greet():
    print("Hello, world")
    
let p1 = Person("John", "Doe")
p1.greet = greet
p1.greet()
error: Expression [3]:29:7: 'Person' value has no attribute 'greet'
    p1.greet = greet
    ~~^~~~~~

classとほとんど一緒ですがいくつか違いがあります。

  • 全てのインスタンスプロパティはvar or letで明示的に宣言する
  • fn定義を使用している=引数が不変であるためselfを変更できない
    • inoutキーワードを使用して変更可能であることを明示する

Pythonモジュールのインポート

numpyやpandasなどの既存のPythonモジュールも使用できます。

from PythonInterface import Python

let np = Python.import_module("numpy")
array = np.array([1, 2, 3])
print(array)

let pd = Python.import_module("pandas")
df = pd.DataFrame([1, 2, 3])
print(df)
[1 2 3]
   0
0  1
1  2
2  3

まとめ

正直、私はデータアナリストではないので数値解析などの検証はしませんでしたが、普段Pythonを書いていて気になるポイントが抑えられている印象でした。

Pythonに優秀な型チェッカーが出てくるか、Mojoの成熟が先かという感じですが、個人的には後者に期待が持てます。

コンパイラが配布されたら、並列処理などをゴリゴリ回してパフォーマンス面の検証もしてみたいと思います(Notebookでたくさんコード書くのは辛い)。

余談ですが、話題の対話型AIはPythonで実装されているようですが、もしMojoに換装されたら、劇的に速度が向上しそうですね。ちょっとAI怖いかもと思う今日この頃でした。

AUTHOR
tsucci
tsucci
記事URLをコピーしました