Thanks very much for taking a look at this Roger. I think your attempt differs from mine in that you don't make use of the future type F in implementing the waiting for the blocks of delayed futures, which means you don't have to deal with combining different instances of F (F[A], F[B] etc.). Also your delayed blocks don't wait for the preceding set of futures to be exhausted before proceeding, I think they're all triggered once the initial set is completed. I also remade use of AsCompleted, which was an extra complication, since I had the difficulty I mentioned regarding passing Fs of different types to it easily.
Now I've had more time to process it, I think my issue comes down to being unsure about how to easily/consistently perform mappings between generic types (like F[A] -> F[B]). A second thing that's not clear is how to handle the type F when I don't care about what type it's been instantiated with (say I wanted to retain the existing code, but I know that if F is in the original map[F[struct{}]struct{}] timeouts that it's a F[struct{}], otherwise it's F[T] (and I'm happy to type-assert at that point)). It's clearly not F[interface{}], for lack of better notation, I'll call it F[*]. On Wed, 2 Dec 2020 at 10:07, roger peppe <rogpe...@gmail.com> wrote: > And again (no need to make a cancelable context) > https://go2goplay.golang.org/p/3UFUaXijuX9 > > On Tue, 1 Dec 2020 at 22:59, roger peppe <rogpe...@gmail.com> wrote: > >> Slightly simpler again: https://go2goplay.golang.org/p/mKdishv4nhT >> >> On Tue, 1 Dec 2020 at 18:44, roger peppe <rogpe...@gmail.com> wrote: >> >>> I'm having difficulty understanding exactly what your code is trying to >>> do (and why), and that makes it hard to understand what >>> generic solution might be appropriate. >>> >>> However, here's one alternative implementation that doesn't seem to run >>> into the same kind of issues that you did. >>> It changes the contract a little bit, but it's still within the spirit, >>> I think and it's somewhat simpler: >>> >>> https://go2goplay.golang.org/p/cEWEUrvfZBl >>> >>> FWIW when I've implemented this kind of logic in the past, the aim is >>> usually to obtain at most one result. I don't really understand the use >>> case being implemented here. >>> >>> To address the actual question you raised: >>> >>> I ran into the situation where I need to "map" the futures of type >>>> *F[int], and *F[T] to *F[timeoutOrResult[T]]. >>> >>> >>> There's no reason why interface types won't still play a large role in >>> the future where Go has generics, and that's >>> how I'd probably represent timeoutOrResult there, with a dynamic type >>> switch to decide which one you've got. >>> >>> cheers, >>> rog. >>> >>> On Mon, 30 Nov 2020 at 02:09, Matt Joiner <anacro...@gmail.com> wrote: >>> >>>> I had a muck around with go2 generics with my toy-ish futures package >>>> https://github.com/anacrolix/futures. The go1 implementation is in >>>> master, and a working go2 implementation in the go2 branch (using channels >>>> of different types instead of the attempt that follows). The package >>>> provides one function AsCompletedDelayed, that allows to favour futures >>>> over others with timeouts. The timeouts are implemented using the future >>>> type *F[int], where as the futures the user provides as arguments are >>>> *F[T]. In the implementation for AsCompletedDelayed I need to pass both >>>> types of futures to another function AsCompleted[T](fs ...*F[T]) <-chan >>>> *F[T], then differentiate them when they're returned: I could get back a >>>> "timeout" future, or a user/argument future. To do this I created another >>>> type timeoutOrResult[T] struct { timeout bool; timeoutIndex int; result T >>>> }, however now I ran into the situation where I need to "map" the futures >>>> of type *F[int], and *F[T] to *F[timeoutOrResult[T]]. This seems >>>> non-trivial: I believe in another language I would make F a Functor, and >>>> map the timeouts to something like `Either int T`. It is possible to write >>>> an Fmap on my *F type, but now I need to create new types, and break out an >>>> interface, and the implementation quickly increases in complexity. >>>> >>>> This seems like a situation where the go1 style of doing this was >>>> easier albeit without enforcing the result types of the futures in the >>>> return chan for AsCompleted and AsCompletedDelayed: I could pass arbitrary >>>> *Fs to AsCompleted, and then compare the returning *F against a >>>> map[*F]struct{} that tracked which ones were timeouts. >>>> >>>> -- >>>> You received this message because you are subscribed to the Google >>>> Groups "golang-nuts" group. >>>> To unsubscribe from this group and stop receiving emails from it, send >>>> an email to golang-nuts+unsubscr...@googlegroups.com. >>>> To view this discussion on the web visit >>>> https://groups.google.com/d/msgid/golang-nuts/adb04bb6-bdda-41a9-a168-2541dd912171n%40googlegroups.com >>>> <https://groups.google.com/d/msgid/golang-nuts/adb04bb6-bdda-41a9-a168-2541dd912171n%40googlegroups.com?utm_medium=email&utm_source=footer> >>>> . >>>> >>> -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/CAB4yi1N9vaw1QNAYJ5tPupnZ9hUZd0QiXtK7Boy14F0e%2BrtsgA%40mail.gmail.com.