I do think there may be a limit to how far it can be improved, though. Like typed nil means that a variable of an interface type (say coming from pure Go code) should enter Lisette as Option<Option<http.Handler>>. Sure, one can match on Some(Some(h)) to not require two unwrapping steps, but it becomes a bit awkward anyway. (note: this double-Option is not a thing in Lisette at least as of now)
Lisette also doesn't remove the need to call defer (as opposed to RAII) in the very awkward way Go does. E.g. de facto requiring that you double-close on any file opened for write.
Typescript helps write javascript, but that's because until WASM there was no other language option to actually run in the browser. So even typescript would be a harder sell now that WASM can do it. Basically, why try to make Go more like Rust when Rust is right there? And fair enough, the author may be aiming for somewhere in between. And then there's the issue of existing codebases; not everything is greenfield.
So this seems best suited for existing Go codebases, or when one (for some reason) wants to use the Go runtime (which sure, it's at least nicer than the Java runtime), but with a better language. And it does look like a better language.
So I guess what's not obvious to me (and I mentioned this to the author) is what's the quick start guide to having the next file be in Lisette and not Go. I don't think this is a flaw, but just a matter of filling in some blanks.
[1] https://blog.habets.se/2025/07/Go-is-still-not-good.html
But I can't help wondering:
If it is similar to Rust why not make it the the same as Rust where it feature-matches?
Why import "foo.bar" instead of use foo::bar?
Why Bar.Baz => instead of Bar::Baz =>? What are you achieving here?
Why make it subtlety different so someone who knows Rust has to learn yet another language?
And someone who doesn't know Rust learns a language that is different enough that the knowledge doesn't transfer to writing Rust 1:1/naturally?
Also: int but float64?
Edit: typos
I'm curious about the compiled Go output though. The Result desugaring gets pretty verbose, which is totally fine for generated code, but when something breaks at runtime you're probably reading Go, not Lisette. Does the LSP handle mapping errors back to source positions?
Also wondering about calling Lisette from existing Go code (not just the other direction). That feels like the hard part for adoption in a mixed codebase.
Is the goal here to eventually be production-ready or is it more of a language design exploration? Either way it's a cool project.
Lisette brings you the best of both worlds.
I know it is Rust inspired, but why write it in Rust and not Go?
What would be actually nice is running async Rust on the Go green threads runtime.
I love Rust for what it is, but for most of my projects, I can’t justify the added complexity. Sure, there are a bunch of things I miss from the Rust world when I’m working on large-scale distsys services in Go, but introducing Rust in that space would be a recipe for disaster.
I guess the Go team knows that if they start adding everyone’s favorite Rust features, the language would become unrecognizable. So we’re not getting terser error-handling syntax or enums. Having union types would be nice too.
But I work in platform engineering, so my needs are quite different from someone writing business logic in Go. I understand that having a more expressive syntax is nice when you’re writing complex business code, but in reality, that almost always comes with a complexity/fragility tradeoff. That’s part of the reason no one wants to use Rust to write their business logic, despite it being so much more expressive.
For distsys, programming ergonomics matter far less compared to robustness and introspectability. So the Go runtime with Go syntax is perfect for this. But of course, that’s not true for all use cases.
Sorry for the rant - completely uncalled for. This is a cool project nonetheless :)