4 ms·
> iterators can be easily implemented with current Go features. It's rare that can is relevant when it comes to language design. You typically can do anything
by Mawr 3y ago
> iterators can be easily implemented with current Go features.
It's rare that can is relevant when it comes to language design. You typically can do anything in any language.
Adding dedicated support for iterators would promote it as the way to iterate. That would actually simplify the language - one way to express a common need as opposed to the current mess of ~5 different ways [1]:
"In the standard library alone, we have archive/tar.Reader.Next, bufio.Reader.ReadByte, bufio.Scanner.Scan, container/ring.Ring.Do, database/sql.Rows, expvar.Do, flag.Visit, go/token.FileSet.Iterate, path/filepath.Walk, go/token.FileSet.Iterate, runtime.Frames.Next, and sync.Map.Range, hardly any of which agree on the exact details of iteration. Even the functions that agree on the signature don’t always agree about the semantics."
Go would have been a far simpler language had it originally shipped with generics, iterators, and sum types.
[1] https://github.com/golang/go/discussions/56413 https://github.com/golang/go/discussions/56413
- imiric 3y agoI agree with you to an extent. But adding more features is always a tradeoff between introducing complexity, and supporting a use case that might not be useful in all programs. For example, generics were a highly controversial topic, and many people still believe that Go didn't need them. I'm partially in that camp. I've encountered maybe one or two situations where generics would've been convenient since Go 1.18, and in both cases not jumping straight at the opportunity to use them, but being forced to refactor and approach the solution in a different way, has produced simpler and more readable code. To this day, I struggle with Go's generics syntax, and it just looks alien to me. Iterators are a useful feature, but are they really generally useful to deserve a change in the language spec? Like generics, I've yet to encounter a situation where they're truly required, and when I do, implementing them myself is trivial. So, sure, language designers can cram every programming construct we've invented in the last 50 years, as Rust and Raku have done, and many programmers will find this very convenient and flexible, but a more focused and conservative approach produces a simpler language that is easy to pickup and read. This is what drew me to Go in the first place, and lately it seems that this is changing.
- deleted 3y ago[deleted]
- Loic 3y agoGenerics very nice as a library writer but in my own application code, I usually have no uses of them. You have language features which are not needed for the ones using directly (for the lack of better term) the language and but really nice for the people providing building blocks for them. I am using generics in other languages than Go but not in Go as I am normally not writing libraries in Go or they are already so specific that generics are not needed.
- int_19h 3y agoIterators have been around for literally decades at this point, and have proven their usefulness in every language they've been introduced in (just like generics). It's not some kind of experimental feature.
- ilyt 3y ago> Adding dedicated support for iterators would promote it as the way to iterate. That would actually simplify the language - one way to express a common need as opposed to the current mess of ~5 different ways [1]: There is one. Return a channel. Just a bit iffy when you want to stop iteration in the middle and throw away the rest.
- aziis98 3y agoReturning a channel is not really a cheap operation. They internally have locks that slow everything down as they are intended mostly as a safe concurrency primitive And in this case there is really no need to spawn goroutines to support iterators
- masklinn 3y ago> Go would have been a far simpler language had it originally shipped with generics, iterators, and sum types. You forgot tuples.
- rollcat 3y agoFirst-class tuples would make this code kind of unpleasant: func F() (A, B) { ... } func G(a A, b B) { ... } G(F()) Is the return value of F a tuple? Is the parameter list of G a tuple? Given H: func H(ab (A, B)) { ... } How and when is H(F()) different from G(F())? (Before you suggest a Python-like star operator, personally I consider using it for non-homogenous arguments about as hygienic as keeping your toothbrush and dirty socks in the same drawer.)
- masklinn 3y ago> First-class tuples would make this code kind of unpleasant: Which assumes this code matters much, outside of errors for which intermediate processors can just take... a tuple of a value and an error. Also assumes the magical splatting of MRVs is a good thing in the first place. > (Before you suggest a Python-like star operator, personally I consider using it for non-homogenous arguments about as hygienic as keeping your toothbrush and dirty socks in the same drawer.) That is literally what Go currently does for MRVs, except opt-in instead of magical. There is nothing about such splatting which wouldn't work with proper tuples, if anything it's the opposite. It is, essentially, the value side of `uncurry`.
- rollcat 3y agoI don't necessarily disagree, but it depends on your goals as a language designer. I think it's OK to sacrifice a niche feature for improved readability in the common case. Anonymous structs are not as fundamentally useful as e.g. anonymous functions. > Also assumes the magical splatting of MRVs is a good thing in the first place. IMHO, G(F()) reads nicer than some variant of G(*F()) or G(F()...). Lua does this too, and is (not unlike Go) considered a simple and elegant language. > Which assumes this code matters much, outside of errors for which intermediate processors can just take... a tuple of a value and an error. Then you'll sooner or later find yourself writing a G((a, b)), which again, I think is a net loss to readability. I think my argument would've been much stronger if Go had had generics in 1.0, and the stdlib/ecosystem wasn't already full of MustParse's and MustCompile's. But in that case we could've had a Result type as well.