awalterschulze / goderive

Derives and generates mundane golang functions that you do not want to maintain yourself
Apache License 2.0
1.24k stars 43 forks source link

function with blank identifier #67

Closed jbl428 closed 3 years ago

jbl428 commented 3 years ago

Given the following test code

func TestCurryWithBlankIdentifier(t *testing.T) {
    f := func(a string, _ bool, c int) string {
        return fmt.Sprintf("%s%v%d", a, true, c)
    }
    curried := deriveCurryWithBlackIdentifier(f)
    want := `1atrue`
    got := curried("a")(false, 1)
    if got != want {
        t.Fatalf("got %s != want %s", got, want)
    }
}

goderive generates the following code

// deriveCurryWithBlackIdentifier returns a function that has one parameter, which corresponds to the input functions first parameter, and a result that is a function, which takes the rest of the parameters as input and finally returns the original input function's results.
func deriveCurryWithBlackIdentifier(f func(a string, _ bool, c int) string) func(a string) func(_ bool, c int) string {
    return func(a string) func(_ bool, c int) string {
        return func(_ bool, c int) string {
            return f(a, _, c)
        }
    }
}

It has compilation error.

./derived.gen.go:4430:12: cannot use _ as value

I think these plugins have this issue.

awalterschulze commented 3 years ago

Wow what a great catch. Hopefully this is only slightly tricky and relatively low effort to fix for someone.

jbl428 commented 3 years ago

@awalterschulze I have tried solve this issue. but there are multiple approach and i am not sure which one is best.

It would be nice if you could give me your opinion. 😄

jbl428 commented 3 years ago

Please ignore first one.

Because people can use generated code with multiple functions (with and without black identifier), first one is not a perfect solution.

awalterschulze commented 3 years ago

Yeah I kind of also wanted number 1 (Zero) to work, but I think you are right. I think number 2 is best: make random parameter name that does not conflict other parameters and replace blank identifier. We want the generated code to be as close as possible to handwritten code that is readable. So I think it is important to keep this random parameter name as short as possible, but this is also the reason to exclude option 3, because p0, p1, p2 is not what a human would probably write.

Maybe it would be nice to create a function that takes in a type signature for a function and returns the same function but with blank identifiers renamed. This way it is easier to test and most of the existing code can stay the same, except for also calling this function. What do you think?

jbl428 commented 3 years ago

I agree with keeping the handwritten code as much as possible. And maybe we can rename that blank identifier to meaningful one, not ugly random string.

I think it is good place to create the function you mentioned in derive/types.go What do you think?

awalterschulze commented 3 years ago

That could work or even better start a new file called params.go