
Go 1.11 got me to stop ignoring Go - waits
https://drewdevault.com/2018/10/08/Go-1.11.html
======
brandur
A few years into using Go, I have mixed feelings about `GOPATH`. On one hand,
I can see the author's frustration in that it was always incredibly
presumptuous of the language's authors to dictate how its users should
organize their hard drives, and more so it feels like exactly the type of
arrogance that people tend to attribute to the Go's core and community.

Also, having helped a number of people now through their early days of the
language it's also the one biggest thing by far that reliably confuses every
single person. And I mean __everyone __— from first time programmers all the
way up to people who 've been in the industry for decades and are learning Go
as their tenth language. Being forced to put files in certain places is
incredibly non-intuitive because there's nothing else out there that requires
it. I must have sent the Go documentation on workspaces [1] to two dozen
different people at this point.

But on the other hand, once you've grasped the system and are using it,
`GOPATH` is surprisingly not bad. It's always obvious where your dependencies
are located and which versions are going to be used to build your project.
Even better, it lets you very easily drop into those dependencies and add
minor changes or debugging lines if you need to. This can be _incredibly_
useful if you're trying to understand how one of them works or think that that
you might have found a bug and trying to verify or patch it. A very powerful
feature once you know about it.

The new Go modules seem good, and will be a huge improvement in lowering the
barrier to entry for Go, but I'll miss the old `GOPATH` style of work at this
point.

[1]
[https://golang.org/doc/code.html#Workspaces](https://golang.org/doc/code.html#Workspaces)

~~~
raziel2p
There's going to be a large group of people (myself included) who graps the
system but refuses to use it because it's pointless and stupid.

> It's always obvious where your dependencies are located and which versions
> are going to be used to build your project.

More obvious than specifying the version in some dependencies file?

> Even better, it lets use very easily drop into those dependencies and add
> minor changes or debugging lines if you need to.

What dependency management system doesn't allow you to do this if you insist?

~~~
brandur
> More obvious than specifying the version in some dependencies file?

I have nothing against dependency files, but yes, it's probably even more
obvious.

If I see an `import "github.com/x/y"` at the top of a Go file, I know that I
can go find the source for that at `cd $GOPATH/src/github.com/x/y` (unless the
project has a `vendor` directory in which case you'll look in there instead).

> What dependency management system doesn't allow you to do this if you
> insist?

I'm sure you could do it on anything, but Go makes it _very_ easy.

As noted upthread, it's pretty simple to do this in other languages like Ruby
when you're using Bundler and know the system well (e.g., `pushd $(bundle show
excon)`), but in many languages it's much more difficult. You'd need to go
chase down the source, download it, then redirect your dependency to point to
it. Sometimes you'll grabbed a newer version that's no longer compatible so
you'll have to make sure to work off of the right tag.

In bad cases (e.g., C, Java) you'd have to learn how to build the project
which might not be trivial because tooling isn't standardized or convenient to
use.

------
sebcat
Having introduced Golang in a business environment in 2014 and having seen the
language solve real problems at that time, at scale, I feel that if your own
reason to not use Go is GOPATH... Either Go does not solve any real problems
for your use case, or your reasons to use Go is misaligned.

GOPATH is really not a problem, but efficient concurrency is. Go made the
company I worked for go from 20 deployments for a service to 1 (I/O bound),
reducing the costs for that service a lot. If you are willing to let the
environment get in between that...

Of course, you could have implemented that system using assembler for all I
care, but Go really made it possible within that organization, something Java,
C and other languages failed at before Go was introduced.

N=1, ymmv, &c

~~~
apta
> something Java, C and other languages failed at before Go was introduced.

Java's concurrency solutions are just as good, if not better than golang's.
Pair that with libraries such as RxJava and you're definitely ahead. I don't
see what golang has to offer in that area that the JVM doesn't

~~~
sebcat
Sounds believable, but at the time we were stuck at 1.6 and had a significant
drop in traffic due to JSSE and non-existing support of "modern" TLS Cipher
Suites and TLS extensions (we even had problems with SNI, years after
introduction)...

We were using C because epoll made it possible for us to compete, but the Java
reactivex stuff were lagging behind.

~~~
apta
Moving to a completely different language and platform was easier than moving
from Java 6 to Java 8? Why were you stuck on 6 otherwise?

------
sonaltr
I whole heartedly agree with the author.

While I disagree with GO's style guide and a ton of other choices - I don't
mind following them since that's what the language requires. But it goes past
that and wants me to organize everything my working directory just for it -
it's absolutely crossing a line.

While I didn't stop using Go because of GOPATH, it's one of those things that
absolutely annoyed the crap out of me.

to the point that all my go projects are now organized as
`project_name/go/src/github.com/username/project_name` as an example.

This was really really annoying to say the least.

~~~
divan
That's funny, but since I started using Go, I now organize all projects under
GOPATH, i.e. in `~/src/github.com/user/project`, no matter what language it is
in. GOPATH and HOME are almost synonims now.

I find it so much better experience than using tons of `~/Work`, `~/Projects`,
`~/Code`, `~/SomeLang/` etc. as I used to have before.

~~~
mtrn
I have been using something similar to ~/site/user/project for years and it
worked well so far.

~~~
merb
me, too. Personal projects:

~/projects/USER/NAMESPACE/PROJECT

Company projects:

~/projects/COMPANY_SLUG/NAMESPACE/PROJECT

------
jerf
If you read over the rest of this thread, you can find opinions ranging from
"GOPATH is horrible" to "It's wonderful". And I just want to point out this is
pretty good example of how important the marginal improvements can be.
Abstractly, you might have a hard time sitting there imagining how for a
thousand of your users, improving $ONE_SMALL_FEATURE might flip them from not
paying you to paying you, but at scale, yes, such margin-based thinking really
is important. Just like you may find it hard to really intuit that going from
.75s page rendering to .5s page rendering can have a significant impact on the
bottom line for an e-retailer, but, yeah, it does.

Just wanted to point this out as a clear example of such an issue, since it
doesn't come up very often so cleanly.

------
tingletech
I guess go 1.11 introduced a modules experimental feature as an alternative to
`GOPATH`

> Go 1.11 adds preliminary support for a new concept called “modules,” an
> alternative to GOPATH with integrated support for versioning and package
> distribution. Using modules, developers are no longer confined to working
> inside GOPATH, version dependency information is explicit yet lightweight,
> and builds are more reliable and reproducible.
> [https://golang.org/doc/go1.11#modules](https://golang.org/doc/go1.11#modules)

------
symmitchry
> I have major gripes with PEP-8, and if you ever see me using it I want you
> to shoot me in the face.

That sounds extreme. I've never heard this before. Why?

~~~
weberc2
IIRC, pep8 would have you write:

    
    
        def my_very_very_very_very_very_long_function_name(self,
                                                           param1,
                                                           param2):

~~~
Franciscouzo
You can choose to use:

    
    
        def my_very_very_very_very_very_long_function_name(
                self, param1, param2):
            ...

~~~
weberc2
Ah, my mistake.

------
docker_up
My biggest problem with Go is the lack of a constructor. I don't feel that a
struct type is good enough to enforce data integrity and as you have a more
complex program, you need to know that the object you are being passed has
data integrity.

With a constructor, I can force data to conform to what I need it to. I can
ensure that certain fields are not nil, that they conform to a specific list
of values, etc.

Because of a lack of a constructor in Go, I can't do that and I need to
continuously validate the data, which is annoying and a source of bugs. It can
be said that this can be accomplished with interfaces but that's adding a lot
of complexity to something that should be a lot easier to handle, in my
opinion.

~~~
venantius
By authoring private structs with public constructors, you can get what you
want out of this. Gets a bit messy with testing, but not impossible.

~~~
thanatos_dem
If you have your tests within the same package, they can access the private
members of structs directly, which helps avoid some of the mess.

If you’re in a different package things aren’t too bad if you have
meaningfully abstracted interfaces. And with Go’s duck typing, even if you’re
using another package that doesn’t have good abstraction, you can create your
own interfaces with the functionality you need for mocking purposes.

------
paxy
I have used goinstall, go get (in GOPATH), godep, dep, multiple GOPATHs,
symlinks, git submodules and lots more to figure out dependencies in Go, and
modules is FINALLY something that actually makes sense.

------
neduma
GOPATH issues - Elaborate more?

~~~
2trill2spill
Apparently too lazy to set an environment variable. I found GOPATH annoying
but not using Golang simply for that seems absurd to me.

~~~
nerdponx
_You see, GOPATH crossed a line. Go is opinionated, which is fine, but with
GOPATH its opinions extended beyond my Go work and into the rest of my system.
As a naive new Go user, I was prepared to accept their opinions on faith - but
only within their domain. I already have opinions about how to use my
computer. I knew Go was cool, but it could be the second coming of Christ, and
so long as it was annoying to use and didn’t integrate with my workflow, I
(rightfully) wouldn’t care._

------
throw7
But how did Go solve the GOPATH problem? He didn't say.

~~~
really_operator
Go modules

FTA: "Go modules are great, and probably the single best module system I’ve
used in any programming language. Go 1.11 took my biggest complaint and turned
it into one of my biggest compliments."

[https://github.com/golang/go/wiki/Modules](https://github.com/golang/go/wiki/Modules)

------
floatboth
I actually adopted GOPATH for _everything_. I use
[https://github.com/motemen/ghq](https://github.com/motemen/ghq) to quickly
clone non-Go projects into the ~/src/github.com/user/project style paths.

But… I don't like Go itself (anymore).

It's not just the 'if err != nil', it's more the general attitude/philosophy
from which it comes. Go is anti-intellectual, the designers basically don't
respect the user. "You're too stupid to use
generics/Result<A,B>/monads/whatever" is what it feels like they think of you.

Go internals are more infuriating than Go language though…

Especially the Plan9-based custom assembler. It truly is a horrific atrocity.
I've had to deal with it two times:

1\. That assembler does not support all instructions and even addressing modes
(!) of amd64, so people have had to create hacks like
[https://github.com/minio/c2goasm](https://github.com/minio/c2goasm) to run
asm functions without the overhead of cgo. Please actually read that project's
README, but tl;dr it assembles your code using a normal assembler and STICKS
THE BINARY CODE INTO A GO ASSEMBLY FILE AS HEX CONSTANTS. This hack actually
didn't work for me when I tried to use some SIMD code, so I had to resort to
cgo with its call overhead.

2\. I also tried (and failed) to port the Go runtime to FreeBSD/aarch64. This
was the last straw, this is what made me actually _hate_ Go.

------
haolez
Side note: I really liked the design of his blog.

------
xet7
Yes, but how to do error handling correctly with Go? My Go code crashes.

------
sdinsn
Server is down?

