make for custom types

1,470 views
Skip to first unread message

Benjamin G.

unread,
Mar 30, 2012, 1:31:58 PM3/30/12
to golan...@googlegroups.com
Hi, i'm just starting to deep into Go for real, and after reading a bit about make and new, i'm wondering something :

The way i understand it , new returns a pointer to a zeroed T, and make returns a struct containing initialized pointers. What I don't understand though, is the reason why make is reserved to three types only, as this feature seems likely to be useful to other types as well.

I've search and only found a very long 2010 thread about make vs new on this mailing list, and the proposition to have new and make merged together, but i don't think it addresses my point.

Benjamin

Stephen Weinberg

unread,
Mar 30, 2012, 1:44:32 PM3/30/12
to golang-nuts
Make initializes the build in types. os.Open() initializes an os.File
and the builtin make() initializes the builtin types map, slice, and
chan. There is no reason to expand make because you can create
initializers for your own types. Trying to force them into make would
just complicate the language.

Another example is bytes.Buffer. The Buffer type has two different
functions for initializing depending on what you are starting with.
http://golang.org/pkg/bytes/#Buffer

The bottom line is the make is the initializer for the builtin types.
New on the other hand is a builtin function for allocating memory.

-- Stephen

On Mar 30, 10:31 am, "Benjamin G." <benjamin.garrig...@gmail.com>
wrote:

Benjamin G.

unread,
Mar 30, 2012, 1:52:24 PM3/30/12
to golan...@googlegroups.com
But I suppose that make is more optimale than new + custom init method, otherwise we could as well have defined map in a "collection" package, and use  
right ?

Stephen Weinberg

unread,
Mar 30, 2012, 2:00:23 PM3/30/12
to golang-nuts
First of all. I would probably add it to containers so we would have
container/map.New(). And yes, that is probably where it would be in a
perfect world. However, because maps, slices, and chans use generics
(which is not allowed in go) they need to be builtins.

Have you noticed that with all three makable types, they are actually
many types? A []string is not a []int. A map[string]string is not a
map[int]string. These builtin types have been allowed by the spec to
have special powers. At the same time, they needed a function (make)
that had magic powers as well. What type does make return?

make([]int, 1) returns an int slice
make(map[int]string) returns a certain type of map.

This is inconsistent with how non builtins are allowed to operate.
Conflating these special cases with everyone else's types would be
detrimental to the language.

-- Stephen

On Mar 30, 10:52 am, "Benjamin G." <benjamin.garrig...@gmail.com>

chris dollin

unread,
Mar 30, 2012, 2:00:36 PM3/30/12
to Benjamin G., golan...@googlegroups.com
On 30 March 2012 18:52, Benjamin G. <benjamin....@gmail.com> wrote:
> But I suppose that make is more optimale than new + custom init method,

You don't need to use new very often either, because for structs you
have &typename{...}.

> otherwise we could as well have defined map in a "collection" package, and
> use
> map := collection.map.New()
> right ?

You'd lose the polymorphism that the built-in map magically has.

Chris

--
Chris "allusive" Dollin

Benjamin G.

unread,
Mar 30, 2012, 2:21:31 PM3/30/12
to golan...@googlegroups.com, Benjamin G.
ok, thanks to both, I completely missed the polymorphism / generic consideration. Never occurred to me that it could be a reason for having a "make" special function.

I guess I understand a bit better now why i see people mentioning generics in their go wish-list here and there.

Benjamin G.

unread,
Mar 30, 2012, 3:30:48 PM3/30/12
to golan...@googlegroups.com
So, just as a side question related to make vs new : 

There's absolutely no hope that one day map could use the "named return parameter" feature easily like this : 

func WordCount(s string) (res map[string]int) {
// need to res = make(map[string]int) here, which quite defeats the handy shortcut... at least that shortcut could recognize the "map" type and do a make instead of a new, since it's built-in... 

?

Jan Mercl

unread,
Mar 30, 2012, 3:43:51 PM3/30/12
to golan...@googlegroups.com
On Friday, March 30, 2012 9:30:48 PM UTC+2, Benjamin G. wrote:
So, just as a side question related to make vs new : 

There's absolutely no hope that one day map could use the "named return parameter" feature easily like this : 

func WordCount(s string) (res map[string]int) {
// need to res = make(map[string]int) here, which quite defeats the handy shortcut... at least that shortcut could recognize the "map" type and do a make instead of a new, since it's built-in... 

?

package main

import (
        "fmt"
        "strings"
)

func WordCount(s string) (res map[string]int) {
        res = map[string]int{}
        for _, v := range strings.Split(s, " ") {
                res[v]++
        }
        return
}

func main() {
        fmt.Printf("%v\n", WordCount("foo bar bar baz foo bar"))
}

 

Rémy Oudompheng

unread,
Mar 30, 2012, 3:47:21 PM3/30/12
to Benjamin G., golan...@googlegroups.com
Le 30 mars 2012 21:30, Benjamin G. <benjamin....@gmail.com> a écrit :
> So, just as a side question related to make vs new :
>
> There's absolutely no hope that one day map could use the "named return
> parameter" feature easily like this :
>
> func WordCount(s string) (res map[string]int) {
> // need to res = make(map[string]int) here, which quite defeats the handy
> shortcut... at least that shortcut could recognize the "map" type and do a
> make instead of a new, since it's built-in...
>
> ?

I personnally prefer to allocate memory only when it's absolutely
needed. Memory allocation is costly and there's no reason to perform a
make() if you want to return a nil map.

Rémy.

Benjamin G.

unread,
Mar 30, 2012, 4:02:47 PM3/30/12
to golan...@googlegroups.com, Benjamin G.
My mistake... I just realized that named return parameters weren't allocated with new as well when they were pointers to struct... 
I'm still a bit rusty with the use of structs (too much used to having types automatically be pointers)
Reply all
Reply to author
Forward
0 new messages