7 ms·
It's just syntactic-sugar. From the proposal (https://github.com/golang/go/issues/32437 https://github.com/golang/go/issues/32437): f, err := os.Open(filen
by kbd 7y ago
It's just syntactic-sugar. From the proposal (https://github.com/golang/go/issues/32437 https://github.com/golang/go/issues/32437):
f, err := os.Open(filename)
if err != nil {
return …, err
}
is simplified to:
f := try(os.Open(filename))
> I dislike the try implementation
What would you suggest instead?
- politician 7y agoIt doesn't matter what we suggest. There are 100s of suggestions on that Git ticket, and it's a fait accompli masquerading as an RFC. Down-vote if you want, but Go modules package management was handled in the same way. It's not without precedent.
- CamouflagedKiwi 7y agoAnd hopefully try will have the same outcome, i.e. something significantly better than existed in the ecosystem before. Basically I agree that the process for modules may not have been ideal, but the outcome was pretty good. We could do a lot worse than getting the same again.
- losingthefight 7y agoI mean, everyone is entitled to their own opinion, but I actually liked dep and never had a problem with it. With Go modules, it has been a massive problem converting our microservices over to Go modules, especially because some dependencies like Resty caused a lot of headaches and I lost several man weeks going through the process. Dep worked and modules doesn't seem to have brought us any real benefit, but again, my use case is my own and perhaps for you module was a better experience.
- CamouflagedKiwi 7y agoIndeed, I had exactly the reverse experience; dep never worked well, it was always moaning about obtuse errors ("project is not part of any GOPATH" etc) and was pretty slow even when it did, whereas go mod just worked almost flawlessly. I guess our mileages vary :)
- atombender 7y agoGo modules have some (minor, in my opinion) issues, but Dep was a total nightmare. Dep was made by one of the authors of Glide, which coincidentally suffered from many of the exact same bugs, maybe because it reused some of the same code. Our entire team constantly had "dep ensure" failing in unpredictable ways (locally or on the CI server), usually caused by the solver not understanding something. These failures were completely incomprehensible and not fixable by the user. Dep's solver was also very slow. From what I could tell, it was a combination of shoddy engineering and trying to do too much; if I remember correctly, Dep and Glide both tried to automatically detect and convert dependencies that used competing tools like Godep, which didn't work very well. For a long time, Dep didn't work at all with the Kubernetes client library, for example. We've had almost zero problems with Go modules. I've encountered some minor bugs, but unlike Dep, nothing worth tearing my hair out. The drama around Dep vs. Russ Cox shouldn't have happened, of course.
- no_wizard 7y agoAny good documentation on using go modules day to day? I have found the package management story around go so confusing its really stopped me from trying to use the language. For context, I'm used to how composer/npm install the modules into a folder locally. I just can't seem to figure the go way of doing modules where I don't get completely confused.
- atombender 7y agoThe official wiki is good: https://github.com/golang/go/wiki/Modules https://github.com/golang/go/wiki/Modules This article looks like a good intro: https://roberto.selbach.ca/intro-to-go-modules/ https://roberto.selbach.ca/intro-to-go-modules/ The equivalent of "npm install" is "go get" (optionally "-u"). You can also edit go.mod manually. Like NPM, this must be done within an application's root. A point of confusion might be the difference between a module and a package. A package is just a folder that declares "package foo" at the top in all its Go files. A module is the closest analogue to an NPM package. Similar to NPM, a single Git repo can contain many nested modules. Unlike NPM, modules can be imported with Git -- no need to publish to a special registry. When a Go file imports a package, the referenced package might live in a module outside your own. It knows it's outside your module because go.mod defines the full root path (e.g. github.com/foo/bar/baz) of your module. You might experience some confusion when you look at how the new module system interacts with the old GOPATH way. Go current supports both modes.
- ploxiln 7y agoWhy did you go through it? You didn't have to, you could have waited a couple of years. dep still works. A custom script to populate a GOPATH with specific versions or forks of all needed modules still works.
- politician 7y agoYes, in fact, I like Go modules. But that's not the point, the point is that the community had precisely zero say in how that feature works. Likewise, the community doesn't have any say in how try works, and that ticket asking for feedback is window dressing. You can tell that this is window dressing by looking at the timestamps on when that ticket was opened, comparing it to when this blog post was released, and then considering how the hundreds of comments on that ticket were completely ignored.
- camdenlock 7y agoWhy must “the community” necessarily have any say at all in how this new feature is designed?
- marcus_holmes 7y agosimply, because "the community" are a set of people who have spent (collectively) millions of hours using the language in a massive variety of use cases and environments. it's not democracy, but they'd be stupid to just ignore all that expertise.
- marcus_holmes 7y agoI feel like there's also some "not invented here" syndrome going on. Dep was pretty good, and there was absolutely the possibility of just making that official (and maybe tidying away a few of the points raised during the module discussion). But no, that wasn't good enough. Dave Cheney's errors package (pkg/errors) is a great contribution to Go error handling, used by a lot of gophers. Adopting that would have been simple, backward-compatible, and given us better error handling. But no, that wasn't good enough. I'm so used to "if err != nil" that it's punctuation for me. Having some code use "try" because it doesn't need to be wrapped, and other code use "if err != nil" is going to break that. I'll have to actually read the error handler now, in case it does something unexpected. Or not use "try" and stick with errors.Wrap. That seems way more sensible to me.
- ngrilly 7y agoI disagree. I think Go modules are the result of listening to the community. GOPATH, for example, would still be there if the Go team would not have listened to the community.
- tacticus 7y agomodules as a way to download stuff, and to remove the dependency on go path. Sure Semantic import version and the rush of shit to the head in their attempts to break vendoring on the other hand.
- grumpydba 7y agoIt is different from the original proposal and takes user feedback into account. At the end of the day one has to make the call. I think I can live with it.
- politician 7y agoThe thing is, they don't have to make a call. This is a non-problem where a change to `go fmt` would suffice (i.e. changing fmt to eliminate the line breaks in `if err != nil { return err }`). This is the C# 9.0-ification of a language. Let's add more constructs because we're compiler developers and that's what we do.
- comex 7y agoChoosing nothing is still making a call.
- marcrosoft 7y agoDo nothing!
- AnimalMuppet 7y agoTo me, that sounds a lot like, when try() is introduced in Go 2, don't use it. (Though I guess it's a bit harder because you'd have to have your whole team not use it...)
- dullgiulio 7y agoCode reviews can help. For me, all examples uses of try would be great with properly contextualized error messages ("could not open file" as opposed to "could not read file": it is two very different operations after all!) At the same time we are surviving the type aliases quite fine (who has ever seen them used? Not me...)
- ithkuil 7y ago> At the same time we are surviving the type aliases quite fine (who has ever seen them used? Not me...) You night not have used them directly but you might have benefited indirectly from type aliases. For example, when the "context" package has been moved to the stdlib aliases allowed existing libraries that still used the old "x" context package to be used together with code that used the new package.
- Groxx 7y agoAnd also all libraries, and community coding habits (which educate new users of the language), and.... "don't use it" is definitely an option, but it's nowhere near "it doesn't exist". It's opting into a constant struggle against the tide.
- fauigerzigerk 7y agoIt's syntactic sugar masquerading as a function call. At the very least, I would use new syntax to make it clear that try does not have the sematics of a function call.
- kbd 7y agoThis I can agree with. Rust, appropriately, has special syntax for similar semantics.
- atombender 7y agoOne downside to this is that doesn't work for functions those return values aren't disjoint. io.Reader is an example where the function can return io.EOF and still returns valid data together with a count in its first return value. If it returns a count > 0, the buffer has valid data. A lot of Go projects get this wrong because it's not obvious -- it goes against the behaviour of almost all Go functions. Go is unfortunately full of little surprising warts like this where you have to tread super carefully. Nil channels is one of my favorites.
- frou_dh 7y agoWhat a thorn the design of that Read method is, because it has caused perennial FUD against the validity of sum typing in Go circles.
- atombender 7y agoHas it come up a lot in Go proposals discussions?
- frou_dh 7y agoDunno, I meant reddit flamewars etc.
- dom96 7y ago> What would you suggest instead? Implement exceptions. I'm honestly at a loss as to why the Go community hates them so much.
- tandr 7y agoGo community is big, divided, and has completely different opinions on "exceptions in Go", covering "we have exceptions already, it is called panic()" to "exceptions are evil" Oh, and by the way agreeing on what an exception IS brings whole another dimension into this discussion too. So, I would go as far as "Go community hates them". People have asked for them more than once. No, we did not get them.
- tandr 7y ago*wouldn't go as far, sorry
- qtplatypus 7y agoThere are a number of good reasons not to like exceptions. And yes I'm fully aware that good coding practices and some implementations can mitigate these problems. * Exceptions create a type of non locality that is hard to reason about. In a language with exceptions every call to a function might result on the calling function exiting. Flow control might jump up serval stack frames unexpectedly. This works against the principles of structured programing and the normal expectation that a function when called will return a value. This means the programer, the compiler and the runtime environment must always take this into account. This can create unexpected behaviour and creates a whole host of special cases for the compiler and runtime. * Uncaught exceptions cause crashes Even when the error is not something that would cause a problem if an exception isn't caught the process will crash. * Exceptions are often too heavy for what they do. In many situations an error is an expected/frequent outcome. Consider a disk based cache of some sort. The cache would attempt to open a file containing th cached result and if the cached result was not found then it would then do the processing to create that result. In this case in most typical exception systems the exception would propagate up the call stack to the exception handler capturing the stack in the process. Once handler is reached all this work is thrown away. * Exceptions create bad error messages Too often I've seen a buggy java process spew stack traces into the logs where a single line error message saying what happened would have made the operator's 2am dealing with emergency much more manageable.
- hacknat 7y agoI like the idea of throwing better. The whole point is reducing boiler plate so that a conditional return can be made. Something like this: f, err := os.Open(filename) throw err This allows alternate signatures easily. I also think the syntax makes a little more sense, as you're "throwing" the error up the chain unceremoniously.
- diegs 7y agoThe problem with this, with Go being a pragmatic language that encourages people to "just write simple code that works," is that people will inevitably use `try()` more often than needed without properly handling, inspecting, and/or wrapping errors. I'm saying this as someone who has helped a large organization of primarily Python programmers onboard with Go. Proper error handling is already something people don't do well (until we enforced lint rules throughout the company, there were already way too many `f, _ := os.Open(...)` types of error dropping). I'd much prefer something more strongly typed with respect to error handling, rather than less. Like if Java had disallowed extending RuntimeException so all exceptions would be part of function signatures (and therefore have to be caught).
- marcus_holmes 7y agoalso, using the same word for a completely different implementation isn't great. people coming from the try/catch world are going to be confused by this, purely because it makes "try" do something completely different.
- grey-area 7y agoI'd make it a keyword at least (things would be fine with lots of warning, just call it Go 2 and accept the incredibly minor breakage), so you don't spray nested brackets everywhere. f := try os.Open(filename) Or perhaps better, leaving the working code alone and concentrating on the bits people actually don't like (the error handling boilerplate). f, err := os.Open(filename) check(err) There is no need to attempt to put the error handling on the same line as the function, and if you do it just gets in the way of reading the actual function call, permits nesting etc. This approach would have the advantage of leaving normal code alone and only touching the error handling. I'd even be fine with check as a new builtin function, since it would typically sit alone anyway, I don't think it needs to be a keyword, whereas with try I think all the brackets will make it harder to read. In fact I've just found a variant of this proposed here: https://github.com/golang/go/issues/32811 https://github.com/golang/go/issues/32811