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

proposal: Go 2: specify default value in named return signature #31266

Closed
marcusljx opened this issue Apr 5, 2019 · 7 comments
Closed

proposal: Go 2: specify default value in named return signature #31266

marcusljx opened this issue Apr 5, 2019 · 7 comments
Labels
FrozenDueToAge LanguageChange Suggested changes to the Go language Proposal v2 An incompatible library change
Milestone

Comments

@marcusljx
Copy link

Background

Currently go has the following syntax for named returns:

func MyFunc(x int) (result int) {
   ...
}

Proposal

I would like to propose that we add syntax for specifying the default value in the named return:

func MyFunc(x int) (result int = 42) {
    ...
}

Essentially, this proposal is for syntactic sugar in place of a var defaultValue ReturnType = value, which I believe will allow for some code cleanliness.

Use Case

The proposed signature would make the function equivalent to the current implementation, but replacing the zero-value at compile-time.

func MyFunc(x int) int {
    if ... { // some guard clause
        return 42
    }
    if ... { // another guard clause
        return 42
    }
    ...

    if ... { // yet another guard clause
        return 42
    }
}

There are other useful cases as well, such as returning the input arguments by default.

// MyFunc .... needless to say, if some condition is not met, the result is the same as the input.
func MyFunc(x int) (result int = x) {

}

Interfacing

The named returned should not affect its function signature, ie. the following functions are all signature-equivalent

func MyFunc(x int) (result int = 4) {}
func MyFunc1(x int) (result int) {}
func MyFunc2(x int) int {}

Also, the equality for interface values should follow the standard go syntax

type InterfaceA interface {
  Do()
}

type SomeValue struct {}
func (s *SomeValue) Do() {}

func DoSomething(x int) (result InterfaceA = &SomeValue{value: 123}) {
    ...
}

Comments

I believe that having a default value specified at compile-time is a useful construct, and saves 1 operation of declaring a default result value, like so:

func MyFunc(x int) int {
    defaultValue := 42
    // use it in all guard clauses
}

Of course this can already be done by duplicating them inline during the return statement, such as this example:

func MyFunc2(x int) *MyType {
    if ... {
        return &MyType{Value: 42}
    }
    if ... {
        return &MyType{Value: 42}
    }
    if ... {
        return &MyType{Value: 42}
    }
    if ... {
        return &MyType{Value: 42}
    }

    ....
}

but it seems that it would look a lot cleaner like this:

func MyFunc2(x int) (result *MyType = &MyType{Value: 42}) {
    if ... {
        return
    }
    if ... {
        return
    }
    if ... {
        return
    }
    if ... {
        return
    }

    ....
}
@gopherbot gopherbot added this to the Proposal milestone Apr 5, 2019
@ianlancetaylor
Copy link
Member

ianlancetaylor commented Apr 5, 2019

What is the difference between

func MyFunc(x int) (result int = 42) {
    ...
}

and

func MyFunc(x int) (result int) {
    result = 42
    ...
}

They seem essentially the same to me.

@ianlancetaylor ianlancetaylor changed the title proposal: syntax: specify default value in named return signature proposal: Go 2: specify default value in named return signature Apr 5, 2019
@ianlancetaylor ianlancetaylor added v2 An incompatible library change LanguageChange Suggested changes to the Go language labels Apr 5, 2019
@marcusljx
Copy link
Author

Wouldn't it be clearer to the users what the expected default will be?

@zigo101
Copy link

zigo101 commented Apr 5, 2019

Default parameters do matter, but have default results any meaningfulness?

@DylanMeeus
Copy link

Even though I like default input params, I feel like default output parameters are definitely less useful.
Because upon reading the signature:

func myFunc(x int) (result int = 42) {..}

You'd still need to read the entire method and verify that the result was not changed within the body.

func myFunc(x int) (result int = 42) {
      if someVariable {
            result = -42
      }
      // lots of code
      return
}

So the only possible use I can see is for removing one line in guard statements (like @ianlancetaylor wrote). But I feel like there is a general risk of making code more obscure.

Default inputs are useful because you can guarantee the method has at least variables with certain parameters, and can help with avoiding some guards by providing sane defaults. I feel like the same can not be said for this proposal :)

@marcusljx
Copy link
Author

Okay. I learned a lot from the feedback. Thank you very much! I'll close this proposal then. Is there already a proposal for default inputs as you mentioned @DylanMeeus?

@zigo101
Copy link

zigo101 commented Apr 5, 2019

It is rejected: #21909

@marcusljx
Copy link
Author

I see.. Thanks!

@golang golang locked and limited conversation to collaborators Apr 4, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
FrozenDueToAge LanguageChange Suggested changes to the Go language Proposal v2 An incompatible library change
Projects
None yet
Development

No branches or pull requests

5 participants