News for hackers. Stuff that matters.
Re:Functional Programming in Go with Generics by mappu on Thursday May 27, 2021 @01:48AM (#27299797)
Piling on here - My impression of your snippet here is that GroupBy() and Values() both construct (potentially very large) temporary arrays on the stack.

Maybe Haskell and F# can elide this kind of thing, but it's not something the Go compiler is going to do.

Re:Functional Programming in Go with Generics by Yoric on Thursday May 27, 2021 @02:17AM (#27299954)
Rust and OCaml (the latter if you use the right libraries) can definitely avoid it. Why couldn't Go?
Re:Functional Programming in Go with Generics by skjfdoslifjeifj on Thursday May 27, 2021 @12:52PM (#27305173)
The standard Ocaml compiler doesn't elide it and as far as I'm aware neither do any of the publicly available libraries. All of the lazy stream implementations in Ocaml have a performance cost similar to Java streams. Haskell and Rust are relatively unique in that they can completely eliminate the performance cost in the typical cases.
Re:Functional Programming in Go with Generics by mappu on Thursday May 27, 2021 @03:13AM (#27300271)
An alternate-universe Go with a lot more (& slower) compiler passes could do it, but I don't believe there are any plans to build such a thing. As it stands, this kind of code (where all intermediates have type []T) will run much more poorly than you could do with imperative loops.

The final generics design is probably not expressive enough to do it ergonomically in user code neither (building something where the intermediates are a library type with a last `.something()` call to collect a final []T).

Re:Functional Programming in Go with Generics by pjmlp on Thursday May 27, 2021 @05:42AM (#27300974)
OCaml compiles as fast Go.

No secret sauce, just having the pleasure of chosing multiple backends, including an interpreter.

Bytecode runtime during workflow, optimized native AOT for release and final production tests.

Re:Functional Programming in Go with Generics by duped on Thursday May 27, 2021 @10:13AM (#27303389)
That's just bad design - iterators and sequences need to be lazy. The intermediary type should not eagerly create large arrays on the stack, it should only ever do real work once the iterator has been driven.
Re:Functional Programming in Go with Generics by rad_gruchalski on Thursday May 27, 2021 @11:01AM (#27303948)
No, they don’t need to be. They can be. Go wasn’t designed as a functional language but to be fast to compile, fast to execute, zero dependency binary and simple syntax. It achieved that by a mile.
Re:Functional Programming in Go with Generics by duped on Thursday May 27, 2021 @12:23PM (#27304857)
Implementing iterator combinators by eagerly evaluating them into temporaries is a bad, naïve design that results in the issue illustrated above.

A much better design is to do it lazily which is possible if you can store closures as fields of a data structure.

Not sure what fast compilation and execution or dependencies has to do with this. Implementing iterators that way is the worst possible solution that results in slow execution that can blow up the stack and crash a program. It would be better not to have iterators at all than to require them to be eagerly evaluated.

You can support functional features without being a Haskell...

Re:Functional Programming in Go with Generics by rad_gruchalski on Thursday May 27, 2021 @01:55PM (#27306018)
Yes, lots of science. Go has slices which require specifying a size and you iterate over them using a for statement. You want lazy, pop in a channel and do it lazy.
Re:Functional Programming in Go with Generics by duped on Thursday May 27, 2021 @03:02PM (#27306789)
This isn't "lots of science" it's rudimentary software engineering...

Sending data through channels just to implement an iterator seems insane. It's not strictly lazy either...

Why do go developers reject simple patterns that make faster code?

Re:Functional Programming in Go with Generics by rad_gruchalski on Thursday May 27, 2021 @03:54PM (#27307431)
How are those magical lazy operations implemented in other languages? Someone had to take that insane step. It’s just not by default in go.

Look, I’ve written lots of scala and erlang so I get your argument. It just does not exist in go. And that’s okay.

Never got caught thinking “gee, need a lazy collection”. Maybe a stream when reading stuff from the ether. In go, channel was enough. 5 minute job. Nothing insane.

Re:Functional Programming in Go with Generics by duped on Thursday May 27, 2021 @05:18PM (#27308683)
They're implemented with closures, not passing things through FIFOs. It's not magic. You barely need a compiler pass to implement the sugar for `for` loops: it's a trivial transformation to a `while`.
Re:Functional Programming in Go with Generics by rad_gruchalski on Thursday May 27, 2021 @06:10PM (#27309206)
Okay, but what’s the benefit for go. I can iterate over slices, maps and channels (for ... range). Slices must have a capacity defined. What’s the benefit of lazy iterator?

for over a channel is in essence lazy. Channel stores the data as a linked list. So what’s the benefit.

Re:Functional Programming in Go with Generics by duped on Thursday May 27, 2021 @07:36PM (#27309957)
The benefit of generic iterators or implementing iterators lazily? The benefit of generic iterators is that they make SOLID programs easy to write, especially when converting data. It makes any kind of data ingest or hand rolled parsing/semantic analysis easy to write, read, and hard to screw up - which is 90% of business logic.

Lazy evaluation is the only reasonable way to implement iterators so you don't have to pay the costs of intermediate data structures or sending data over channels. Insertion into a data structure isn't free. Function composition is.

Re:Functional Programming in Go with Generics by skybrian on Thursday May 27, 2021 @12:20PM (#27304827)
That’s probably okay if the code is I/O bound anyway, but in Go it will run a lot slower than doing multiple steps within a single for loop.

For loops may be unfashionable but they aren’t hard to read.

Re:Functional Programming in Go with Generics by duped on Thursday May 27, 2021 @03:04PM (#27306807)
I don't find iterator combinations hard to read. Especially with postfix methods.

I do find deeply nested for loops with outer variables that might start uninitialized or need to be mutable much more difficult to read.

Re:Functional Programming in Go with Generics by skybrian on Thursday May 27, 2021 @04:04PM (#27307598)
Sometimes moving an inner for loop to a separate function (that will likely be inlined) is better to explicitly show its inputs and outputs.
Re:Functional Programming in Go with Generics by mappu on Thursday May 27, 2021 @09:10PM (#27310659)
I agree they need to be lazy. This is why it's problematic - Go is only adding generics and not laziness.
Re:Functional Programming in Go with Generics by wrnr on Thursday May 27, 2021 @02:27AM (#27300016)
I've been waiting to do things like that in Go for a long time. It can be done efficiently just like the Java Stream interface.
Re:Functional Programming in Go with Generics by Serow225 on Thursday May 27, 2021 @10:34AM (#27303642)
FWIW C# would as well (LINQ)