paolobrasolin / fletcher

Universal sourcecode transpiler for commutative diagrams
MIT License
1 stars 0 forks source link

fletcher

CI tests status badge Latest release badge License badge Maintainability badge Test coverage badge

Victorian illustration of a boy drawing a bow.

This project is a sourcecode transpiler for commutative diagrams.

The aim is being able to translate from and to any format, most of which are LaTeX DSLs.

Here is the progress on the planned ones:

Target Import Export
amscd ██████████ ██████████
amscdx ██████░░░░ ███████░░░
CoDi ░░░░░░░░░░ ░░░░░░░░░░
quiver ████████░░ ███████░░░
tikz-cd ░░░░░░░░░░ ░░░░░░░░░░
xymatrix ██░░░░░░░░ ░░░░░░░░░░
...

Abstract nonsense

Private repo: https://github.com/paolobrasolin/ouroboros

Practical considerations

A transpiler like this could be realized with many technologies. I have a few end goals:

TypeScript therefore looks like the best choice. On top of it, two outstanding libraries that trivialize a lot of groundwork are nearley.js for grammar-based parsing and Superstruct for data validation and coercion.

Architectural guidelines

Freely transpiling among many DSLs requires a transpilation procedure for each ordered source/target language pair we want to connect.

How many transpilers do we need in total?

Implementing an Universal Language (UL for short) clearly is the winning strategy.

Each DSL will have a dedicated folder It will contain a some components allowing it to be transpiled back and forth from the UL.

The UL will also have its own folder. It will contain much less than other DSLs, since it's used only for internal representation.

A few more words should be spent about the design of the UL, as two very different approaches can be followed for the usage of optional structures.

  1. Everything is optional (except topology).

    • PRO: injectors output can be limited to the used attributes
    • CON: projectors input needs to be asserted to circumvent partial signatures (after the input has been coerced externally, of course)
  2. Everything is mandatory (and has reasonable defaults).

    • CON: injectors output must be created as the injector must not know about defaults and all properties are mandatory; this also avoids breakage on UL extensions
    • PRO: projectors input has simple signatures (no * | undefined) and can be destructured right away while simply ignoring unsupported features of the target DSL

It's a matter of balance, but ultimately the latter alternative has slightly better ergonomics, and a fully explicit UL schema should be simpler to reason about.