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: allow to use return statement with function's call uniformly. #39225

Closed
goofinator opened this issue May 23, 2020 · 3 comments
Closed

proposal: allow to use return statement with function's call uniformly. #39225

goofinator opened this issue May 23, 2020 · 3 comments
Labels
Milestone

Comments

@goofinator
Copy link

@goofinator goofinator commented May 23, 2020

Proposal:

I suggest that you allow using the expression of the return f() type in a single way, no mater if the function returns value or not.

History

In accordance with the https://golang.org/ref/spec#Return_statements,:

In a function without a result type, a "return" statement must not specify any result values.

It makes impossible to use following syntax:

func f() {
}

func main() {
	return f()
}

and produces the error:

./prog.go:7:2: too many arguments to return
./prog.go:7:10: f() used as value

In the same time, with functions that returns values, it's allowed:

func f() int {
	return 5
}

func fCaller() int {
	return f()
}

func main() {
	f()
}

Changes

I suggest to modify the specification:

In a function without a result type, a "return" statement must not specify any result values or functions that returns values.

Rationale

  1. The uniform syntax, without special cases, is simpler to read and follow.
  2. Described situation can be found within http handlers. Let's consider the example:
func (c controller) Handle(w http.ResponseWriter, r *http.Request) {
	data := context.Get(r, binders.SomeDataKey).(model.SomeData)

	result, err := c.service.Process(data)
	if err == services.ErrBadData {
		http.Error(w, err.Error(), http.StatusBadRequest)
		return
	}
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

        // The positive workflow 
}

With suggested changes, this code could be shortened to:

func (c controller) Handle(w http.ResponseWriter, r *http.Request) {
	data := context.Get(r, binders.SomeDataKey).(model.SomeData)

	result, err := c.service.Process(data)
	if err == services.ErrBadData {
		return http.Error(w, err.Error(), http.StatusBadRequest)
	}
	if err != nil {
		return http.Error(w, err.Error(), http.StatusInternalServerError)
	}

        // The positive workflow 
}

It will allow to reduce the number of lines with error check slightly and decrease the verbosity of code.

@gopherbot gopherbot added this to the Proposal milestone May 23, 2020
@gopherbot gopherbot added the Proposal label May 23, 2020
@mvdan
Copy link
Member

@mvdan mvdan commented May 23, 2020

While I see the intent is to reduce verbosity, I don't think this would be a good change to make. return <expr> has always meant actually returning at least one value, and developers and tools are used to that.

I think you should look at https://go.googlesource.com/proposal/+/master/design/go2draft-error-handling-overview.md.

@ALTree
Copy link
Member

@ALTree ALTree commented May 23, 2020

Note that this was rejected in the past: #10200 (see final comment from gri).

@goofinator
Copy link
Author

@goofinator goofinator commented May 23, 2020

Note that this was rejected in the past: #10200 (see final comment from gri).

Sorry, i didn't find it. Yes, the case of function without the arguments shows, that it's a natural born special case, not the artificial as i was thinking.

@goofinator goofinator closed this May 23, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
4 participants
You can’t perform that action at this time.