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

Add support for generics #44

Closed
paddycarver opened this issue Apr 28, 2022 · 7 comments · Fixed by #49
Closed

Add support for generics #44

paddycarver opened this issue Apr 28, 2022 · 7 comments · Fixed by #49

Comments

@paddycarver
Copy link
Contributor

With the release of Go 1.18, interface types can now have type constraints. It would be neat to be able to specify these type constraints when generating the implementation.

@josharian
Copy link
Owner

Maybe I'm missing something, but impl generates methods, and as of Go 1.18, there are no generic methods.

@paddycarver
Copy link
Contributor Author

paddycarver commented May 5, 2022

Sorry, this probably would've been more helpful with an example, huh?

type Parser[Result any] interface {
    Parse(in []byte) (Result, error)
}

That's valid in Go 1.18, but I can't use impl to generate an implementation of, say github.com/my/package.Parser[string]. You get interface Parser[string] not found: type Parser[string] not found in github.com/my/package.

I would expect it to generate (assuming it was run with s stringParser):

func (s stringParser) Parse(in []byte) (string, error) {
    panic("not implemented")
}

@josharian
Copy link
Owner

Ah! I see. So you'd also have to tell impl the intended type of Result.

I see the usefulness, although I'm a bit worried about the command line API. There can be an unlimited number of type parameters. Using order isn't a great API, but naming them gets awkward. At some point it'll be easier to write the implementation stubs by hand. :P

I'm not spending much time on impl at this point. If there's a path forward that is simple and clear, I'm happy to review it. If not, I will probably wait until popular demand grows larger. :)

@paddycarver
Copy link
Contributor Author

So I think my preferred way of invoking it would be to just attach the type parameter to the interface type. I don't use impl on the command line, I use it through vim-go, so what it would look like there is:

:GoImpl s stringParser github.com/my/package.Parser[string]

I don't know what the command line equivalent is, sadly. :(

But the above could read that it wants a string from the type parameter, and I think that's a semi-standard way to refer to type parameters? It matches how I'd declare a variable of that type with those parameters, at least: https://go.dev/play/p/XldKb_P2Uvp It was also my first instinct for how to go about doing that.

I haven't looked at impl's source, but would you be amenable to a PR for that functionality if I ever got around to implementing it? (Can't promise I will, but in case I get the time. 😄)

@josharian
Copy link
Owner

That works for me. I would review such a PR, with the caveat that my turnaround time is typically O(weeks) or even O(months). I'm not proud of that...just being honest.

@paddycarver
Copy link
Contributor Author

The transparency is appreciated and no judgment. Appreciate the willingness to look at it, if I (or someone else) can find the time and energy to put something together :)

paddycarver added a commit to paddycarver/impl that referenced this issue Dec 19, 2022
Update go.mod to indicate support for Go 1.19.

Add support for generic interfaces, i.e. interfaces that accept a type
parameter.

For example, you can now have this kind of interface:

```go
type Interface[Kind any] interface {
	DoTheThing() Kind
}
```

and if you run `impl 's StringImpl' 'Interface[string]` it will generate
the following code:

```go
func (s StringImpl) DoTheThing() string {
	// normal impl stub here
}
```

Fixes josharian#44.
@paddycarver
Copy link
Contributor Author

I've opened #49 with my implementation of this feature. I've added some test cases, but was unable to get a test case for a qualified interface working in an automated fashion; the full path worked, and the unqualifed interface worked, but the qualified one couldn't find the testdata package. I have verified it manually, though that's not ideal and it has only been tested with an interface that accepts two type parameters (that's all I had handy).

paddycarver added a commit to paddycarver/impl that referenced this issue Jan 2, 2023
Update go.mod to indicate support for Go 1.19.

Add support for generic interfaces, i.e. interfaces that accept a type
parameter.

For example, you can now have this kind of interface:

```go
type Interface[Kind any] interface {
	DoTheThing() Kind
}
```

and if you run `impl 's StringImpl' 'Interface[string]` it will generate
the following code:

```go
func (s StringImpl) DoTheThing() string {
	// normal impl stub here
}
```

Fixes josharian#44.
paddycarver added a commit to paddycarver/impl that referenced this issue Jan 16, 2024
Update go.mod to indicate support for Go 1.19.

Add support for generic interfaces, i.e. interfaces that accept a type
parameter.

For example, you can now have this kind of interface:

```go
type Interface[Kind any] interface {
	DoTheThing() Kind
}
```

and if you run `impl 's StringImpl' 'Interface[string]` it will generate
the following code:

```go
func (s StringImpl) DoTheThing() string {
	// normal impl stub here
}
```

Fixes josharian#44.
josharian added a commit that referenced this issue Jan 17, 2024
Add support for generic interfaces, i.e. interfaces that accept a type parameter.

For example, you can now have this kind of interface:

```go
type Interface[Kind any] interface {
	DoTheThing() Kind
}
```

and if you run `impl 's StringImpl' 'Interface[string]` it will generate
the following code:

```go
func (s StringImpl) DoTheThing() string {
	// normal impl stub here
}
```

Add a Type abstraction, make type parsing more robust.

Instead of parsing generic types using string manipulation, parse them using the go/parse package to get the AST.

Rather than passing around a type ID and its params everywhere, create a Type struct that contains both.

Fixes #44.

Co-authored-by: Josh Bleecher Snyder <josharian@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants