3 ms·
I've chatted a bit with the author, but not actually tried the language. It looks very interesting, and a clear improvement. I'm not particularly quiet about no
by thomashabets2 6mo ago
I've chatted a bit with the author, but not actually tried the language. It looks very interesting, and a clear improvement. I'm not particularly quiet about not liking Go[1].
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 https://blog.habets.se/2025/07/Go-is-still-not-good.html
- smw 6mo agoRust's async story is much less ergonomic than go's -- mostly because of lack of garbage collection. That might be a good reason by itself?
- thomashabets2 6mo agoDoes Go actually have an async story? I know that question risks starting a semantic debate, so let me be more specific. Go allows creating lightweight threads to the point where it's a good pattern to just spin off goroutines left and right to your heart's content. That's more of a concurrency primitive than async. Sure, you combine it with a channel, and you've created an async future. The explicit passing of contexts is interesting. I initially thought it would be awkward, but it works well in practice. Except of course when you need to call a blocking API that doesn't take context. And in environments where you can run a multitasking runtime, that's pretty cool. Rust's async is more ambitious, but has its drawbacks. Go's concurrency story (I wouldn't call it an async story) is way more yolo, as is the rest of the Go language. And in my experience that Go yolo tends to blow up in more hilarious ways once the system is complex enough.
- Matl 6mo agoFor one, I am glad I don't have to color my functions like your typical async.
- thomashabets2 6mo agoI agree that this is the big problem with Rust's async story. But like I said, in my opinion this compares with Go not having an async story at all.
- ncruces 6mo agoOther languages have ill considered shortcomings. Rust has ambitious shortcomings.
- osigurdson 6mo agoGo's async story is great, as there is no function coloring at all. That being said, I don't like Go's syntax very much. The runtime is great though.
- ninkendo 6mo agoTo be fair, Go’s async story only works because there’s a prologue compiled into every single function that says “before I execute this function, should another goroutine run instead?” and you pay that cost on every function call. (Granted, that prologue is also used for other features like GC checks and stack size guards, but the point still stands.) Languages that aspire to having zero-cost abstractions can’t make that kind of decision, and so you get function coloring.
- osigurdson 6mo agoI'm not sure this is 100% correct. I haven't researched it but why would they perform such a check at runtime if it is 1)material and 2) can be done at compile time. However, even if it is, Go is only trying to be medium fast / efficient in the same realm as its garbage collected peers (Java and C#). If you want to look at Rust peer languages though, I do think the direction the Zig team is heading with 0.16 looks like a good direction to me.
- zozbot234 6mo ago> Basically, why try to make Go more like Rust when Rust is right there? Go gives you access to a compute- and memory-efficient concurrent GC that has few or no equivalents elsewhere. It's a great platform for problem domains where GC is truly essential (fiddling with spaghetti-like reference graphs), even though you're giving up the enormous C-FFI ecosystem (unless you use Cgo, which is not really Go in a sense) due to the incompatibilities introduced by Go's weird user-mode stackful fibers approach.
- sa-code 6mo ago> Basically, why try to make Go more like Rust when Rust is right there? The avg developer moves a lot faster in a GC language. I recently tried making a chatbot in both Rust and Python, and even with some experience in Rust I was much faster in Python. Go is also great for making quick lil CLI things like this https://github.com/sa-/wordle-tui https://github.com/sa-/wordle-tui
- thomashabets2 6mo agoNo doubt a chatbot would be built faster if using a less strict language. It wasn't until I started working on larger Python codebases (written by good programmers) that I went "oh no, now I see how this is not an appropriate language". Similar to how even smaller problems are better suited for just writing a bash script. When you can have the whole program basically in your head, you don't need the guardrails that prevent problems. Similar to how it's easy to keep track of object ownership with pointers in a small and simple C program. There's no fixed size after which you can no longer say "there are no dangling pointers in this C program". (but it's probably smaller than the size where Python becomes a problem) My experience writing TUI in Go and Rust has been much better in Rust. Though to be fair, the Go TUI libraries may have improved a lot by now, since my Go TUI experience is older than me playing with Rust's ratatui.
- aaztehcy 6mo ago[flagged]
- LtdJorge 6mo agoI've also found that traversing a third-party codebase in Python is extremely frustrating and requires lots of manual work (with PyCharm) whereas with Rust, it's just 'Go to definition/implementation' every time from the IDE (RustRover). The strong typing is a huge plus when trying to understand code you didn't write (and I'm not talking LLM-generated).
- smohare 6mo ago[dead]
- knocte 6mo agoFrom your blog entry: > Go was not satisfied with one billion dollar mistake, so they decided to have two flavors of NULL Thanks for raising this kind of things in such a comprehensible way. Now what I don't understand is that TypeScript, even if it was something to make JavaScript more bearable, didn't fix this! TS is even worse in this regard. And yet no one seems to care in the NodeJS ecosystem. <selfPromotion>That's why I created my own Option type package in NPM in case it's useful for anyone: https://www.npmjs.com/package/fp-sdk https://www.npmjs.com/package/fp-sdk </selfPromotion>
- smt88 6mo agoHow would TS fix null in JS without violating its core principles of adhering to EcmaScript standards and being a superset of JS?
- knocte 6mo agoMaybe spit warnings when undefined is used? In the same way it does for when you use typeScript in a type-loose way. But yeah it's a fair point. Sometimes I think I should just write my own lang (a subset of typescript), in the same fashion that Lisette dev has done.
- smt88 6mo agoYou can already do this with strict type checking enabled and the NonNullable type. You can't enforce it in any normal codebase because null is used extensively in the third party libraries you'll have to use for most projects.
- alpinisme 6mo agoYour readme would really benefit from code snippets illustrating the library. The context it currently contains is valuable but it’s more what I’d expect at the bottom of the readme as something more like historical context for why you wrote it.
- 6mo ago
- phplovesong 6mo agoBefore typescript we had Haxe, and its still a "better language". But i guess marketing won, and worse it better. Shrug.
- omcnoe 6mo agoGolang does have a lot of weird flaws/gotchas, but as a language target for a compiler (transpiler) it's actually pretty great! Syntax is simple and small without too many weird/confusing features, it's cross platform, has a great runtime and GC out of the box, "errors as values" so you can build whatever kind of error mechanism you want on top, green threading, speedy AOT compiler. Footguns that apply when writing Go don't apply so much when just using it as a compile target. I've been writing a tiny toy functional language targeting Go and it's been really fun. Go's defer is generally good, but it interacts weirdly with error handling (huge wart on Go language design) and has weird scoping rules (function scoped instead of scope scoped).