Haxe 4.2.1 で python コードを出力した結果

# 概要
Python を最近触り始めたところコードブロックがインデント基準というのが個人的に気に入らず、スーパーセットを探したところ Haxe "ハックス(Youtube調べ)" (https://haxe.org/) を見つけた。
バイトコードを吐くのではなく、Python のソースにトランスパイルできるので、既存の Python コードとキメラ合体できるのでは？と思い触ってみた。

- Python へのトランスパイル方法はこちら
https://haxe.org/manual/target-python-getting-started.html

# 環境
Haxe: 4.2.1

# コード1
## Haxe
```haxe:Main.hx
class Main {
  static public function main():Void {
    trace("Hello World");
  }
}
```

ファイル名はクラス名と一緒じゃないといかんのかな？

## Python

トランスパイルコマンド: `haxe --python main.py --main Main`

```python:main.py
# Generated by Haxe 4.2.1+bf9ff69
# coding: utf-8
import sys



class Main:
    __slots__ = ()

    @staticmethod
    def main():
        print("Hello World")


class haxe_iterators_ArrayIterator:
    __slots__ = ("array", "current")

    def __init__(self,array):
        self.current = 0
        self.array = array

    def hasNext(self):
        return (self.current < len(self.array))

    def next(self):
        def _hx_local_3():
            def _hx_local_2():
                _hx_local_0 = self
                _hx_local_1 = _hx_local_0.current
                _hx_local_0.current = (_hx_local_1 + 1)
                return _hx_local_1
            return python_internal_ArrayImpl._get(self.array, _hx_local_2())
        return _hx_local_3()



class python_internal_ArrayImpl:
    __slots__ = ()

    @staticmethod
    def _get(x,idx):
        if ((idx > -1) and ((idx < len(x)))):
            return x[idx]
        else:
            return None


class python_internal_MethodClosure:
    __slots__ = ("obj", "func")

    def __init__(self,obj,func):
        self.obj = obj
        self.func = func

    def __call__(self,*args):
        return self.func(self.obj,*args)




Main.main()
```

でかい。


# コード2
## Haxe
```haxe:Main.hx
class Main {
  static public function main():Void {
    trace("Hello World");

    var items = ["a", "b", "c"];
    for (index in 0...items.length) {
        trace('$index : ${items[index]}');
    }
    if (items.length == 3) {
        trace('length is ');
        trace('3');
    } else {
        trace('length is ');
        trace('not 3');
    }
    trace('end');
  }
}

```

肝心のコードブロックを作ってみた。

## Python

トランスパイルコマンド: `haxe --python main.py --main Main`

```python:main.py
# Generated by Haxe 4.2.1+bf9ff69
# coding: utf-8
import sys



class Main:
    __slots__ = ()

    @staticmethod
    def main():
        print("Hello World")
        items = ["a", "b", "c"]
        _g = 0
        _g1 = len(items)
        while (_g < _g1):
            index = _g
            _g = (_g + 1)
            print(str(((("" + str(index)) + " : ") + HxOverrides.stringOrNull((items[index] if index >= 0 and index < len(items) else None)))))
        if (len(items) == 3):
            print("length is ")
            print("3")
        else:
            print("length is ")
            print("not 3")
        print("end")


class haxe_iterators_ArrayIterator:
    __slots__ = ("array", "current")

    def __init__(self,array):
        self.current = 0
        self.array = array

    def hasNext(self):
        return (self.current < len(self.array))

    def next(self):
        def _hx_local_3():
            def _hx_local_2():
                _hx_local_0 = self
                _hx_local_1 = _hx_local_0.current
                _hx_local_0.current = (_hx_local_1 + 1)
                return _hx_local_1
            return python_internal_ArrayImpl._get(self.array, _hx_local_2())
        return _hx_local_3()



class python_internal_ArrayImpl:
    __slots__ = ()

    @staticmethod
    def _get(x,idx):
        if ((idx > -1) and ((idx < len(x)))):
            return x[idx]
        else:
            return None


class HxOverrides:
    __slots__ = ()

    @staticmethod
    def stringOrNull(s):
        if (s is None):
            return "null"
        else:
            return s


class python_internal_MethodClosure:
    __slots__ = ("obj", "func")

    def __init__(self,obj,func):
        self.obj = obj
        self.func = func

    def __call__(self,*args):
        return self.func(self.obj,*args)




Main.main()
```

`for` じゃない！…のは `index in ...` でイテレートしてるからかな？まぁコードブロックはよしなにしてくれるのでありがたい。

あと `HxOverrides` というのが増えてる。

# 気づき
- 互換性のためのイテレータコードとか入ってるけど、ロジックでは使ってない。そこは Tree-shaking されないっぽい。でもまぁイテレータなんて実際のコード書いたら100%出てくるから無駄ではないか。
- python の package manager (pyenv とか poetry とか) で Haxe を Virtualenv スコープにできたら、つよいと思う。

# 他の気になるポイント
- python の 3rd party library の使い方
- IDE補完力（上記ありきだと思うけど）