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: Go2: must(): Improve code density for handling rare fatal errors #21419

Closed
kduda opened this issue Aug 12, 2017 · 9 comments
Closed
Labels
error-handling Language & library change proposals that are about error handling. FrozenDueToAge LanguageChange Proposal v2 A language change or incompatible library change
Milestone

Comments

@kduda
Copy link

kduda commented Aug 12, 2017

Instead of this:

numberString := // string that we know contains only digits
number, err := strconv.Atoi(numberString)
if err != nil {
	panic(err)
}
fmt.Printf("Your number times two is %d\n", 2*number)

I would like to write this:

numberString := // string that we know contains only digits
fmt.Printf("Your number times two is %d\n", 2*must(strconv.Atoi(numberString)))

The semantics of must() are: evaluate the single expression inside, which returns N values (N>=1); if the Nth value is non-nil, pass the Nth value to panic(); otherwise, return the first N-1 values.

must() is especially useful in unit tests, where I find a 25% of my code is error handling for errors that should really never happen, and if they did, panic() is fine.

must() is a built-in function like "append"; it can be re-declared in user code. Thus, introducing this function would not create backward compatibility issues.

must() is inspired by regexp.MustCompile.

Thanks,
-Ken

Kenneth Duda

@ianlancetaylor ianlancetaylor changed the title Go Enhancement Proposal: must(): Improve code density for handling rare fatal errors proposal: Go2: must(): Improve code density for handling rare fatal errors Aug 12, 2017
@gopherbot gopherbot added this to the Proposal milestone Aug 12, 2017
@ianlancetaylor ianlancetaylor added v2 A language change or incompatible library change LanguageChange and removed Proposal labels Aug 12, 2017
@mahdix
Copy link

mahdix commented Aug 24, 2017

What prevents you from writing this function in your code?
Why does it need to be part of built-in functions?

@bcmills
Copy link
Contributor

bcmills commented Sep 7, 2017

See also #20803 (comment).

@bronze1man
Copy link
Contributor

What prevents you from writing this function in your code?
Why does it need to be part of built-in functions?

Because, we can not write this function only with golang compiler. How to define that xxx.Must() function? we can not do that right now.
We can write another compiler that compile that code with must() and output golang source code, or we can just change golang compiler.

@tmthrgd
Copy link
Contributor

tmthrgd commented Nov 16, 2017

Wouldn't it be possible to write a must function exactly as described if Go gained generics?

@bronze1man
Copy link
Contributor

@tmthrgd
I have used the c#/java with some generics support.
I found that generics is not enough for this kind of problem.
generics can solve some problem
How do I write a function , and make it callable from another machine? How do I embed a png content in the finial binary memory, and serve it as a http response. How do I write a function that can works like golang builtin make? How do I write a function that can direct call some windows apis?
I think we need same simple way to program read and write golang code. May be some way to generate code on the fly and compile into the finial binary.

@tmthrgd
Copy link
Contributor

tmthrgd commented Nov 16, 2017

@bronze1man You could create a must function using generics something like this and it wouldn't require a language built-in:

func must<T>(arg T, err error) T {
	if err != nil {
		panic(err)
	}

	return arg
}

func must<T0, T1>(arg0 T0, arg1 T1, err error) (T0, T1) {
	if err != nil {
		panic(err)
	}

	return arg0, arg1
}

func must<T0, T1, T2>(arg0 T0, arg1 T1, arg2 T2, err error) (T0, T1, T2) {
	if err != nil {
		panic(err)
	}

	return arg0, arg1, arg2
}

// ... and so on ...
numberString := "0" // string that we know contains only digits
fmt.Printf("Your number times two is %d\n", 2*must(strconv.Atoi(numberString)))

@bronze1man
Copy link
Contributor

bronze1man commented Nov 16, 2017

@tmthrgd
This version of generics/override implement you said only solve little problems and make the language very complex. (For example, writing a tool that can read/write the language).I think this is the reason the golang writer do not want it.
I do not want it too. Because I need to change my tools (that can read/write the language) to accept the generics/override feature.
A lot of problem that generics need solved in java/c# have already been solved by go built stuff like map, reflect, unsafe.Pointer. And looks like those problems have been solved better(run faster).
But there are a lot problems that generics can not solve(like write a function , and make it callable from another machine). And tools that read/write the language can solve them.
So if golang support this version of generics.I may not upgrade to that version of golang in a long time.

I think I can write a function that can do compute at compile time, and output the right code base on input type, should be better solution to this kind of problem.

@creker
Copy link

creker commented Nov 16, 2017

@bronze1man

make it callable from another machine

What do you mean by that and how it relates to this proposal?

@ianlancetaylor
Copy link
Contributor

Closing in favor of #15292 (generics) and #21161 (error handling).

@golang golang locked and limited conversation to collaborators Mar 13, 2019
@bradfitz bradfitz added the error-handling Language & library change proposals that are about error handling. label Oct 29, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
error-handling Language & library change proposals that are about error handling. FrozenDueToAge LanguageChange Proposal v2 A language change or incompatible library change
Projects
None yet
Development

No branches or pull requests

9 participants