

Thoughts on Go after a few days - jamesjyu
http://bklimt.tumblr.com/post/38104505318/go

======
enneff
> I’ve been learning Go the last few days.

Great! But it might have been more productive to hold off on the blog post
until you've been using it for a few weeks, at least. You make a few barbed
comments about the language designers, but you are nowhere near familiar
enough with Go to be justified in doing so (IMO).

> If Foo is derived from a struct, and it doesn’t work when zero-valued, then
> there should be a function somewhere called something like NewFoo. Good luck
> finding the right one.

I've never needed luck, here. This isn't a real problem for actual Go
programmers.

> Why is there this special function that construct these three random types?

They're not "random types". They're special built in types that are managed by
the language runtime. That makes them distinct from anything you can write as
a user, and that's why they use the built in make function for initialization.

> I think channels are value types, which is strange since it’s the only other
> type created with make.

No, channels are reference types, too. Just like everything created with make.

There are more misconceptions and inaccuracies.

~~~
waterlesscloud
There's nothing wrong with making a blog post about his early impressions.
It's just an opinion on the internet. There's millions more out there, and we
all probably disagree with a few of them.

But even aside from that, it's valuable to have someone's early impressions of
a language. They may change later. That's cool. But it's also cool to know
what they think early on, because it's fairly likely other people will have
the same experience. Whether or not his comments represent misconceptions and
inaccuracies, they still report his experience. Other people can benefit from
knowing others shared the same experience, and if he blogs later when he has
more knowledge they can also see how his experience changes over time.

I encourage more blogging of this sort.

~~~
enneff
> There's nothing wrong with making a blog post about his early impressions.

I totally agree, but he makes a number of conclusions (or at least strong
statements) throughout that, to me, seem premature.

For example, in the introduction: "I get the feeling that Go was designed by
System Engineers, who focus on implementation." Systems engineers focus on
APIs as much, if not more so, than other programmers. Systems engineers build
the things at the bottom of the stack, where API design decisions have a
fundamental effect on everything built above them.

It's definitely worth reading this:
<http://talks.golang.org/2012/splash.article>

------
rcoh
It's worth noting that some of the Go inconsistencies derive from the language
designers desire to make the grammar regular (facilitating extremely efficient
and simple parsing). In order to do this, you need statements that mean
different things to the compiler to look different. This manifests itself in
the (I admit, very inconsistent) var x int foo vs. x := 5 declaration. They
mean the same thing to you, but different things to the compiler -- to
preserve a regular grammar, they have to look different.

It's definitely a little ironic that what is needed to make a regular grammar
makes the language more inconsistent.

~~~
Mooby
Supporting declaring variables with new(), make and local variable assignment
isn't mandated by the need to make the grammar regular. It's simply a
braindead idea. Go might have significant improvements over C, but they
screwed the pooch on this one.

~~~
drivebyacct2
Another uninformed comment, I can't freaking believe you created a troll
account just to spread your ignorance about Go.

The difference between make and new is well covered in documentation and on
the mailing list.

~~~
Mooby
So, when faced with criticism mentioned in the blog post and referred to in a
post, instead of thinking about it you mindlessly insult others and say
absolutely nothing about what has been said. Who exactly is the troll here?

~~~
drivebyacct2
What do you want me to say? Everything in the blog article is addressed in the
two very short documents that have been mentioned all over here.

Do I literally need to link you to the FAQ entry for "make vs new"? Or the
docs for initialization? You're the one spreading FUD.

------
skybrian
Yes, make versus new is confusing for beginners and I consider them
unfortunate. But fortunately they're easy to avoid most of the time. You can
initialize local variables like this:

foo := map[string]string {}

bar := []string {}

------
lbarrow
I really like Go. My team has been working on a Go application at work for the
last two months and I've had a great time of it.

That said, like all good languages, it's perfect until you run into the small
list of warts that enrage you. In particular, as the author said, the fact
that the make() types are different can get pretty annoying. What's really
going on there are that _make is really the only generic function in Go_.
That's why it's special -- unlike a lot of Go builtins, it's impossible to
write make() in Go. I really do think this is the biggest single wart in the
language (although there are others).

I don't really agree with the author's complaints about declaration syntax. I
don't find it distracting: just figure out an idiomatic way to do things and
move on.

Not having nil-able strings is annoying though. There are plenty of functions
both in the standard library and in my own code that return ("", error) simply
because the first return type is a string -- in a similar function with a
different return type, I'd just return (nil, error) and be done. Not a big
deal but it is a wart.

There are also some definite problems with the standard library, but I expect
these will get fixed by OSS packages in time.

Before we all dump on Go though, it's worth pointing out some of the really
cool innovations in the language that work great:

* Dependency management in the code is awesome. I love that importing a package and not using it is a compilation error. This seems to be so successful that they went and made declaring unused variables an error as well, which also does wonders for readability.

* Once you understand how you're supposed to use it, the GOPATH story is pretty great. Package management can get tricky and it's cool to see a language attacking it head on from the beginning -- you don't want to end up like Ruby.

* The notion of a Go "package" for namespacing -- and the exporting of CapitalizedVariables but not uncapitalizedVariables makes for very readable code. I really like it.

* The multiple return types for error handling definitely makes for more verbose code than the try-catch-finally pattern, but it also feels a bit cleaner. It takes a while to fully see the benefits of it, but it works great in the end.

I'm really excited for the future of this language. I think with a few more
years, a few better frameworks, etc, we'll be able to do some really cool
stuff very very easily in Go.

~~~
frou_dh
But is it that make is inherently confusing or that "creating" things in
general is muddied by being conceptually too crowded? There are at least 6
concepts jostling around (make, new, zero values, special reference types,
literals, pointers-to-literals). For starters, it seems like that could have
have been reduced to 5 by eliminating new(T) completely and allowing the
already-idiomatic &T{} to pick up the slack.

I must agree with your overall praise for the language. The package/export
system and the official tooling is masterfully done!

------
damian2000
The language has such a limited set of keywords and concepts that I think the
issue with having a separate way of creating arrays and channels isn't really
a problem. For me the killer idea is that of Go's interfaces ... its really
great. And of course the fact it generates a standalone .exe with no
dependencies.

------
stcredzero
_> I don’t think Go is a terrible language. It has some really great
features,...But all the inconsistencies in the language design have made
learning it feel like a chore._

In comparison to other languages out there, like Objective-C and C++, this
sounds like an i-th world problem.

~~~
myko
I'm not sure what you mean, maybe it is Apple's tools and Cocoa but I feel
like Objective-C is very easy to pick up and consistent.

Though I felt the same way about Go, I may just be terrible at noticing things
like this.

~~~
dietrichepp
Objective-C is only very easy to pick up and consistent if you only consider
the parts of it that are different from C. The parts of it that it has in
common with C can be pretty nasty.

------
rdtsc
For constructors, why notabstract that away all the inconsistencies with a
function call. Such as

    
    
        Foo foo_module_new() ?
    

I don't know Go, but I would do that in C for example and just create an
opaque struct for example.

------
dmbass
_> The standard library also seems to be missing a lot of the most common data
types. As far as I can tell, there are no standard stack or queue types. ...
How can a language provide an http server, but no stack type?_

I've never really done any Go, but aren't these just different use cases for a
Slice? Why would they need their own data type?

~~~
agentS
You are absolutely correct. Indeed, it is rather trivial to do so.

Pushing onto a stack is equivalent to `s = append(s, obj)`. Checking if the
stack is empty is equivalent to `len(s) == 0`. Peeking at the top (assuming
its non-empty) is equivalent to `top := s[len(s)-1]`. Popping from the top
(assuming its non-empty) is equivalent to `s = s[:len(s)-1]`

------
cerales
> Why is there this special function that construct these three random types?
> I don’t know.

It's reasonable for someone to be confused about this; my rationale is that
these three types are basically where go allows "magic": all of them support
special syntaxes (the range operator, optional multi-value context when
looking up a map, the select operator on channels), so they have a magic
initialiser, ignoring Go's usual "declaration is initialisation" rule.

As others have said, it's not too bad a special case in the context of the
language. The problem I have with it is that it introduces the possibility of
run-time errors that in a language this advanced and generally so well-
designed should probably be compiled-time errors: panics when you assign to
keys in nil maps or deadlocks when you send to a channel you forgot to
initialise are both errors of a class that the language generally doesn't
have.

------
andrewcooke
your general impression is correct, fwiw.

however, that doesn't necessarily mean that go is "a bad language". it's more
a cultural thing, as far as i can see.

go has some nice ideas and is a big advance over, say c or c++. it's also made
by people with a lot of experience and, for want of a better phrase "good
taste".

but it does have a certain culture (or, if you like, a disregard for a certain
culture).

nothing very useful seems to have come from these observations, and many
people have made them. it's probably better to simply consider the language as
a tool and work with it on its own terms. perhaps the most you can say is
that, because it does choose its own path, you really do need to use it in the
way intended by the authors.

------
mseepgood
Simple: new() is for memory allocation, make() is for the more complex
initialization of reference types. <http://research.swtch.com/godata>
<http://golang.org/doc/go_faq.html#references>

Why can't you add methods to types outside of your package boundaries? Because
Go aims for clean, comprehensible, robust boundaries between components:
<http://talks.golang.org/2012/splash.article>

------
chimeracoder
> But all the inconsistencies in the language design have made learning it
> feel like a chore.

That's interesting. Go is one of only two languages that I've been able to
learn by writing production code without feeling like I'm getting "held back"
by my inexperience (or, on the flip side, holding others back). It never felt
like a chore to me; there was only one "gotcha" that caused me a significant
amount of frustration.

> So what’s the response from Go’s designers about the requests for nullable
> strings? To treat the empty string as a special value. Sometimes it’s like
> they haven’t even read their own design justifications.

The only time I've run across this is with JSON encoding/decoding, but there's
a really easy solution to this (take a look at gobson, for example[1])

[1] <http://labix.org/gobson>

------
hakaaak
I was interested in Go because of its brevity, speed, and because Rob Pike
wrote it.

Reading this I see a lot of the reasons I like Ruby: no worrying about
different constructors or needing to worry excessively about types. If only
Ruby treated everything, even the little bit that is syntax, as mutable
objects, it would be near-perfect (and it would basically be Lisp). But, it's
close enough.

Maybe if Go could become Ruby...

~~~
damian2000
Having done a bit of development in both, I found I got productive in Go
quicker than with Ruby. With Ruby, there's many ways to do the same thing.
That might be great when you're experienced with the language, but for someone
starting out it can be daunting. The compexity of installing RVM put me off
also - I was never able to install it on Linux properly so ended up using the
version that came with the Ubuntu package manager, which was an old version.

~~~
hakaaak
You don't have to install RVM, but it does help. It was never that difficult
for me, but I use OS X for Ruby dev mostly.

And there may be a variety of ways of doing things, but that's because (1)
Ruby has been more well-used than Go, and (2) it has more flexible loops, etc.
to make it less verbose, and yes there are a variety of ways to add methods,
attributes, etc. but after you spend a little time to understand how the Ruby
object model works, you'll understand why- almost everything is an object.
Also, the language has evolved, so there are some differences in syntax
between 1.8 and 1.9 but you can still use 1.8 syntax in 1.9.

~~~
damian2000
Yeah agreed Ruby is more powerful especially with loops. The object model and
that methods are messages passed between objects is also great, once you
understand it.

------
Svip
Nullable types? I thought that was one of the bad things about C#. I asked
Anders Hejlsberg about it when he was in the country, and he said if he could
go back, he would remove nullable types from C#.

~~~
kibwen
There is at least one way for a language to have nullable types that is both
type-safe and memory-safe: Option types.

<http://en.wikipedia.org/wiki/Option_type>

------
drivebyacct2
I'll just summarize my ramble with: the author of this blog post could have at
least read the short Spec or "Effective Go". Would have dispelled his
confusion on several things and would have prevented a few of the
inaccuracies.

------
Mooby
He forgot to mention how programmers need to add each project directory to
$GOPATH to be able to include files stored in project subdirectories. Talk
about a braindead idea.

~~~
burke
I interpret this as encouragement to use fully-qualified package names (eg:
[https://github.com/burke/zeus/blob/master/go/zeusmaster/zeus...](https://github.com/burke/zeus/blob/master/go/zeusmaster/zeusmaster.go#L8-L14)),
which I don't really have a problem with.

Go code is nothing if not explicit.

~~~
Mooby
That approach is nice and all if we are dealing with modules which we wish to
reuse. If instead we would like to organize our source tree following a deep
directory structure, we are forced to screw around with $GOPATH, which is a
braindead idea.

~~~
marshray
You keep asserting that this $GOPATH is "braindead" but you provide no
meaningful criticism of it or suggest any better alternatives.

I haven't messed with Go, but nothing about the idea of defining a path for
source modules sounds braindead on its face to me. I certainly would give the
benefit of any doubt to the designers of Go over some random troll.

~~~
Mooby
These are not source modules I'm talking about. If it was only necessary to
set $GOPATH to point to source modules then everything would be fine. The
problem is that go requires that $GOPATH points to a project's source tree to
be able to build it, if the project is organized to store other go source
files in subdirectories. We aren't talking about packages or modules intended
to be reused in other programs. We are talking about how source code trees are
organized.

~~~
marshray
_The problem is that go requires that $GOPATH points to a project's source
tree to be able to build it_

How is that different than the /I ${INCLUDE} path of C/C++ compilers (and many
other languages)?

