Pythonとの連携

badge

Pythonへのexport

Ergスクリプトをコンパイルすると.pycファイルが生成されますが、これは単純にPythonのモジュールとして読み込むことができます。 ただし、Erg側で非公開に設定した変数はPythonからもアクセスできません。

# foo.er
.public = "this is a public variable"
private = "this is a private variable"
erg --compile foo.er
import foo

print(foo.public)
print(foo.private) # AttributeError:

Pythonからのimport

Pythonから取り込んだオブジェクトはデフォルトですべてObject型になります。このままでは比較もできないので、型の絞り込みを行う必要があります。

標準ライブラリの型指定

Python標準ライブラリにあるAPIは、すべてErg開発チームにより予め型が指定されています。なので、pyimportでそのまま呼び出すことが出来ます。

time = pyimport "time"
time.sleep! 1

ユーザースクリプトの型指定

Pythonスクリプトの型ヒント(type hint)をErgは関知しません。

Pythonのfooモジュールに型を付けるfoo.d.erファイルを作成します。

# foo.py
X = ...
def bar(x):
    ...
def baz():
    ...
class C:
    ...
# foo.d.er
.X: Int
.bar!: Int => Int
.foo! = baz!: () => Int # aliasing
.C!: Class

d.er内では宣言と定義(エイリアシング)以外の構文は使えません。

Pythonの関数はすべてプロシージャとして、クラスはすべて可変クラスとしてしか登録できないことに注意してください。

foo = pyimport "foo"
assert foo.bar!(1) in Int

これは、実行時に型チェックを行うことで型安全性を担保しています。チェック機構は概念的には以下のように動作します。

decl_proc proc!: Proc, T =
    x =>
        assert x in T.Input
        y = proc!(x)
        assert y in T.Output
        y

これは実行時オーバーヘッドとなるので、PythonスクリプトをErgの型システムで静的に型解析するプロジェクトが進められています。