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.
This version would mesh a little better with https://github.com/golang/go/issues/12854, too.
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.
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.
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.
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?
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.
@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.
Related to #9097.
This is basically the same idea as #9097. Closing in favor of the earlier issue.
Most helpful comment
But getting rid of
newaltogether is not backward compatible, so now you need a really big benefit.Every change to the language has benefits and drawbacks. Eliminating
newhas 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.