7 ms·
Go's quite horrendous and limited type system makes it a poor fit for everything. The worst thing about Go is, in fact, the language. Everything except the lang
by flanked-evergl 1y ago
Go's quite horrendous and limited type system makes it a poor fit for everything. The worst thing about Go is, in fact, the language. Everything except the language redeems it.
- giik 1y agoCan you elaborate a bit on how does "Go's quite horrendous and limited type system" get in the way of crafting agents? Honest question, I am genuinely interested in what cannot be done easily or at all due to limitations of the Go type system.
- zveyaeyv3sfye 1y agoIt's just a uninformed hivemind comment written by someone lacking original thought. If you are interested in the merits of golang, you should listen to someone who uses it.
- flanked-evergl 1y agoI used it for years.
- williamdclt 1y agoI think the point was that "Go's quite horrendous and limited type system" gets in the way of everything (programming in general), nothing specific to crafting agents. There's a lot of discussions on the internet about the bad design decisions of Golang (for example around channels, enums, error handling, redeclarations, interfaces, zero values, nilability... at least generics aren't so much a subject anymore)
- Luker88 1y agoIf you want to know only about the type system, nowadays it's mostly the lack of basic enums, a clear divide in basic features of the language and of the libraries (and modern generics support) leading to things like `len(..)` vs `.Len()`. Those actually end up playing a bigger role than it seems imho, but even just the rest is death by a thousand cuts. You can find many articles on the internet about it, but in my experience I would summarize it in: It looks like it's made to have a simple compiler, not to simplify the programmer's life. Initially its simplicity is wonderful. Then you start to notice how verbose things are. Channels are another looks-nice-but-maybe-don't feature. nil vs nil-interface. Lack of proper enums is hurting so much I can't describe it. I personally hate automatic type conversions, and there are so many inconsistencies in the standard and most used libraries that you really start to wonder why some things where even done. validators that validate nothing, half-done tagging systems for structs, tons of similar-but-not-quite interfaces and methods. It's like the language has learning wheels that you can't shake off or work around. You end up wanting to leave for a better one. People had to beg for years for basic generics and small features. If google is not interested in it, you'd better not be interested in it and it shows after a while. Companies started to use it as an alternative to C and C++, while in reality it's an alternative to python. Just like in python a lot of the work and warnings are tied into the linter as a clear workaround. Our linter config has something like 70+ linters classes enabled, and we are a very small team. C can be described as a relatively simple language (with caveats), C++ has grown to a blob that does and has everything, and while they have lots of footguns I did not find the same level of frustration as with go. You always end up fighting a lot of corner cases everywhere. Wanted to say even more, but I think I ranted enough.
- deleted 1y ago[deleted]
- 9rx 1y ago> Lack of proper enums is hurting so much I can't describe it. Do you mean sum types? That is not a case of them not being "proper", though. They simply do not exist as a feature at all. Go's enums function pretty much like enums in every single other language under the sun. If anything, Go enums are more advanced than most languages, allowing things like bit shifts. But at the heart of it all, it's all just the same. Here are enum implementations in both Go and Rust: [Go] https://github.com/golang/go/blob/f18d046568496dd331657df4ba90218821cb9ffd/src/go/types/decl.go#L405 https://github.com/golang/go/blob/f18d046568496dd331657df4ba... [Rust] https://github.com/rust-lang/rust/blob/40daf23eeb711dadf140b2536e67e3ff4c999196/compiler/rustc_middle/src/ty/adt.rs#L562 https://github.com/rust-lang/rust/blob/40daf23eeb711dadf140b... While Go leans on the enum value produced by `range` to act as the language's enumerator, while Rust performs explicit incrementing to produce the enumerator, the outcome is no different — effectively nothing more than [n=0, n++]. Which stands to reason as that's literally, as echoed by the dictionary, what an enum is.
- Luker88 1y agoIt's not about 'range', and like you said enum and sum types are tied concepts in other languages, and yes I was talking about sum types. Even without sum types, there is a common pattern of defining a new type and const-defining the possible values that is a clear workaround on the lack of an 'enum' keyword. Maybe because the compiler can't be sure that those const values are all the possible values of the type, we can't have things like enforcing exhaustive switches on this "enum", and that is left to the linter at best. Default-zero initialization is always valid too, which can leave you with an "enum" value that is not present in the const definitions (not everything starts on iota, iota does not mean 0). It's a hack, it became a pattern. It still is not a proper (or even basic) enum even without sum types.
- 9rx 1y ago> It's not about 'range' It is to the extent that it helps explain what an enum is, and why we call the language feature what we do. Python makes this even more apparent as you explicitly have to call out that you want the enum instead of it always being there like in Go: for i, v in enumerate(array): # ... In case I'm not being clear, an array enumerator like in the above code is not the same as a language enumerator, but an array enumerator (or something similar in concept) is how language enumerators are implemented. That is why language enumerators got the name they did. > It still is not a proper (or even basic) enum even without sum types. It most certainly is "proper". In fact, you could argue that most other languages are the ones that are lacking. Go's enums support things like bit shifts, which is unusual in other languages. Perhaps it is those other languages that aren't "proper"? But, to be sure, it's not sum types. That is certain. If you want sum types you are going to have to look elsewhere. Go made it quite clear from the beginning that it wanted to be a "dynamically-typed language with statically-typed performance", accepting minimal static type capability in order to support the performance need. There is definitely a place for languages with more advanced type systems, but there are already plenty of them! Many considerably older than Go. Haskell has decades on Go. Go was decidedly created to fill in the niche of "Python, but faster", which wasn't well served at the time. Creating another Haskell would have been silly and pointless; but another addition to the long list of obscure languages serving no purpose.
- bbkane 1y agoI agree- multiple return values don't compose; errors are better than exceptions, but still super verbose; channels have a lot of foot guns; enums are just sad. But despite all of that the language has some really good qualities too- interfaces works far better than it feels like they should; the packaging fits together really well (I'm learning Rust right now and the file structure is far more complicated); and people are able to write a lot of linters/codegen tools BECAUSE the language is so simple. All in all I worry the least about the long term maintenance cost of my Go code, especially compared to my Python or JS code.
- 9rx 1y ago> enums are just sad. There isn't much more you can do with them. Literally all an enum can produce is a number. In increasingly common use in a number of languages, enums are being coupled with discriminated unions, using the enum value as the discriminant. This is probably what you're really thinking of, noticing Go's lack of unions. But where you might use a discriminated union if it were available, you would currently use an interface, where the type name, rather than an enum, is what differentiates the different types. If Go were to gain something like a discriminated union, it is likely it would want to extend upon that idea. Most especially given that generics already introduced syntax that would lend itself fairly well to it: type Foo interface { Bar | Baz } Where enums are used to act as a discriminant in other languages, that is largely just an implementation detail that nobody really cares about. In fact, since you mentioned Rust, there are only 8,000 results on Github for `std::mem::discriminant` in Rust code, which is basically nothing. That is quite indicative that wanting to use an enum (in Rust, at least) is a rare edge case. Funny, given how concerned Rust users seem to be about enums. Talk is cheap, I suppose.
- LtdJorge 1y ago#[repr(u8)] enum Discriminant { Disc0 = 0, Disc1 = 1, … }
- 9rx 1y agoFunny enough, manually defining the discriminant disables the enumerator: enum Discriminant1 { Disc0, Disc1, } #[repr(u8)] enum Discriminant2 { Disc0 = 10, Disc1 = 20 } fn main() { let d1 = Discriminant1::Disc1; let d2 = Discriminant2::Disc1; println!("{:?}", std::mem::discriminant(&d1)); // Value by enumerator. println!("{:?}", std::mem::discriminant(&d2)); // Value by constant. } Which makes the use of the enum keyword particularly bizarre given that there is no longer even an enumerator involved, but I suppose bizarre inconsistencies are par for the course in Rust.
- rcarmo 1y agoI wouldn't mind a well-maintained LISP/Scheme dialect that compiled to Go.
- Zambyte 1y agoDefinitely not well maintained, but it's interesting to see that something like that came out of SteelSeries: https://techblog.steelseries.com/golisp/index.html https://techblog.steelseries.com/golisp/index.html https://github.com/SteelSeries/golisp https://github.com/SteelSeries/golisp I wonder if they still use it.
- Luker88 1y agoI have been programming in Go for several years now and I agree, though I am not that sure even the rest of the ecosystem redeems it that much. On the other hand, the programming languages used by LLM people seem to be python and javascript mainly. So while I argue that they all should really move on to modern languages, I think go is still better than the I-can't-even-install-this mess of python and javascript imports without even a Dockerfile that seem to be so prevalent in LLM projects.
- 9rx 1y agoTo be fair, it is unlikely that Go would have a static type system at all if they had figured out how to achieve the performance expectations without. It was made abundantly clear that it is intended to be like a dynamically-typed language, but faster. Thinking of it as being a statically-typed language is a bit flawed, and shows a gross misunderstanding of what the language was created for. While you could try to argue that dynamically-typed languages in general are a poor fit for everything, the reality is that people there are typically using Python instead – and the best alternative suggestions beyond Go are Erlang and Elixer, which are also dynamically typed, so that idea doesn't work. Dynamic typing is what clearly fits the problem domain.