Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for generics #250

Open
tdakkota opened this issue Jun 26, 2020 · 11 comments
Open

Support for generics #250

tdakkota opened this issue Jun 26, 2020 · 11 comments
Labels
experimental Experimental work. v3 RxGo v3.

Comments

@tdakkota
Copy link

Experimental go2go translator is published!
https://blog.golang.org/generics-next-step

@teivah
Copy link
Member

teivah commented Jun 26, 2020

Hey @tdakkota,
Thanks for creating the issue. For information, I started to work on it on the generics branch but I didn't finish yet. It's really a heavy change and so far the compiler is sometimes panicking without providing useful information so it's not simple.
Anyone who's willing to give it a try can start working from generics (or your own branch, whatever works).

@teivah teivah changed the title Support dev.go2go branch with generics Support for generics Jun 26, 2020
@teivah teivah added version 2 RxGo v2. experimental Experimental work. labels Jun 26, 2020
@teivah teivah added v3 RxGo v3. and removed version 2 RxGo v2. labels Apr 7, 2021
@czras
Copy link

czras commented Feb 13, 2022

With the upcoming 1.18 go release would this issue pick up some steam?

@manisenkov
Copy link

manisenkov commented Mar 13, 2022

I think because of lacking of parameterized methods in the current state of generics it would be impossible to migrate this project without major change of API.

@aak1247
Copy link

aak1247 commented Mar 29, 2022

@manisenkov But still helpful

@evanmoran
Copy link

I suspect if generics improve the API we'd very much be fine with a breaking API change. Any thoughts on if the current generics Go feature would be enough to make things easier to use?

@manisenkov
Copy link

RxGo is pretty much based on fluent interface (observable.Filter(...).Map(...)) and without type parameters in methods it wouldn't be possible to implement.

The one way is to switch to non-fluent API but it would be not as easy to read

Map(Filter(observable, filterFn), mapFn)

or

ob1 := Filter(observable, filterFn)
ob2 := Map(ob1, filterFn)

(here is an issue for adding type parameters)

@simake2017
Copy link

when can finish it

@ianldgs
Copy link

ianldgs commented Jul 4, 2022

Would it be helpful to take inspiration from RxJs and use a pipe function with operators also as functions?

Pipe(
  observable,
  Filter(fn),
  Map(fn),
  Reduce(fn)
)

@manisenkov
Copy link

Would it be helpful to take inspiration from RxJs and use a pipe function with operators also as functions?

Pipe(
  observable,
  Filter(fn),
  Map(fn),
  Reduce(fn)
)

I thought about it, but generics in Go doesn't support variadic number of type arguments. Some kind of solution would be if you have multiple variance for Pipe function for different number of arguments

Pipe2(
  observable,
  Filter(fn)
)

Pipe3(
  observable,
  Filter(fn),
  Map(fn),
)

Pipe4(
  observable,
  Filter(fn),
  Map(fn),
  Reduce(fn),
)

// etc...

@ianldgs
Copy link

ianldgs commented Aug 8, 2022

An example of what the above could look like: https://go.dev/play/p/AJwmCH2iIA-

@si3nloong si3nloong mentioned this issue Aug 27, 2022
8 tasks
@si3nloong si3nloong linked a pull request Aug 27, 2022 that will close this issue
8 tasks
@plastikfan
Copy link

plastikfan commented Apr 15, 2024

If anyone is interested, I have created a new version of RxGO - lorax (RxGo with generics) that is implemented using generics, but maintains the existing interface (ie it is still fluent). It is still under construction, but most of it is implemented and working. At some point, I intend to work through the item list defined here in RxGO and fix those issues, if there is interest. There are some caveats though:

  • I prefer to use an alternative test runner and matching library rather than use Testify as most projects use. I use ginkgo and gomega which together I believe provides a much richer dev ex. The Assert api is still the same, excepts that it uses gomega matchers behind the scenes. After having looked through the implementation of rx.Assert, I decided to re-write it, so the rx matchers are different to the originals.
  • My focus on the new fucntionality has been to implement the features I need for my own projects. There are some major features that have not been implemened yet, since I currently have no use for them. However, if there is interest, I will be more than happy to complete them. This set includes: Debounce, BufferXXX, Map, ToMap and Marshal/Unmarshal, everyting else has been implemented and works the same as the original.

The heart of the new generic based funcationality was to introduce a new opaque field defined as any to Item[T]:

	Item[T any] struct {
		V    T
		E    error
		aux  any
		disc enums.ItemDiscriminator
	}

All channels are strongly typed to Item. Whenever an auxilary value needs to be send thru the channel, an auxilary item can be created (Num in the example below), eg the Range factory iterates using an int based index, which needs to be sent via a channel. Since the channel can only send Item[T], the Range function creates an aux value (via newRangeIterable), carrying the integer value:

		for idx := i.start; idx <= i.start+i.count-1; idx++ {
			select {
			case <-ctx.Done():
				return
			case next <- Num[T](idx):
			}
		}

This is only meant as a stop gap project, just waiting for rxgo V3, but since that doesnt seem to be forth-coming, this stop gap looks to becoming more permanent than I intended.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
experimental Experimental work. v3 RxGo v3.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

9 participants