Hacker News new | ask | show | jobs
by gngeal 4617 days ago
for- and with-statements over user-defined data types

Any reason why doing this with channels and goroutines doesn't fulfill your requirements?

1 comments

I don't need concurrency, and my app (which is a fairly simple "munge some data from backends, apply some algorithms, and template it" webapp) seems easier to reason about without introducing them.
I don't need concurrency

Except that you do. You've just said it yourself! What the for command does in Python is essentially running two communicating coroutines, passing control between them. Yield-using generators actually make it very explicit, by creating special resumable stack frames. The only difference is that in Go, you're not limited to a single stack frame in the producer, nor do you have to use a loop or the new PEP-380 "yield from" syntax (for example, if you're iterating over a tree). The blocking channel takes care of the execution sequencing. (Also, in Go, the channel makes it possible for the consumer to use multiple stack frames, if you're re-building another data structure instead with the data you receive from the producer, but that seems to be a rarer case. It's a nice symmetry, though.)

The Python equivalent of two communicating goroutines is a bidirectional generator (PEP 342), not a for-loop. I try to use the language construct with the least power.

Basically what I wanted this for is that I have a user-defined type that is basically a list of some other user-defined type, plus some extra stuff. In Python it's trivially easy to implement __iter__ and delegate, and then I could manipulate these objects the way I thought of them, as containers for other objects. In Go...I wonder if I could've used type embedding (making the first member of A be []B), but I don't think the built-in language constructs respect embedding when figuring out what's a legal expression. I ended up biting the bullet and explicitly looping over the slice member, but the point of prototyping is being able to think of your code in the terms of your problem domain.