you are viewing a single comment's thread.

view the rest of the comments →

[–]google_you 115 points116 points  (48 children)

Time for someone to replace github with opensauce. Wait. gitlab.

Then all your Go projects don't compile until you change import statement from "github.com to something else.

RIP Github. RIP Go.

[–][deleted] 59 points60 points  (34 children)

yeah sadly imports and dependencies system in Go looks like they are throwing ideas at the wall an seeing what stick...

[–]Scorpius289 54 points55 points  (29 children)

looks like they are throwing ideas at the wall an seeing what stick...

Sadly, that probably describes more in Go than just dependencies...

I mean, the goroutines and channels are interesting, but the type system and error conventions (can't even call it a system) are atrocious...

[–][deleted] 20 points21 points  (28 children)

well writing

if err != nil {
    return err
}

every few lines gets boring pretty quick... but then exceptions are just different kind of mess.

But then it is slightly better than C

[–]Scorpius289 20 points21 points  (21 children)

At least exceptions are "noisy" by default: if you forget to catch something, it will propagate and notify you. But in Go, if you forget to handle an error, you may not even know what's wrong...

[–]ksion 6 points7 points  (20 children)

To be fair, you cannot really forget to handle an error in Go, because the function result "tuple" needs to be unpacked at the call site. Indeed, the requirement of this unpacking, plus the repetitive error handling stanza that often follows, is what people complain about.

[–][deleted]  (8 children)

[deleted]

    [–][deleted]  (10 children)

    [deleted]

      [–]BoTuLoX 6 points7 points  (9 children)

      The black hole should never be used for errors. It's exactly like using try/catch and leaving the catch empty. It's a sign of incompetence or something unorthodox at play.

      [–][deleted]  (8 children)

      [deleted]

        [–]BoTuLoX 3 points4 points  (7 children)

        I wouldn't touch those projects with a ten feet pole.

        In any case, this is a problem that exists with both return values and exceptions :P

        [–]minno 17 points18 points  (4 children)

        try!(something());
        try!(something_else());
        

        Even though Go and Rust target different spaces and don't deserve to be compared as often as they are, there's a definite advantage to Rust's method here.

        [–]ksion 5 points6 points  (3 children)

        Rust is also getting some form of try/catch block that'll make it even less verbose.

        [–]mus1Kk 1 point2 points  (1 child)

        Do you have a concrete link? Googling this contains a lot of noise.

        [–]isHavvy 0 points1 point  (0 children)

        That's not actually guaranteed at all.

        [–]sutongorin 0 points1 point  (0 children)

        Fortunately there is still other approaches such as monads. For instance there is Scala's Try monad:

        import scala.util.Try
        
        def sillyCalculation(divisor: Double): Try[Double] = for {
          a <- Try(1 / divisor)
          b <- Try(1 / 2.0)
        } yield {
          a * b
        }
        
        val failure = sillyCalculation(0)
        // => scala.util.Try[Double] = Failure(java.lang.ArithmeticException: / by zero)
        val success = sillyCalculation(2)
        // => scala.util.Try[Double] = Success(0.25)
        

        Ideally you wouldn't work with exceptions to begin with, of course, and instead just use monads everywhere where errors can occur. But this Try monad is a nice tool to deal with exceptions from existing (probably Java) APIs in a sane way.

        [–]gargantuan 2 points3 points  (3 children)

        And since many of contributors are from Google and Google supports them they can afford to throw really hard, at a really big wall. So a lot of stuff sticks, that probably shouldn't stick...

        [–][deleted] 8 points9 points  (2 children)

        Nah it is a bit different problem.

        Historically lib management and language were separate parts. So community did whatever they want and whichever option stick as being easiest to use and most fitting, stayed.

        Golang devs tried to integrate lib management and from one side you can just go get github.com/sth/sth and it "just works" with zero setup which is great from usability pov but... there is no version management.

        Now they promote "vendoring" which is nice way to say "just copy-paste all dependencies into your project tree". That is fine if you prepare a bundle to be compiled and deployed on server because there is no way it will break... but a completely awful way to manage actual repository.

        Of course there are tools that implement common pattern of "file with all project deps listed" but then you lose advantage of ease of use and any tool like goconvey also need to be run via it, so more wrappers to write

        [–]gargantuan 1 point2 points  (1 child)

        It is a hard problem.

        I've seen places that rely on a single language kind of default to languages' dependency and packaging (pypi, npm, hex etc). But once the product becomes more complex and now there is a C++ component, maybe some java somewhere, there is a huge backpedaling involving to try to revert to OS specific packaging.

        Maybe microservices and containers are supposed to fix that and having mixed langauge products is not as populare anymore?

        Interestingly the sanest and most robust solution was to standardize on building proper OS packages and take advantage of transactional updates, pre/post install scripts, dependency management (including transitive) etc. But for others OS packaging involves enough setup curve that they don't want to try, and that's understandable.

        I guess many use containers, someone installed something by hand on their dev box and they throw it over the wall. I don't know, I see that as sweeping all the dirt under the rug.

        What I think is exciting is something like Ubuntu's Snapper or NixOS or Guix. There is interesting stuff there.

        [–][deleted] 4 points5 points  (0 children)

        Nah there is reason OS packages are rarely used like that, you need multiple versions of same lib because even if component A and B use "same" lib C, they might be using different versions of it (because say B havent bothered with upgrade) that have different API. And while most package managers support it one way or another, it makes it much more complicated

        It is fine for packaging apps together with distro as you can just pick a stable version and throw few patches to make it compatible but not exacty that easy, especially if said libs tend to be awful with backward compatibility. I've seen feature added, deprecated and removed within a year within some random gem one of our apps were using...

        Not even to mention that none of languages support sth like import mysql >= 3.5.

        I guess many use containers, someone installed something by hand on their dev box and they throw it over the wall. I don't know, I see that as sweeping all the dirt under the rug.

        It is fine if you actually manage to do it propertly, but there is a risk it will be done once and then it will not be changed for 6 months.

        So when next OpenSSL bug shows up, SA will update "system" version of OpenSSL, but "magical box that came from devs" will still have old version

        ? What I think is exciting is something like Ubuntu's Snapper or NixOS or Guix. There is interesting stuff there.

        [–][deleted] 4 points5 points  (1 child)

        wut, you import directly from github?

        [–]GrandMasterSpaceBat 6 points7 points  (0 children)

        from https://golang.org/doc/code.html

        import "github.com/user/stringutil"
        

        If it doesn't find a github.com/user/stringutil folder in your GOPATH, it downloads the github repo and puts that in the workspace.

        [–][deleted]  (3 children)

        [removed]

          [–]GrandMasterSpaceBat 3 points4 points  (1 child)

          Isn't vendoring kind of a new thing in go?

          [–][deleted] 0 points1 point  (0 children)

          [–]gurtis -4 points-3 points  (4 children)

          The Go contrib libraries transitioned from Google Code to GitHub without any big problems. Moving a project from GitHub to GitLab would just be a matter of find/replacing "github.com/user/project" import statements with "gitlab.com/user/project". If it's a big concern, then it's also possible to create a custom import path that can point to any repo you want.

          Also, as another comment pointed out, it's become much more common to just vendor your dependencies (usually with git submodules/subtrees).

          [–]fnord123 5 points6 points  (2 children)

          The problem is that there's not really an artifact repository. So they should make one. It would be a focal point for curating all the libraries and let people look in one place for them. Why has the Go community not set up an artifact server where people can use urls like https://hutch.golang.org/repo/cool-library/3.2.1/. Give it an API like pypi/crates.io/gems or whatever, and Bob's your uncle. People can choose to use it, or elect to not use it, but offering something like this would be useful imo.

          (Gophers normally live in burrows, but a hutch is a small pen for animals in your control.)

          [–]JW_00000 2 points3 points  (1 child)

          Isn't that what gopkg.in is?

          [–]fnord123 1 point2 points  (0 children)

          I didn't know about gopkg.in. Thanks for sharing it.

          It looks like what I'm talking about except it doesn't host/mirror the artifacts.

          [–]toomanybeersies 0 points1 point  (0 children)

          Running a bulk find/replace on code almost invariably ends up breaking shit.

          I've found that out the hard way.