dingo: A meta-language for Go
68 points by telemachus
68 points by telemachus
I looked at the pattern-matching code (because I know about this stuff). I find the code weird (pattern_match.go, exhaustiveness.go).
I would expect that patterns form a tree, for example Ok(x, Some(y)). The representation of match expressions is designed as if a pattern was either a Result, or an Option, or a Tuple, it does not seem to support nesting them.
There is no abstract syntax tree to represent patterns, match expressions, etc. For example constructor names are strings. In general datatypes are weird, they use poor types that are not informative. For example, the function that checks looks for counter-examples to exhaustiveness (patterns that are not covered) returns a list of strings (that is, a list of already-formatted counter-examples), whereas I would naively expect a list of patterns.
I would have naively expected a standard compiler that parses an extension of the Go syntax into an abstract representation, then transforms it into Go code. But the datatypes and API design are a bit strange, in-between "low-tech hack" and "proper compiler". I don't know if this is idiomatic Go style, or a design choice (made by a human or by a machine) that would deserve an explanation and may be questionable.
I have the impression that there is something wrong in the findMissingPatterns function, when it checks hasWildcardAtPosition. For example if I use the tuple patterns
(Ok(x), Error(y)) -> ...
(_, Ok(y)) -> ...
At position 0, one of the clauses has a wildcard, but continuing looking for counter-examples of the form (Ok, _) is not quite correct -- there are no counter-examples of this form, but (Error, Error) is not covered.
interesting project -- though the readme reeks of AI.
note to people writing projects: using LLMs to generate rote, boring crap is fine, but the description of your project should be hand-written if you want it to resonate. you're telling a story, and humans are great storytellers.
Yeah and it's also unnecessarily long. I don't mind long READMEs in general but if they are AI generated for the most part I am reluctant to invest time in reading them. The "why dingo" bit in the beginning feels like pure kitsch for example.
The sick irony of this README is that it's about 10 times less terse than a human would have written. I actually like the sales pitch of Dingo in general, but distilling it from all the Claudium is far more tiring than it needs to be.
What happened to "summarize this for me", I thought that was half the point of these dang tools?
humans are great storytellers.
Some humans are. Some are in fact worse than an LLM fed a heap of facts and ideas.
think about it this way: would you prefer to receive a handwritten note (written by a friend who has a tenuous grasp on language), or a perfectly grammatically correct and focus-groupedly-appropriate hallmark card?
in my view, a readme is about expression, storytelling -- it's personal, and often creative.
i believe that everyone should nurture their ability to tell stories -- LLMs are incapable of doing this well by nature, because they are not personable or creative machines.
But a readme isn’t a note from a friend. I’d much rather have a readme that clearly conveys the information I want than an inscrutable personal statement.
that's a fair point, thank you. i stand by my assertion that the readme of your project should feel human -- it's 1 of the main entrypoints & you need to tell people why they should use your thing, and you need to tell them quickly. instead of using a readme as a man page or a reference manual, most are more of a "marketing" page for people who have never seen their project before.
this is obviously project dependent - but i think my theory stands true: that readmes, as project intros, are best off being written by hand, because it lets the author's character shine through.
is their writing highly technical? outworldy and strange? static and careerist? all of these are important indicators to me, and they're washed away by either the overuse of LLMs, or the "man page readme" approach.
I agree, it is very happy-go-lucky style, I immediately hesitate when I see that it's not polished and cleaned up.
I'm a simple man. I see "claude" in contributors. I close the tab.
care to explain your perspective?
I feel the same even though I use Claude Code and I'm not really against AI code generation in general. But allowing Claude to perform the git commits and list itself as a coauthor suggests either the author has very low competence, or is an AI hypester who wants to explicitly signal that they are vibecoding. Both of these are very negative signals about the project quality.
Interesting, specifically on commits I have the opposite opinion: I think that it is healthy to acknowledge that an AI tool wrote most of the code, and making it an author is a nice way to do this.
One problem with AI-generated READMEs is that they are often too verbose. But this is an editing/direction problem: just as people should review the code produced and ask the automated tool to do better if there are issues, they should re-read the README produced and iterate to get better output. It may be a signal that the latter is not done (either people value the text less than the code, or they don't review either seriously and both are going to be mediocre).
It’s a very high-probability marker of 1. low code quality and 2. lack of long-term development
See neighbour comment for more red flags https://lobste.rs/c/snnopm
Go deserves to get TypeScripted. There have been a few compile-to-Go projects but this may be the most reasonable I've seen. Go has a fine runtime and ecosystem, but actually writing Go code is a miserable experience.
alt take: actually writing Go code is an excellent experience once you learn how and it makes writing anything else into a miserable experience.
Why do Go developers have such a Stockholm syndrome? I don't see such attitudes in other communities.
I started using Go in 2012 because other languages didn’t have a sane build/deploy story. With Go I could build a truly static binary with “go build”, I could run the tests with “go test”, the code was formatted the same way across the eco system when I saved my editor, even things like nonblocking I/O were far better in Go than other languages, etc. It was just a lot more productive than everything else, and that really hasn’t changed for most of the systems I work with.
For some things, TypeScript is more ergonomic. For peak performance applications I would use Rust. But by default I would strongly prefer Go. In all cases, my guiding light is “get shit done”; my goal is not to write my programs according to a specific dogma.
Have you considered that others might like things that you don't like? And that they're not wrong for that?
Looking at other comments by kbd I’m sure they have considered that! But also, your take here conveniently ignores the 2nd part of jrwren’s take: “[…] once you learn how and it makes writing anything else into a miserable experience”. IMO, this is a big proposition which often lacks evidence. Evidently, there are plenty of other languages that people clearly do like and in fact prefer over Go for their expressiveness despite the extra complexity to build amazing things. It’s one thing to say you like a thing and another to accuse everybody else of incompetence or negligence.
They didn't accuse everybody of incompetence or negligence!
Alex just suggested that its possible to like writing go and it not be because 'stockholm syndrome'
To be clear I don't really agree with jrwren's take either. My disagreement is in taking the leap to stockholm syndrome.
I find joy in languages in general and have learned about and used as many as I can. But I've been most productive in Go. It's not perfect, but it stays out of my way and has never ended up being a poor choice for anything I've built with it.
What I've observed over the years is folks using Go are mostly just building stuff, and not trying to shout about Go from the rooftops. Meanwhile in some spheres, Lobste.rs included, there's almost a compulsion to shit on Go at any opportunity like it's a badge of honor. That, to me, is more strange than any language fandom.
I've spent years obsessing over and using tons of different languages. But I've been most productive in Go. It's not perfect, but it stays out of my way and has never ended up being a poor choice for anything I've built with it.
I’m glad you found something that you enjoy doing, that works for you and the problems you’re solving. But there’s a lot of people who simply do not enjoy reading or writing Go for one reason or another. That’s ok and those people don’t need to be called out for “not appreciating the simplicity” either. Some are happy to trade simplicity in syntax for simplicity and maybe even clarity in semantics. The latter usually comes with quite a bit of complexity in the language.
What I've observed over the years is folks using Go are mostly just building stuff, and not trying to shout about Go from the rooftops.
When it comes to languages there’s so much to like and dislike IMO. I love Go’s speed, the std lib, the tools people usually build with it and some of its operational characteristics while not enjoying its syntax and some associated conventions at all. Quite frankly, I do find it ugly and get annoyed by Go people repeatedly telling everybody else that it’s fine and eventually you’ll get past that, the very definition of stockholm syndrome.
Meanwhile in some spheres, Lobsters included, there's almost a compulsion to shit on Go at any opportunity like it's a badge of honor. That, to me, is more strange than any language fandom.
Dunno, IMO there are always people like that in every language community. I try to skip over those zealots and focus on the useful bits of which there’s still plenty on here. Interestingly, I find the opposite: while Go as a language is criticized an ok amount I’d like to see more focus on how those short comings lead to faults if that is even a factor.
Seems we're talking past each other. I'm not calling out anyone for "not appreciating the simplicity" or even not liking Go. I agree with most of the things you said.
What I'm calling out is how eager folks are to have these same tired arguments over and over again specifically for Go. I don't mean this in an antagonistic way, but your reply is a perfect example as it pre-replies to those arguments which no one even made yet!
Quite frankly, I do find it ugly and get annoyed by Go people repeatedly telling everybody else that it’s fine and eventually you’ll get past that, the very definition of stockholm syndrome.
This is a nitpick, but that isn't the definition of stockholm syndrome. If you were captive to the language (e.g. had to use Go for work), then sure! Not everyone gets to use their favorite language for work. That's a bummer, and if another language would genuinely be better (in the grand scheme of things including the cost to switch and compatibility with the team), it could make sense to advocate for it in good faith. Failing that, yes, I would recommend stockholm syndrome. :) It's probably easier than changing jobs.
But if you're choosing to use Go because the pros outweigh the cons, which I promise you is the case for plenty of Go developers, that's not stockholm syndrome. That's just logic.
Every language has pros and cons. Go in particular has some cons that are like catnip for language nerds to whine about. As a language nerd myself, I just wish Go threads were less prone to these tired routines. It's not some grand mystery to me. I can imagine why it happens and why people would be motivated to do it, and engage with it, and for the cycle to keep going. It just makes talking about Go less fun and more shallow.
tl;dr: don't yuck other people's yums
What I'm calling out is how eager folks are to have these same tired arguments over and over again specifically for Go. I don't mean this in an antagonistic way, but your reply is a perfect example as it pre-replies to those arguments no one even made yet!
Not you specifically; I was referring to “and it makes writing anything else into a miserable experience” and the response it prompted that it’s actually ok to like other ways of doing it. The part that I quoted is the one thing that I keep hearing from Go folks all over the interwebs and IMO it carries the idea that using any other language is suffering from the Stockholm syndrome as you pointed yourself if I understand you correctly. Maybe I’m misunderstanding.
This is a nitpick, but that isn't the definition of stockholm syndrome.
Maybe let’s agree to disagree here unless you’re willing to explain this in more detail.
Keep in mind this thread started before the reply you're complaining about. The reply you keep jumping back to was pretty hyperbolic for sure, but their point was pretty clear to me, and it was only using the same arguments it replied to.
What I'm hearing from you is:
Rather than complaining about Go devs not being bothered by these 17 year old takes, I wish folks would just stop making those 17 year old takes in every Go thread, especially if they're going to get so riled up by Go folks not agreeing with them!
Where are the Go devs waltzing into every Rust or Zig thread trying to sell them on the ways of if err != nil unprompted? Or that for loops are all those languages really need? I promse you that's not happening. Why would we care what other languages do? Are we trying to find One True Language?
Where are the Go or even Python devs going into every Ruby thread and raising its many failure modes and how miserable it can be at scale? Maybe that was acceptable in 2012, but I would expect that mostly on Reddit or Hacker News; I have a higher standard for Lobste.rs discourse. (Context: I love Ruby and especially its early days as a community, I do not like it at scale in a large org, but I'm not going to take every opportunity to dunk on it in Ruby threads because of that.)
Maybe let’s agree to disagree here unless you’re willing to explain this in more detail.
I explained it in detail already. The necessary part of stockholm syndrome is being captive. In assuming there's no way to use Go other than being forced to, you're just projecting your own feelings onto others.
What I'm hearing from you is:
When someone implies that people that like Go are insane or have poor taste or Have Not Seen the Light of Other Languages, that's OK and based. When Go devs chime in that actually possible to legitimately like it for other reasons, and there are miserable aspects of other languages too, that's insane, and you're tired of it, and it's their fault for making you hear that they disagree with your take.
I think we’re done here. I explicitly said that I ignore the zealous takes and focus on meaningful critique of which there is plenty to be had. Yet, you chose the worst possible way to put words into my mouth and attribute malice.
Rather than complaining about Go devs not being bothered by these 17 year old takes
C/C++ and the like will always be there and devs who’ll value those old takes. But this is not what’s happening here. Instead, people compare TypeScript, Rust, Ocaml, Haskell, Elixir, Gleam, etc with Go and this is where the interesting conversations are to be had.
Where are the Go devs waltzing into every Rust or Zig thread trying to sell them on the ways of if err != nil unprompted?
Of course they do: Rust borrow checker is hard/stupid so I chose Go instead. Repeated a million times by Go folks and everybody else.
Where are the Go or even Python devs going into every Ruby thread and raising its many failure modes and how miserable it can be at scale?
Mostly Twitter/X but also Reddit, to this day despite Shopify printing money and so many other successful businesses being built on Ruby.
The necessary part of stockholm syndrome is being captive.
In what sense are other languages captive compared to Go?
In assuming there's no way to use Go other than being forced to, you're just projecting your own feelings onto others.
I never assumed that; for the last time, please do not put words into my mouth. There’s a lot to like about Go and I even said that much. Yet, many people—yes, myself included—do not think that Go is a beautiful language. My own reading is that it was never the ambition to have a beautiful language but a pragmatic one. This in and off itself can perceived as a beautiful trait and I agree. But I and many other people seem to prefer other traits more. So I do not project any of my own feelings onto others.
Yet, you chose the worst possible way to put words into my mouth and attribute malice.
In fairness to the parent, myself and at least one other user also interpreted your comments as supportive of kbd's "Go users have Stockholm syndrome" because the parent rebutted that claim and then you seemed to disagree with the rebuttal. I don't really know what else to make of your comment, but I'll believe you if you say that's not what you meant. I just don't think the parent (or others of us) were unreasonable or acting in bad faith for interpreting your rebuttal of a rebuttal as support. 🤷♂️
I’m chiming in to say that I didn’t interpret it that way. From the original response:
But also, your take here conveniently ignores the 2nd part of jrwren’s take: “[…] once you learn how and it makes writing anything else into a miserable experience”. IMO, this is a big proposition which often lacks evidence. … It’s one thing to say you like a thing and another to accuse everybody else of incompetence or negligence.
The problem is that both parties made exaggerated claims that provoked the other. I saw the original response as trying to insert itself in the middle.
I’m chiming in to say that I didn’t interpret it that way.
Absolutely. My point wasn't that mine was the only reasonable interpretation, but rather that it's a reasonable interpretation.
The problem is that both parties made exaggerated claims that provoked the other.
I strongly disagree that "Have you considered that others might like things that you don't like? And that they're not wrong for that?" is an exaggerated, provocative claim in response to the previous "Stockholm Syndrome" comment. I genuinely don't know how alex's comment might read as "provocative", but I can easily understand how rebutting alex's comment might be interpreted as support for kbd's "Stockholm Syndrome" comment (I have great difficulty understanding it differently, except to take ur5us at his later word that he didn't mean it as such).
My point wasn't that mine was the only reasonable interpretation, but rather that it's a reasonable interpretation.
That’s ok, nor did I intend to imply that you were making that point.
Have you considered that others might like things that you don't like?
I read this as provocative because this question was a straw man. It was not claimed that others can’t like things that the commenter did not like. In fact, the original comment claimed that once you learn go, it is impossible to like any other language. That, too, was an exaggeration that provoked a long back and forth here.
I don’t want to make this discussion any longer. Just wanted to note that I read the exchange differently.
But there’s a lot of people who simply do not enjoy reading or writing Go for one reason or another
I agree with this, but I don't see how it justifies kbd's "Stockholm syndrome" comment that the parent is rebutting.
IMO, this is a big proposition which often lacks evidence... It’s one thing to say you like a thing and another to accuse everybody else of incompetence or negligence.
Yes thank you for calling this out, other people are pretending to miss it. "If only you knew what you were doing...". I programmed Go professionally. Go just leaves many modern language features on the floor, gives you nothing in return, and developers say 🤖 thank you we didn't need that stuff 🤖. No you really do want your compiler to tell you if you forget to even check the error value you're returning. Brain worms to think that Go is acceptable in its design.
Well, we have to pick some tool, and while I can live with a linter rather than the compiler telling me when I forgot to check an error, I often cannot live with a language that is dramatically slower to iterate with (either because there is far too few static guarantees or because the static guarantees are onerous in exchange for precious little real world value). I cannot live with tooling that makes every mundane task (like building a program) cumbersome. I cannot live with a language that my team can't learn to use productively in a short amount of time, or for which I can't find developers who can be productive quickly.
Your "brain worms" analysis would have people prefer tools that fail miserably at the fundamentals in order to avoid the mild inconvenience of using a linter rather than the compiler for a particular category of errors. That seems like "brain worms" to me. 🙃
"Despite its glaring flaws that we can all recognize, this is yet my imperfect tool of choice." is of course a reasonable position.
"It's a skill issue that you don't see how everything else is miserable compared to Go." is not.
"Despite its glaring flaws that we can all recognize, this is yet my imperfect tool of choice." is of course a reasonable position.
Agreed, but this contrasts sharply with your previous "Brain worms to think that Go is acceptable in its design." and "Why do Go developers have such a Stockholm syndrome?".
Far from exclusive to Go.. I see a lot of it among the .NET developers I've worked with. (And I'm sure people would say similar things about me in other contexts..)
Fair, I can imagine .NET folks being insular as well. Microsoft even encourages that by its behavior.
I suppose Java people were like this too about OO, and anyone who knew anything went "dude, Java isn't even good OO" and yet we had to tolerate Java's supremacy for decades.
Why do Go developers have such a Stockholm syndrome? I don't see such attitudes in other communities.
Um what? People have preferences and they are extremely shown in all communities. You call it stockholm syndrom based off of personal bias but in a differnt view it's no different than the RiiR group.
I love the idea of making the Go language better. Go as a language is pretty mediocre (the rest of the ecosystem is great), but the existing syntax isn't (much of) a problem, it just lacks features. Dingo unfortunately changes more of the syntax than necessary: There's no need for a let keyword, or a colon separating types in parameter lists. The enum syntax would also be better off leaning on Go structs, e.g.:
type Result enum {
Ok struct {
value int
}
Error {
message string
}
}
Or, better than translating the example from the readme 1:1, drop nested structs and be more Go-y:
type Result[T any] enum {
OK T
Err error
}
Same for the match syntax:
switch v := result.(enum) {
case OK:
fmt.Printf("Success: %d\n", v)
case Error:
fmt.Printf("Error: %s\n", v)
}
Right? This feels much closer to what I would have expected with the stated goals.
I do like your examples tho. :)
This project is only about a week old, but people may find it interesting. It's a transpiler that adds a whole lot of Rust-like syntactic sugar to Go. One thing that struck me in the pitch is that they hope to have the same effect on Go that TypeScript has had on JavaScript. That is, the authors hope that the Go team would be more receptive to changes if this project makes clear how useful (and easy to implement?) they are. (My two cents: this isn't likely. See, e.g., this thread about sum types and especially this post by Russ Cox.)
For decades, programming language evolution has been broken:
❌ The old way: Community → Proposal → Years of debate → Maybe no → Frustration
✅ The Dingo way: Developers → Use features → Data emerges → Go team decides with evidence
This doesn’t really make sense after looking at the examples. It’s not an extension of the language — it’s added colons to separate identifiers from their types, introduced let, and others. By diverging so far from mainline, I would think it becomes harder to consider it evidence based for pushing proposals.
Obviously, you're quoting an LLM. I'm not sure it's worth the time arguing with something that can produce nonsense faster than we can read and understand it.
The thing about TypeScript that made it succeed is you can take ordinary JS and just add types. Dingo has needless syntax differences from Go.
func main() {
let message = "Hello from Dingo!"
fmt.Println(message)
}
Changing from var to let is a total bikeshed move. Completely pointless.
func divide(a: int, b: int) Result {
Adding colons between the variable name and type is also pointless. Maybe you like it better or maybe you don't, but if the goal is to be "TypeScript for Go" you have to have a superset of syntax, not arbitrary aesthetic differences.
My understanding of any missing license is that the code is by default "All Rights Reserved" by the author (and, uh, I guess the T&C of Claude)
Actually, modern TypeScript does not add any runtime syntax. Dingo looks more like CoffeeScript to me.
this thread reminds me of https://lobste.rs/s/jrwaey/why_engineers_can_t_be_rational_about ("Why Engineers Can't Be Rational About Programming Languages")
"TypeScript for Go" is something I've wanted for years. I'm looking forward to digging into this.
Man, this made my day. One of the funniest README out there.
Also, it made me think what "community" means for DontBeEvil™ guys.
Skimming the AI generated README there's few cases were the dingo output is shown. From what I do see, some of the transpiled code isn't very idiomatic Go: returning Option<T> returns an OptionT struct, and not T, bool that would be idiomatic. Code isn't shown for Result<T, error> but I imagine it's similar. I imagine this makes it difficult to use dingo effectively when importing existing Go from other packages or modules.
That meta-level programming can adapt a programming language to many use cases made Lisp syntax macros very popular within that community. gcc adopted some kind of plug-in architecture like 25 years ago. Nim for like 20 years has had macros you write analyzers/transformers in Nim, but they want to move to a plug-in architecture like this dingo project.
There's a fundamental tension between extensibility and locking everything down. Some people love this kind of thing while others hate it. Where one's opinions lie usually depends one one's lived experience with various instances -- which is to say, is usually more anecdotal than systematic.
I liked that this project at least claims to value empiricism, but the way dependency works, it's all too easy for plug-ins to become unscoped and needed if any of your upstream dependencies need it. E.g., to make this point more specific, with Nim you can do user defined operators and templates (a simple kind of macro) and call templates with a foo: block syntax. So, you can say:
template pointerArith(blk) = # library
proc `+!` ...
blk
pointerArith: # my code
b = a +! 1 # bump some pointer
but here the "magic" (it's not very magical) is very contained and identifiable/auditable by just the regular scoping rules of the language.
They mention "dependency resolution" in the gigantic bulleted readme, but is anyone familiar enough with Dingo to answer if it has easy scoping like this or if a dependency 3 levels back uses enum then everything downstream needs that plug-in?
You know that feeling when you're writing Go and you type if err != nil for the 47th time in a single file?
I am happy to not mess with ugly try/catch logic. And also, now I write ? for the 47th time. Easy to overlook and miss like any symbolic operators.
Or when you forget to check for nil and your production server learns what a panic feels like?
No, because I wouldn't dream of putting code without basic static analysis into production.
Or when you're explaining to a Rust developer why Go doesn't have sum types and they look at you like you just said "we don't believe in seatbelts"?
Considering sum types to be a security features seems really weird. Look, if I want sum types I wouldn't be using a language designed for simplicity. I would use a more complex language, like Rust. And if I want to use Rust, why would I use Dingo?
A lot of this sounds like "I want to use Go, but I want to use Rust" or any other language for that matter, which always sounds strange to me. Maybe I am missing something, but I don't get those projects that want to make one language into another. Why not use the language you wanna use in first place?
From the the sound of:
67% less error handling boilerplate — ? operator instead of 47 if err != nil blocks 78% code reduction with sum types — Rust-style enums that just work Zero nil pointer panics — Option types that the compiler enforces Pattern matching — Exhaustive, type-safe, impossible to mess up Same performance — Transpiles to clean Go, zero runtime overhead
With all of this why do you want to use Go in first place?
And why when you want "Go plus many features" don't you any of the other languages like vlang, etc.? Too many to point out.
The whole idea of Go is to have simple primitives, so you can create simple constructs, so you can easily see what is going on, and everything is "loud" instead of subtle. Both choices are very valid, but twisting one into the other is fighting the language you use.
Don't get me wrong, I am not saying "This project shouldn't exist". It just appears to do what the initial design of Go tried to avoid, which is adding additional constructs, instead of relying on fewer core ones. Now granted it appears that Go is slowly leaving that path, after Rob Pike stated the opposite (fewer language changes, more focus on the ecosystem, compiler, GC, etc.) and went into well deserved retirement.
With all that said looks like a cool project. Like that there are both many examples, a Manifest, the "just do it", "don't ask for permission" attitude. So even if I seem to completely miss the point and don't appear to be part of the target audience: Cool project!
(just hoping that despite what is written in the Manifest, people using Dingo isn't the reason for changing Go. And if so I hope there actually is a fork that doesn't just throw design decisions overboard, cause some other language has a feature)