I'll talk about several things, so don't hesitate to pick what interest you ;).
Previously, I demonstrated (among other things) that we can produce small, clean, and fast JS by using types known at compile time. However as all types need to be known at compile time, we need a strong deduction type system.
I also used DOP principles to achieve good performances during parsing and emission. However this quickly become a pain when you have complex types (unions, type guards, etc). A pain to achieve performances in a part I'll argue isn't the priority.
Now I want to test other ideas with RBrython, this time with a dynamic type system (i.e. not known at compile time). I'll work time to time on it as a pet project, when I want to do something for a change.
I'll try to document as much as possible, as well as documenting similar Brython features. Offering some suggestions and opinions. It'll prevent me from flooding github issue.
E.g. :
https://github.com/denis-migdal/RBrython/blob/master/docs/runlib/index.mdIn this new project, I want to clearly segregate different parts:
- parser (py2ast using brython)
- emitter (ast2py)
- runlib : helpers required to run the JS code.
- corelib : implementation of global python symbols (e.g. int, range, etc).
- stdlib : standard python library.
Indeed, I think that parser, emitter and runlib aren't that big, and can be implemented quite easily (maybe I'll soon change my mind about it xD). However corelib and stdlib are an huge code base. This means that if they depends on the emitter or on the runlib, each changes e.g. on functions calls, impact all of this huge code base.
I recently read "clean code", "clean architecture", and "refactoring" books, it was quite interesting. And indeed, keeping things segregated is very important.
I want to write corelib in Python, using special emitter rules to generate the JS. Then, if something changes, we just have to modify the emitter rules. For example:
class int:
def __new__(cls) :
return 2
def __add__(self, b: int) -> int:
return __JS_ADD__(self, b) # type: ignore
I think this will make contributions easier on corelib and stdlib, without having to know too much on Brython specifics. Also, if something changes in emitter/runlib, this shouldn't impact too much of the code base.
For performances, I can then have 2 more processes :
- checker : assert types at compile time.
- optimizer : modify the AST.
When optimizing, instead of trying to modify the emitter rules, I'll change the ASTNode type and add new emitter rules. I can then, e.g. inline some function calls.
Ofc, I still want no JS-Python conversions. I'll argue that we should manipulate vanilla JS data, and that Python specific behavior should be implemented in the Python operations.
Making it easier to write JS libs for Brython to achieve native performances.
I'll keep you updated on my progress ;)
You can read more on:
https://github.com/denis-migdal/RBrython/