On Wed, Sep 11, 2013 at 5:29 PM, Fumin Wang <awaw...@gmail.com> wrote:
> However, `new` is an exception to such
> elegant and comprehensive thought, as it not only creates confusion for
> people that come from other languages that have "new",
Not true, IMO. Pascal has 'new' and people coming from Pascal can
hardly be confused as it works exactly the same in Pascal and Go.
> but also is redundant
> and can be replaced by either "&T{}"
Not true, IMO. "&int{}" doesn't work.
-j
Any reasons why not go for this proposal?
There is another fundamental difference. new returns a pointer to a
valid Go type. make allocates something which is not representable by
a Go type.
Sort of true, but a somewhat arbitrary distinction.
Slices are more similar to pointers than they are to maps.
I don't think there's any strong argument that either new(T) or make(*T) is fundamentally right or wrong, so it really comes down to a design decision that has already been made.
I don't think it's particularly useful to pretend that the particular choice that was made here is the One True Way. In fact, this approach tends to get language communities blacklisted in a lot of people's books if it's too widespread.
Note that the above cannot be replaced by
var v0 = T{whatever}
v = &v0
As that is a static instance ('v0') only. For run time determined
number of instances, 'new', the underlying one in &T{}, is inevitable.
It's not arbitrary. It's one of the fundamental distinctions between make and new. That's Rémy's point.
That's not true. Map, slice, and channel types have more in common with each other than with pointers. That's why they are all associated with the make function.
The whole point of Go is to forbid pointer arithmetic. Why would you
unify pointers and slices?
Rémy.
Additionally, there has been much discussion concerning the idea of arbitrarily addressable expressions, through implicit use of an implicit intermediate var. The idea does not involve large hidden costs, but thus far has perhaps suffered from lack justifiable usefulness (since part of its role is already fulfilled by new). Getting rid of new, for Go2, would make addressable expressions much more appealing. Examples:x := &int(3) // replaces `x := new(int); *x = 3`x := &3 // illegal: constants are not addressable.*&int(0) = 1 // compiler errors with "declared and not used", if not syntactically invalidIt would also have the benefit of making &T{} a non-special case.
This would have the unfortunate consequence of allowing people to accidentally write `T(x).F()` where they mean `(*T)(&x).F()`. I'm not sure how big of a deal this would be. I'd suggest pointer literals as an alternative (`(*T){5}`) instead, but this doesn't play well with type elision in slice and array literals (is `{x}` a pointer to a copy of `x`, or a pointer to a struct containing a copy of `x`?).
Generally speaking, in Go you can't do `(*T)(&x)` anyway, unless x is already a *T (e.g., unlike C, where you can get away with murder). That said, they can already accidentally write `T(x).F()` anyway. Furthermore, I can't see how addressable expressions would allow any of what you mentioned (beyond what is already allowed).