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: spec: drop new(int) in favor of &int{} #20446

Closed
alercah opened this issue May 22, 2017 · 9 comments
Closed

proposal: spec: drop new(int) in favor of &int{} #20446

alercah opened this issue May 22, 2017 · 9 comments
Labels
FrozenDueToAge LanguageChange Proposal v2 A language change or incompatible library change
Milestone

Comments

@alercah
Copy link

alercah commented May 22, 2017

This is sort of spawning out of #19642, and may be related to its resolution.

Currently, struct types (and, less commonly, array, slice, and map types) can have a pointer to a zero value constructed in two different ways: new(T) and &T{}. I've never seen a style guide recommending one or the other, but the latter is more clear next to &T{foo}.

Having two ways to do something isn't ideal, so one potential solution is to allow composite literals for all types (with one possible exception I'll get to). For any type for which Go 1 does not allow composite literals (numeric, boolean, function, interface, channel, and pointer types), the literal must be empty and yields the zero value. So instead of writing new(int), you would write &int{}.

If this is done, the new builtin becomes redundant. We can therefore remove it from the language to simplify. I'm not sure this is necessarily a good idea, but it would remove the duplication.

The only issue is pointer types. Under this proposal, I think that *T{} is ambiguous between "a pointer to a zero T" and "a nil pointer to T" (I frequently mistype *T{} for &T{}). I'm not sure the best resolution for this.

@gopherbot gopherbot added this to the Proposal milestone May 22, 2017
@mvdan mvdan added v2 A language change or incompatible library change LanguageChange labels May 22, 2017
@bcmills
Copy link
Contributor

bcmills commented May 22, 2017

This version would mesh a little better with #12854, too.

@ianlancetaylor
Copy link
Contributor

You seem to be suggesting that we permit &T{} for any type, while still permitting &T{V} where T is an aggregate type. I'm not sure that buys us much. If we were starting from scratch it might be worth discussing, but given that we have new, we need a significant benefit to providing another way to write new.

@alercah
Copy link
Author

alercah commented May 23, 2017

That's correct, but it is also a suggestion to get rid of new altogether, because of the redundancy.

It may be a comparatively low-value feature, but it's one that I wanted to put forward especially in connection with other proposals relating to compound literals and zero values.

@ianlancetaylor
Copy link
Contributor

But getting rid of new altogether is not backward compatible, so now you need a really big benefit.

Every change to the language has benefits and drawbacks. Eliminating new has a huge drawback: existing code stops working. It needs a correspondingly huge benefit.

To put it another way: Go is now an existing working language that people are actively using. It's not a playground for language design. Breaking existing users is pretty much a non-starter.

@andlabs
Copy link
Contributor

andlabs commented Jun 7, 2017

Also you are implying that having two ways of accomplishing something is a problem that needs to be solved — that we should avoid that at all costs. But we can reduce this line of thinking to absurd levels: do we get rid of arrays and slices because we have maps?

And even after it makes sense, the "is it worth it" test still doesn't really pass or fail by that much: removing new would be a minimal-effort change that doesn't affect Go's internals that much, so the mere act of making that change doesn't itself justify the change. Ergo, there needs to be stronger motivation than just "having two ways of doing things isn't ideal". (An example of a breaking change whose very change justifies itself would be bumping minimum supported versions of various flavors of BSD to avoid the signal-routing issues that plague the Go runtime, since Go would no longer need to worry about that, and it can get rid of complicated code that takes time away from your code to run. I'm probably not articulating this well; an actual runtime engineer would need to come up with a better analogy. For my own projects, it would be dropping Windows XP to gain advantage of higher-quality drawing APIs and better GUI primitives.)

In fact, I can think of a point against it, given Go 1 rules: In order for this proposal to make sense, we would need to expand the composite literal syntax to all types, so we can say int{5}, float64{3.2}, etc. But what about chan? Do function bodies count as composite initializers?

@rsc rsc changed the title proposal: Go 2: Replace the 'new' builtin with composite zero literals for all types proposal: spec: drop new(int) in favor of &int{} Jun 16, 2017
@ghasemloo
Copy link

I am not sure the proposal covers all use cases of new, e.g. if the type to be allocated is determined at the run time. Without it we would have to use reflection and recursion to do so, and in addition the code would break if new builtin types are added to the language.

@bcmills
Copy link
Contributor

bcmills commented Jul 11, 2017

@ghasemloo The existing new operator only supports static types. To the extent that the situation you describe is a problem, it is already a problem today.

@ianlancetaylor
Copy link
Contributor

Related to #9097.

@ianlancetaylor
Copy link
Contributor

This is basically the same idea as #9097. Closing in favor of the earlier issue.

@golang golang locked and limited conversation to collaborators Feb 13, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
FrozenDueToAge LanguageChange Proposal v2 A language change or incompatible library change
Projects
None yet
Development

No branches or pull requests

7 participants