Hacker News new | past | comments | ask | show | jobs | submit login

To be fair, the Go authors have always strongly promoted that you fork and maintain your dependencies. That may be a bad operational decision (outside of Google), but is technically unrelated to the language itself.

Mind you, if third party code needs debugging, you're going to have to fork it in order to apply your fixes in a timely manner anyway. Perhaps their stance is not as crazy as it may originally seem.




And with my professional experience, sometimes maintaining a program over a decade, I have to agree. When you are using an external library, you have to at least have a copy of the version you are using. Repositories might go away without a warning. Also, you want to go to a new version only after some review. Ideally, you don't have any local modifications - if you patch libraries, you should donate the changes back. But then, it happened that patches were rejected. In the end you are going to need a local copy/branch for several reasons.


> Also, you want to go to a new version only after some review

Happened here recently - modules used in the core build aren't versioned which means when someone external updated a module with an incompatible change, the build broke.

Moral: Never build direct from CPAN / GOPAN / CCAN / WHATEVSPAN without pinned versions.


Can you point me to a quote where Go authors have encouraged people to fork a third party library in order to insert better error handling code?

I don't want to insult anyone, but this seems like an utterly insane software engineering practice to me. It means you can't just update to the next version of that library any longer. You're taking it upon yourself to review and patch every single new version of that library. Manually.


See: Any discussion related to go get and its design motivations.

Even vendoring, which was added to the tooling later, is built on the idea of keeping your own fork. It just simplifies the forking process for people who do not work like Google does, where each fork is shared company-wide.


GP is right: this is insane.

Not only are people here suggesting that you fork your dependencies to add stack traces to errors, which is a problem no other modern language seems to have, but it's also going to be a security disaster when some common package is found to have a vulnerability and ten percent of projects ever bother to update it.

I feel like I've entered some sort of bizarro world where everyone has forgotten that programming doesn't have to suck and pretends that none of this is a problem.


I love programming in Go but the thought of forking and maintaining every single library I might use in one of my projects makes me also feel we've entered a new, bizarre, and terrifying world. This is literally one step away from "write your own OS and compiler, it's the only way to be sure you get the exact behavior you want".


I feel like every time you point out a design flaw in go, the response that hand-waves away your concerns contains advice that's even more absurd than the problem you were originally pointing out.

Can't get stack traces from third-party errors? Maintain all of your dependencies! Tired of reimplementing common math functions? Just cast all your numerics to double! And so on...


I know the debate. It's a debate about versioning, not about maintaining your own fork in order to insert your own error handling philosophy into third party libraries.


They have always maintained that Google does modify the packages and maintains any necessary merging and maintenance of the package. It is not just about versioning. This is why they maintain their own repository of third-party libraries in the first place, and why the tooling is designed to support their forking methodology.

Again, this may be a poor operational choice for those outside of Google, but they have also been quite clear that Go is built for the problems that Google has. If your problems are different, it may not be the right tool for the job. A hammer doesn't have to be able to cut wood. There is no harm in choosing a saw instead.


You seem to be forgetting what your original claim was. It was not that Google maintains forks of some third party libraries for some reason or other. That wouldn't be surprising at all. You claimed that

>the Go authors have always strongly promoted that you fork and maintain your dependencies

And you said that in response to a need for stack traces and specific error types.

Burdening yourself with maintaining a fork of a third party library for that specific purpose is what I'm calling insane, and I don't think the Go authors have ever suggested such a thing.


> You claimed that

Which is true. Their stance on maintaining your own forks is pervasive through all the tooling and their explanations of how the tools are designed to be used. There has been emphasis that if you want the tools to work well, you need to fork and maintain your dependencies.

You are, of course, free to do whatever you want. You can even feely let a random third-party maintain your dependencies, and hope they don't break anything, if you so wish. Many do exactly that. Despite what some people like to claim, the Go authors are not benevolent dictators that completely rule how you must develop software. They've simply published tools that worked for them, and granted a license that allows you to use and modify them in any way you see fit.

> And you said that in response to a need for stack traces and specific error types.

Technically the discussion was about how stack traces aid in debugging. It is a fair point. They most certainly do. And if you are interested in the stack within a third-party library, that suggests that you intend to debug said library.

If you are debugging a third-party package, you have already decided to fork it by virtue of what debugging requires. Adding stack traces to ease debugging of the package, if you so desire, is not a great undertaking on what is already a fork you have decided to maintain. You, of course, can submit your changes to the upstream maintainer, but in the meantime you are still holding on to a fork that you have decided to maintain. There is no guarantee that anyone else will want your changes. There is really no escaping that fact. It is not insane. It is simply pragmatic.

If you are only ever going to maintain your own code, the stack trace up to your call out to the buggy third-party package will still be available, if you choose to provide it, allowing you to work around or otherwise deal with the buggy package in your code.


>If you are debugging a third-party package, you have already decided to fork it by virtue of what debugging requires.

I think we disagree on two separate issues that shouldn't be conflated.

The first issue is whether the only purpose of a stack trace coming from a third party library is to actually debug that library. I suggest that this is not the the case.

I may simply want to understand what's going on in there. Maybe I'm passing incorrect data to that library, but the returned error is not specific enough to tell me what I did wrong. Maybe the error is somewhere further down in my own code (e.g. in a callback), in a different library altogether or related to the environment (missing file, broken database connection, ..). Or I may just want to post the stack trace in a support forum to get help.

I have often been looking at stack traces from third party libraries, but I have rarely wanted to debug those libraries.

Our second disagreement is perhaps a more gradual one. You seem to suggest that maintaining a fork is something completely normal or even desirable. I think it is something extremely undesirable - a last resort.

In any case, I do not believe that the Go creators have ever suggested that maintaining a fork is something you should do willy nilly or something that everybody should do all the time. This is different from the use of vendoring for versioning purposes. If the Go creators did in fact promote such a thing, I would strongly disagree with them.


> I have often been looking at stack traces from third party libraries, but I have rarely wanted to debug them.

If you have found stack traces are already readily available in third-party packages – that you can claim you do it often – what's the issue? Maybe this thread would be better served by real world examples of where the lack of stack traces in Go has actually bitten you?

> Maybe the error is somewhere further down in my own code (e.g. in a callback)

To be fair, the Go authors have also driven home the fact that you need to make your errors meaningful with the full context necessary to determine the path of the error (granted, not necessarily a full-fledged call stack). They have been abundantly clear that you should never simply `return err`. If this is an issue, it is because the code was written poorly.

And if a package is written poorly, and you don't want to fix the issues with it, perhaps you should reconsider using it in the first place?

> This is different from the use of vendoring for versioning purposes.

How so? The simplest form of a fork is one that is an exact copy of the original. If a package is already suitable to your needs, there is no reason to modify it, other than to perhaps merge in updates that the upstream author has made.

You can either keep that fork in a global repository, or you can keep it in vendor. There is no fundamental difference between either of those. At all. Vendor is just a convenience feature to allow the fork to stay in your application's tree.

Of course, if the library is poorly written or doesn't perfectly suit your needs you may have to make modifications to it. But that is true of every library written in every language in existence. It is not insane to do that, just pragmatic.


>If you have found stack traces are already readily available in third-party packages – that you can claim you do it often – what's the issue?

Not in Go. I have found them extremely useful as a diagnostic tool in languages that have ubiquitous stack traces.

>And if a package is written poorly, and you don't want to fix the issues with it, perhaps you should reconsider using it in the first place?

As I said, the problem may not even originate in that particular third party library. The error may just be passing through, coming from my own code or from a different library altogether.

>How so? The simplest form of a fork is one that is an exact copy of the original.

Vendoring is not primarily about forking and then changing the code. The main purpose of vendoring is freezing dependencies.


> The error may just be passing through, coming from my own code or from a different library altogether.

Then you will have a stack trace to work with. Again, this discussion would be more meaningful if you provided some real world examples. Hypothetical situations that will never happen in the real world are kind of pointless. You don't have to invent reasons to justify not using Go, if that is your intent. Frankly, I couldn't care less what tools you use, and it seems like it is justifiably not the right tool for your problems to begin with.

> Vendoring is not primarily about forking and then changing the code. The main purpose of vendoring is freezing dependencies.

But you are quite literally maintaining a fork. In 99% of the cases there will be no need to modify the code, be it in vendor or in another repository. Freezing the dependency has always been the primary goal of both approaches. The only difference vendor introduced is that the code resides under the vendor tree of each individual application, instead of in a global namespace that allows you to share your pinned version with all of your applications. That's it.


>Then you will have a stack trace to work with

Only if a stack trace was added in the original location and then passed on at each intermediate step. As stack traces are not automatically created in Go, nor customarily passed on, there is usually no stack trace available.

>Again, this discussion would be more meaningful if you provided some real world examples. Hypothetical situations that will never happen in the real world are kind of pointless. You don't have to invent reasons to justify not using Go, if that is your intent.

I have been a real world developer for 25 years, and I have explained to you the sort of real life situations in which I have used stack traces to diagnose errors, either originating in or bubbling up through third party code.

If you want to call me a liar, fine, but otherwise don't call it a hypothetical situation that will never occur if I'm telling you that I have run into countless such situations.

I have been using Go and I have defended it on many occasions. But this sort of obstinate reaction of denial and deflection to the most obvious difficulties caused by any of Go's design decisions is really starting to put me off big time.

>But you are quite literally maintaining a fork. In 99% of the cases there will be no need to modify the code

Inserting error handling code is a modification and keeping it up-to-date with new versions of the library is the problem I'm talking about. I think I have made that very clear before.




Consider applying for YC's Spring batch! Applications are open till Feb 11.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: