81

I'm still puzzled as why we have new in Go.

When you want to instantiate a struct, you do

t := Thing{}

and you can get a pointer to a new instance by doing

t := &Thing{}

But there's also this possibility :

t := new(Thing)

This last one seems a little alien to the rest of the language. &Thing{} is as clear and concise as new(Thing) and it uses only constructs you often use elsewhere. It's also more extensible as you might change it to &Thing{3} or &Thing{Feets:7}.

In my opinion, having a supplementary keyword1 is costly, it makes the language more complex and adds to what you must know. And it might mask to newcomers what's behind instantiating a struct.

It also makes one more reserved word.

So what's the reasoning behind new ? Is it sometimes useful ? Should we use it ?


1 : Yes, I know it's not a keyword at the grammar level, you can shadow it, but that doesn't change the fact it's, for the reasonable developer, a reserved word.

Denys Séguret
  • 1,424
  • 1
  • 10
  • 14
  • legacy from java/C++? – ratchet freak Sep 04 '13 at 07:34
  • Probably. But does that sound as an error to have kept it only to me ? – Denys Séguret Sep 04 '13 at 07:35
  • 3
    "...to Go coders..." - this is the reason. F#/Haskell/etc. are very alien to C developers and that's why they are getting ~0 traction. Scala made an effort and now it is more approachable and heard of. – Den Sep 04 '13 at 08:25
  • 15
    By the same notion, Python and Ruby are very alien to C developers, as they use bunch of unfamiliar keywords, "weird" syntactical rules (where are braces?) and strange semantical concepts (generators? metaclasses? decorators?). Yet they don't get ~0 traction, quite the opposite. – Xion Sep 04 '13 at 11:01
  • 8
    @Xion: did you look at the initial growth rate of Ruby? It took *ages* to get where it is now (18 years, to be precise). Python is even older (1991!). – Joachim Sauer Sep 04 '13 at 12:05
  • Another possibility may be that they originally went with `new` because of the impler parsing semantics for the compiler toolchain. – haylem Sep 04 '13 at 14:28
  • @Den This is likely to change in the future, but Scala isn't particularly popular yet, and in particular [not more popular or "heard of" than Haskell](http://langpop.com/). Scala can also be very weird looking to Java programmers, and in fact in the early days some complained precisely about that: that Scala was "too difficult" for real world use (an assertion I don't agree with, either for Scala or for pure FP languages). – Andres F. Oct 04 '13 at 14:38
  • 2
    @AndresF. Some of the resistance to Scala could have nothing to do with the language. As a younger programmer (age 25), something about the name itself makes me think of a cross between a math-based language like Matlab (which I have bad memories of) and a really old one like Fortran. There has never been any urge to even look at it. – Izkata Nov 03 '13 at 16:50
  • The best answer would surely come from the people who invented the language. – Florian Margaine Nov 03 '13 at 17:40
  • @FlorianMargaine Feel free to invite them here ;) – Denys Séguret Nov 03 '13 at 17:41
  • @AndresF. I don't have the numbers but I'd wager Scala sees more industry use by large scale companies than Haskell. – Rig Nov 03 '13 at 21:46
  • @Rig Agreed. Scala is more likely to be adopted by the industry (besides well known cases such as Twitter, where I work is also starting to use Scala as well, though with mixed results). But this is likely because Scala is a JVM language which interoperates with Java nicely, and not because it's "less alien to C programmers". To C/Java programmers, Scala can look truly bizarre. I remember there used to be plenty of complaints about this some years ago. – Andres F. Nov 04 '13 at 00:12
  • 1
    @AndresF. The JVM is a big reason, from what I understand, why my division is migrating towards it. Its already used in other divisions. I have to say our ramp up was fairly short with a largely .NET and Java developer base. – Rig Nov 04 '13 at 01:28
  • 5
    A side note: *new* isn't a keyword in Go. It's a built-in function. – Manish Malik Nov 05 '13 at 08:35
  • @ManishMalik Good observation but unless [you shadow it](http://play.golang.org/p/1fPPqcXNU1), this makes little difference to me. I'd still call it a keyword even if it's not implemented at the grammar level – Denys Séguret Nov 05 '13 at 08:40
  • @Izkata: That's a great shame, because Scala is one of the most modern and expressive languages I've had the pleasure to use. – Phoshi Nov 05 '13 at 11:57
  • 1
    Related: https://groups.google.com/forum/#!topic/golang-nuts/K3Ys8qpml2Y – Florian Margaine Nov 05 '13 at 13:31
  • Ruby was virtually unknown in the English-speaking world until Ruby on Rails came onto the scene, ~10 years after Ruby was created. – sevenseacat Nov 05 '13 at 13:42

2 Answers2

66

The best way to ask is probably to the people working on it; exactly what I did!

Tl;dr: it was originally there before make and &{}, and it's still the function to use in some situations.

Basically, here are the most important parts quoted:

So what's the reasoning behind new ? Is it something useful ? Should we use it ?

You cannot do this without new

v := new(int)
*v++
fmt.Println(*v)

new isn't a headline feature of Go, you won't find it used often, but when you need it, it is there.

Cheers

Dave

After another answer showing this kind of solution:

vv := 0
v := &vv
*v++
fmt.Println(*v)

I asked for further clarification:

So basically, Dave's point doesn't really stand?

There are places where it's inconvenient to sneak in a new variable just to take its address.

new(T) has an immediately straightforward meaning, rather than being a multi-step idiom.

Dave's point only falls if mere technical possibility (of doing without new) is compelling on its own.

Wasn't this discussed because it was just obvious that Go should have it because almost every language has it?

The "shall we keep new?" discussion pops up from time to time. Since we can't take it out until Go 2, if I understand the Promise correctly, there doesn't seem to be much to be had from going round the loop again; by the time Go 2 is thinkaboutable, we might have some different and better ideas ...

Chris

It's also there mostly for historical reasons:

you need to consider the history of the project. i think new is introduced first before there is make.

That is true. In fact we struggled for a while before coming up with the idea of make. If you look at the repository logs you can see that make only shows up in January 2009, revision 9a924177598f.

The new builtin function also preceded the idea of &{} for taking the address of a composite literal (and that syntax is in some sense wrong; it probably ought to be (*T){fields of T} but there wasn't enough reason to change it).

The new function is not strictly necessary but code does seem to use it in practice. It's hard to get rid of it at this point.

Ian

Florian Margaine
  • 6,791
  • 3
  • 33
  • 46
  • I would be happy to see links to the other *"shall we keep new?" discussions* which *pops up from time to time*. – Denys Séguret Nov 05 '13 at 14:42
  • Does something prevent you from doing `v := &(0)` and skipping the temp variable? (I know no Go.) – Alex Feinman Nov 05 '13 at 14:48
  • 3
    @AlexFeinman As `0` is a literal constant, you can't take its address. A problem would occur if you'd want a specific type too. That's why a syntax like `&int` or `&int(0)` might be useful (didn't think a lot about the best syntax, though). But doing it in two lines as Collins showed is fine too (`vv := 0; v := &vv`). – Denys Séguret Nov 05 '13 at 14:50
  • 22
    "Since we can't take it out until Go 2" ...which, as everyone knows, will never happen because `Go 2` is considered harmful. – Mason Wheeler Sep 28 '16 at 15:34
  • 2
    @MasonWheeler you almost killed me... still laughing at "Go 2 considered harmful"... weirdly enough I was talking about that article today at lunch. – Daniela Petruzalek Jun 06 '19 at 00:39
  • Rather than wait for Go 2, why not add a strict switch that forbids all unneeded nonsense? – candied_orange Jun 09 '23 at 18:55
0

In peano.go they do the following:

type Number *Number
func add1(x *Number) *Number  {
     e := new(Number)
     *e = x
     return e
}

and I could rewrite it without using "new" and get the same results:

type Number *Number
func add1(x *Number) *Number {
     var e Number
     e = x
     return &e
}

So even in this very particular case, it does not seem necessary at all.

Gzorg
  • 101
  • run `go build -cflags "-m"` and I believe you'll see why they chose their solution. If it needs to be more obvious https://gist.github.com/Lewiscowles1986/df2e49ebafd51f74f1d3331736607dd4/revisions shows the 2 line diff. This can be why unit analysis fails – MrMesees Apr 21 '20 at 12:55