There are several languages that compile to Go, trying to be a better a Go. Off the top of my head: XGo (https://github.com/goplus), Borgo (https://github.com/borgo-lang/borgo), Soppo (https://github.com/halcyonnouveau/soppo)...
There are several languages that compile to Go, trying to be a better a Go. Off the top of my head: XGo (https://github.com/goplus), Borgo (https://github.com/borgo-lang/borgo), Soppo (https://github.com/halcyonnouveau/soppo)...
Both Borgo and now Lisette seem to act as though (T, error) returns are equivalent to a Result<T, error> sum type, but this is not semantically valid in all cases. The io.Reader interface's Read method, for example, specifies not only that (n!=0, io.EOF) is a valid return pattern, but moreover that it is not even an error condition, just a terminal condition. If you treat the two return values as mutually exclusive, you either can't see that you're supposed to stop reading, or you can't see that some number of valid bytes were placed into the buffer. This is probably well known enough to be handled specifically, but other libraries have been known to make creative use of the non-exclusivity in multiple return values too.
You are right, and thank you for pointing this out. I've opened an issue:
https://github.com/ivov/lisette/issues/12
I have a few approaches in mind and will be addressing this soon.
I gave Lisette a run today. I really like it, its a clear improvement to Go.
Here a few things that i noticed.
- Third party Go code support (like go-chi) is a absolute must have. This is THE feature that will possibly sky-rocket Lisette adoption. So something like stubs etc, maybe something like ReScript has for its JS interop (https://rescript-lang.org/docs/manual/external). The cli tool could probably infer and make these stubs semi-easily, as the go typesystem is kind of simple.
- The HM claim did confuse me. It does not infer when matching on an Enum, but i have to manually type the enum type to get the compiler to agree on what is being matched on. Note, this is a HARD problem (ocaml does this probably the best), and maybe outside the scope of Lisette, but maybe tweak the docs if this is the case. (eg. infers somethings, but not all things)
- Can this be adopted gradually? Meaning a part is Go code, and a part generated from Lisette. Something like Haxe perhaps. This ties to issue 1 (3rd party interop)
But so far this is the BEST compile to Go language, and you are onto something. This might get big if the main issues are resolved.
To be fair, I feel like the language is widely criticized for this particular choice and it's not a pattern you tend to see with newer APIs.
It's a really valid FFI concern though! And I feel like superset languages like this live or die on their ability to be integrated smoothly side-by-side with the core language (F#, Scala, Kotlin, Typescript, Rescript)
To be honest you could easily mark this as an additional (adt) type if that suits you better. Its a halting situation no matter how you twist it.
How do compile errors propagate back from the target language to the source language?
They are not supposed to produce code that doesn't compile, why would they?
Debugger positions on the other hand are a pain with these things.
Uh yes, that's what I meant ;)
In C/C++ you have the #line preprocessor directive. It would be nice if Go had something similar.
Go has apparently got //line directives, and this project uses them.