Mojo入門 (2) - Mojo言語の基本
以下の記事が面白かったので、かるくまとめました。
前回
1. Mojo言語の基本
「Mojo」は、「Rust」「C++」などの他のシステム言語と多くの共通点がありますが、「Pythonのスーパーセット」になるよう設計されているため、「Python」の機能や概念の多くは、「Mojo」にうまく反映されています。
ただし、「Mojo」は新しい言語であり、Pythonの新実装ではありません。「Mojo」は、システムプログラミング機能、強力な型チェック、メモリ安全性、次世代コンパイラなどを備え、Pythonをまったく新しいレベルに引き上げます。
2. Mojoプログラム
「Mojo」はコンパイル言語であり、パフォーマンスとメモリ安全性の多くはこの事実から派生しています。
「Mojoプログラム」 (.mojo または .🔥 ファイル) は、AOT (ahead-of-time) または JIT (just-in-time) でコンパイルできます。他のコンパイル言語と同様、プログラムへのエントリポイントとして fn main() が必要です。
fn main():
var x: Int = 1
x += 1
print(x)
Pythonと同様の def main() も利用できますが、fn main() を使用すると動作が少し異なります。「Mojoプログラム」ではなく「Mojoモジュール」 (APIライブラリ) では、インポートするため、main() は必要ありません。
3. 構文とセマンティクス
「Mojo」は Pythonの構文とセマンティクスをすべてサポートしています。ただし、「Mojo」はまだ開発中であるため、Pythonの機能のうち、「Mojo」にまだ実装されていないものがいくつかあります (詳しくは「Mojo roadmap」を参照)。不足している Python機能はすべて間もなく提供される予定です。
さらに、「Mojo」にはPython機能を超える多くの機能が含まれています。
4. 関数
Mojoの関数は、fn (上記) または def (Python と同様) で定義します。fnは、厳密に型指定されたメモリセーフな動作を強制するのに対し、def は Pythonスタイルの動的を提供します。
fn と def にはそれぞれの価値があるため、両方学習することが重要です (詳しくは「programming manual」を参照)。
5. 変数
Mojoの変数は、var で可変値、または let で不変値を定義します。
fn do_math():
let x: Int = 1
let y = 2
print(x + y)
do_math()
3
6. 関数の引数と戻り値
関数 fn の引数と戻り値には、型が必要です。
引数を不変 (borrowed) にしたい場合は、引数の頭に borrowed を指定、または何も指定しない (デフォルト) ようにします。
fn add(x: Int, y: Int) -> Int:
return x + y
z = add(1, 2)
print(z)
3
引数を可変 (inout) にしたい場合は、引数の頭に inout を指定します。この引数は、関数内で変更でき、その変更が関数外に反映されます。
fn add_inout(inout x: Int, inout y: Int) -> Int:
x += 1
y += 1
return x + y
var a = 1
var b = 2
c = add_inout(a, b)
print(a)
print(b)
print(c)
2
3
5
引数を所有者 (owned) にしたい場合は、引数の頭に owned を指定します。この引数は、関数内で変更できますが、その変更は関数外に反映されません。
fn set_fire(owned text: String) -> String:
text += "🔥"
return text
fn mojo():
let a: String = "mojo"
let b = set_fire(a)
print(a)
print(b)
mojo()
mojo
mojo🔥
ただし、関数に値の所有権を与え、コピーを作成したくない場合 (型によってはコストのかかる操作になる可能性がある)、関数にaを渡すときに ^ “transfer” 演算子を指定できます。 transfer 演算子は事実上、ローカル変数名を破壊します。後でそれを呼び出そうとすると、コンパイラエラーが発生します。
let b = set_fire(a^)
7. 構造体
Mojoの構造体は、Pythonのクラスに似ています。どちらもメソッド、フィールド、演算子のオーバーロード、メタプログラミング用のデコレータなどをサポートしています。ただし、Mojoの構造体は完全に静的であり、コンパイル時にバインドされます。動的なものは許可されません。
構造体の例は、次のとおりです。
struct MyPair:
var first: Int
var second: Int
fn __init__(inout self, first: Int, second: Int):
self.first = first
self.second = second
fn dump(self):
print(self.first, self.second)
使用方法は、次のとおりです。
let mine = MyPair(2, 4)
mine.dump()
2 4
8. Pythonのインテグレーション
Mojoはまだ開発中であり、Pythonの完全なスーパーセットではありませんが、既存のPythonコードをすぐに活用できます。内部ではCPythonインタープリタを使用してPythonコードを実行します。
NumPyをインポートして使用する例は、次のとおりです。Pythonのnumpy はインストールされている必要があります。
from python import Python
let np = Python.import_module("numpy")
ar = np.arange(15).reshape(3, 5)
print(ar)
print(ar.shape)
[[ 0 1 2 3 4]
[ 5 6 7 8 9]
[10 11 12 13 14]]
(3, 5)
次回
この記事が気に入ったらサポートをしてみませんか?