Thanks a lot for explanation! I've looked through the code, too. Let me make some comments, if you excuse me.
I've looked at your usages of
Either. You are indeed using it as a union type on your own types. It does seem from the cursory reading of your code that it can be slightly improved. Let us take one example where you return
Either<Node.Import, Node.Global> from
globalAtIndex. In this particular example you can define an interface
ImportOrGlobal that is implemented by both
Node.Global and return that one instead of
Either. It looks like the immediate uses for this function can be made slightly simpler and easier to read after this change. The same seems true for other uses of
Either in your project.
Also, I've looked at some of the usages of
Triple in your code base. Many of them would defenitly benefit from one-line declaration of the
data class. For example, you could declare
data class FuncSig(val nameMap: NameMap, val exprsUsed: Int, val sig: List<Node.Type.Func>) right before
toFuncSig function. Not only this will immensly improve readability of the
toFuncSig function declaration itself, but this would also reduce the need to redeclare (by destructuring) the names of the actual components at every use-site of the corresponding function. The last, but not the least, it will make it easier to refactor the code in the future (e.g. adding a new returned item will not force all prior uses to be changed).
I do suggest you to try it, if you care. This will make your code more idiomatic from Kotlin standpoint.