[generics] Fuzzer, Type Switches

178 views
Skip to first unread message

Josh Hoak

unread,
Jul 17, 2020, 3:36:38 PM7/17/20
to golang-nuts
I was playing around with trying to use generics to de-interface-ify a fuzzer implementation, and I ran into some stumbling blocks.

is it possible to perform type switches? It seems the answer is currently no (example, design doc reference). Maybe there's a better way to handle the following?

type Primitive interface {
  type int, string
}

func Randomize(type F Primitive)(f F, r *rand.Rand) F {
  switch v := (interface{})(f).(type) {
  case string:
    return fmt.Sprintf("%s--%d", v, r.Int())
  case int:
    return v + r.Int()
  default:
    panic(fmt.Sprintf("I don't know about type %T!\n", v))
  }
}

func main() {
  r := rand.New(rand.NewSource(1))
  fmt.Println(Randomize(int)(1, r))
}

Thanks,
Josh

Carla Pfaff

unread,
Jul 17, 2020, 3:45:27 PM7/17/20
to golang-nuts
Why not write two functions?

Ian Lance Taylor

unread,
Jul 17, 2020, 4:21:36 PM7/17/20
to Josh Hoak, golang-nuts
Yes, there currently is no way to switch on the underlying type of the
type argument, as discussed in the part of the design draft that you
link to.

Ian

ulu...@gmail.com

unread,
Jul 18, 2020, 6:43:52 PM7/18/20
to golang-nuts
This seems to work: https://go2goplay.golang.org/p/8veymwXYCoZ

Still uses interfaces internally.

Ian Lance Taylor

unread,
Jul 18, 2020, 9:01:02 PM7/18/20
to ulu...@gmail.com, golang-nuts
On Sat, Jul 18, 2020 at 3:43 PM <ulu...@gmail.com> wrote:
>
> This seems to work: https://go2goplay.golang.org/p/8veymwXYCoZ
>
> Still uses interfaces internally.

Compare that to https://go2goplay.golang.org/p/8U4h9flkhFN.

Ian

Steven Blenkinsop

unread,
Jul 18, 2020, 9:39:52 PM7/18/20
to Ian Lance Taylor, ulu...@gmail.com, golang-nuts


On Jul 18, 2020, at 9:00 PM, Ian Lance Taylor <ia...@golang.org> wrote:

Seems like this should work, but it doesn't:

The draft says:

Writing *T instead of T in a type parameter list changes two things. Let's assume that the type argument at the call site is A, and the constraint is Constraint (this syntax may be used without a constraint, but there is no reason to do so).

The first thing that changes is that Constraint is applied to *A rather than A. That is, *A must implement Constraint. It's OK if A implements Constraint, but the requirement is that *A implement it.


It appears the type constraint is being applied to int instead of *int here.

Jake Montgomery

unread,
Jul 19, 2020, 11:42:54 AM7/19/20
to golang-nuts
I'm confused. It panics when I run it now.

Steven Blenkinsop

unread,
Jul 19, 2020, 1:44:49 PM7/19/20
to Jake Montgomery, golang-nuts
On Sun, Jul 19, 2020 at 11:43 AM, Jake Montgomery <jake...@gmail.com> wrote:
 This seems to work: https://go2goplay.golang.org/p/8veymwXYCoZ

I'm confused. It panics when I run it now.

Since the outcome is probably cached, I'm not sure how that could be the case. Did you mean to respond to Ian's modified version?

On Jul 18, 2020, at 9:00 PM, Ian Lance Taylor <ia...@golang.org> wrote:
The point there is that the argument to the type parameter F is now MyInt instead of int. Since the underlying type is int, this satisfies the Primitive constraint on F. However, the switch in Randomize doesn't handle MyInt, so we hit the default case, which panics.

Jake Montgomery

unread,
Jul 20, 2020, 9:02:25 AM7/20/20
to golang-nuts


On Sunday, July 19, 2020 at 1:44:49 PM UTC-4, Steven Blenkinsop wrote:
On Sun, Jul 19, 2020 at 11:43 AM, Jake Montgomery <jake...@gmail.com> wrote:
 This seems to work: https://go2goplay.golang.org/p/8veymwXYCoZ

I'm confused. It panics when I run it now.

Since the outcome is probably cached, I'm not sure how that could be the case. Did you mean to respond to Ian's modified version?

They must have been working on the go2 playground. I'm sure it was your link, ending in Z, and it complained about MyInt and panicked:
panic: I don't know about type main.MyInt!
But now it works fine.
Reply all
Reply to author
Forward
0 new messages