22 ms·
Declined Proposal: A built-in Go error check function, “try”
- poweroftrue 7y agoThank God!
- mutt2016 7y agoGod codes in C, and uses three space tabs.
- alexanderdmitri 7y agoI'd definitely be interested in knowing what His take on error handling is.
- grogenaut 7y agoIt's undefined and implementation specific. Or maybe she took the approach Linus did with git and just let it crap out and start clean next big bang.
- 6nf 7y agoWhy three spaces?
- thesuperbigfrog 7y agoI am pretty sure He uses lisp^H^H^H^H perl: https://imgs.xkcd.com/comics/lisp.jpg https://imgs.xkcd.com/comics/lisp.jpg
- FireBeyond 7y agoI have seen a code base in the high six digits of LOC that is written with three space tabs. Ack.
- deleted 7y ago[deleted]
- jph 7y agoKudos to the Go team for their process on this. IMHO it's worth reading Russ Cox's explanation of the problem area, including examples, and comparisons to other languages e.g. Rust and Swift. https://go.googlesource.com/proposal/+/master/design/go2draft-error-handling-overview.md https://go.googlesource.com/proposal/+/master/design/go2draf...
- 0815test 7y ago"But Rust has no equivalent of handle: the convenience of the ? operator comes with the likely omission of proper handling." what's that supposed to mean? The ? operator just bails out if an Error result is returned from the called function, and forwards that Error to the caller. Cleanup is performed implicitly by drop implementations (destructors) using the RAII pattern ala C++.
- dralley 7y agoExactly, and the error types have to match, or at least be convertible, or else it won't compile. Seems either off-base or poorly worded.
- MaulingMonkey 7y agoIn the draft design, they give an example of special-case cleanup that would only execute only when an error occurs, not on the success path. You can emulate this with a boolean flag in your RAII types in Rust or C++, that's set or cleared immediately before a successful return, and then doing conditional logic in your Drop/dtor. Or you could do a std::mem::forget before successful returns. But I guess they think this is an important enough case to dedicate syntax to it for ergonomic reasons, which Rust doesn't have - which is what I think they're getting at.
- 0815test 7y ago> execute only when an error occurs You can use the match construct for that, and the Result<T,E> type comes with some utility methods that make it easier to clarify your desired semantics in many cases. The page complains that the "match" syntax is clunky, but I'm not that sure how 'handle' is supposed to be better.
- drivebyops 7y agoGreat that they listened to the community
- kjksf 7y agoThey listened to the part of the community that agrees with you. I'm "community" and I would prefer to have `try()` than not to have. They didn't listen to me.
- libria 7y ago"Listened to" is colloquial for "engaged with". They engaged with people who represented the `try()` option and declined to implement it. It is impossible to implement every proposal their ears listened to so obviously that's not what listened means.
- deleted 7y ago[deleted]
- FireBeyond 7y agoAnd they also "fast tracked" the decline "ahead of schedule".
- owaislone 7y agoThey didn't listen to the community. It was not a democratically driven decision. They gathered feedback from the community, weighed it in, discussed it and took a decision considering all aspects. It's not like they listened to whatever had the most votes on Github. At least I'd like to believe they didn't.
- __david__ 7y agoI right there with you. I would have loved try() even as a stop-gap to something better.
- gjs278 7y agothey shouldn't listen to you because you just tried to add a new way of error handling that has been proven to lead to unreadable messes
- rbtprograms 7y agoGood on the Go Team listening to the community, I definitely saw more people against this feature than for it. I hope they take another stab at improving error handling. I like Go a lot and do think error handling is one place it could use improvements.
- farah7 7y agoI didn't have particularly strong feelings towards this proposal (maybe just slightly against it) but it's probably important to note that people who are against it are generally much more vocal and make their voices are heard whereas those who like it just give it a thumbs up/tacit approval and keep it moving. Wish I knew how to accurately gauge the opinion of proposals from user communities.
- AnimalMuppet 7y agoI don't understand why anyone would be (strongly) against this proposal. If I understand it correctly, it's just a shortcut. That is, the old (existing) way would still work. If anyone didn't like "try", well, don't write your code that way. It would also appear to be amenable to an automated tool that would convert to or from try-style. Given that, why would people have strong feelings against? Because they think go needs something better, and if this passes, they'll never get it?
- badrabbit 7y agoHas the idea of making the returned error implicit and handling(or discarding) of the return value mandatory been explored? Thinking on the lines of errno in C.
- deleted 7y ago[deleted]
- curtis 7y agoA lot of Go programmers didn't like this proposal at all. I'd like to think this is just because they didn't think it was good enough. However, it seems that many, many Go programmers didn't like it because they think Go error handling is just fine the way it is.
- guessmyname 7y agoI am one of the Go programmers who didn’t like this proposal. I also spent a significant amount of time discussing with many people, including the Go team, and I am glad the proposal was declined, not because I like “if err != nil {…}” but because the proposal to add “try()” was not solving a good problem. Many, and I would say, every Go programmer wants better error handling, but “try()” was not it. I hope the Go team keeps exploring other ideas to hopefully one day have a better error handler.
- crimsonalucard 7y agoThe maybe monad is the best solution for this. Usually to support this the language needs Enum support and a proper type system neither of which golang has. So I'm ok with the developers just baking in syntax for an error monad with specific sugar for extracting the value or handling an error.
- millstone 7y agoWhy is a monad the “best” solution? Best according to what criteria? Special purpose syntax can buy you a lot more. For example Swift’s try makes it obvious which statements contain error handling without burdening each expression.
- crimsonalucard 7y agoOk let me tell you the criteria. There are two. First: The monad allows for composition of functions. Returning two values does not. It breaks the flow of a function pipeline and forces you to handle every error in the same way. Second: Extracting the value via pattern matching guarantees that the error will either be handled or used correctly. This is a way to 100% guarantee that there are No runtime errors. That's right. Using the error monad with pattern matching makes it so that there is zero room for runtime errors. Why create a language that has runtime errors? Create a language that forces you to handle all possible runtime errors before it even compiles. According the criteria of safety, zero runtime errors, and expressivity via composition the monad is the Best solution. There is literally no other way of error handling that I know of that can catch runtime errors at compile time. I know you tried to flip my statement on it's head by using the term "criteria" as if there are many many different criteria for "best." And you are right, programming is an opinionated thing. However, ZERO runtime errors is a too powerful of a feature to assign to a specific criteria. Such a feature is so powerful, it should be part of EVERY criteria. If you don't understand completely what I mean by "composition" or how pattern matching and a maybe monad can guarantee a runtime error will NEVER occur, ask me to elucidate, I'm happy to clarify.
- quotemstr 7y agoWith try, Go might have been a language I'd have enjoyed using. It's a shame. Right now, I see Go as being anti-abstraction and anti-cleverness, and I'd rather not work on codebases in which the language of choice is designed to deter creativity and encourage monotony. Heavy use of Go is a big negative when I evaluate potential projects to work on.
- CraftThatBlock 7y agoAnti-cleverness is what makes Go great. Go code is simple, and it is easy to read/understand. It's a feature of the language
- z0r 7y agoGo code is all about being able to see the trees, forget about the forest. Go programs are rarely easy to read or understand unless they are written by exceptionally talented developers in my experience.
- chrismarlow9 7y agoIn my experience this is true with any language. I think this is a function of talent and program complexity (the size of the forest), not the language.
- baby 7y agoI read code for a living and Go was the easiest language to read imo.
- hu3 7y agoI arrived late in a team that worked on a very large Go codebase. To this date, it was the easiest codebase to grok by far.
- apta 7y agoAgreed. Because golang is "simple", the actual code base becomes a mess, littered with 10 line functions that are basically map/filter/etc. calls, which can be written on a single line in a proper modern language. The majority of golang code bases I've seen are much more difficult to follow compared to if they had been written in something like Java or C#.
- minieggs 7y agoPerfect timing. Started mucking around with the Go compiler recently to implement my own error handling. https://pbs.twimg.com/media/D_ojiEqUYAAhmrH.png https://pbs.twimg.com/media/D_ojiEqUYAAhmrH.png edit: s/%s/%d/ but you get it.
- wybiral 7y agoThis hits at something fundamental about Go, which is what I like the most about it... It's a language intended to have few primitives with an emphasis on code being transparent and errors being values, requiring you to think about what they might be at each point as you're forced to carry them up the chain. Do I particularly like managing errors that way? No, but I do think that it improves the transparency and quality of a lot of Go projects. The same goes with the Go ecosystem and tools. You might not like how gofmt forces your code or the documentation conventions used by golint but the fact that we all use the same convention and documentation is awesome and it's what allows things like godoc.org. I think the proverb is "gofmt's style is no one's favorite, yet gofmt is everyone's favorite". And things like the lack of abstractions and generics are what create a community that's less reliant on dependencies. "A little copying is better than a little dependency" and you can see it in stark contrast to something like the JS community with its require('left-pad') NPM ecosystem. So, yeah, I like that they didn't fragment the community around something as arbitrary as this. And I get that some people won't like it, just as they don't like the lack of generics, but there is strength in some of these approaches that isn't immediately obvious.
- inlined 7y ago> errors being values Though with generics we could have the error values be less invasive. Learning the Scala mindset was eye opening. For e.g. the design patterns of an Optional[T]’s primary code flow are the same as a Try[T,E]. With common transformation idioms, you learn to recognize code patterns the same way one might recognize data structures. It’s no less magical and it simplifies greatly.
- bmurphy1976 7y agoBut it doesn't simplify, it just moves the complexity around. That's not necessarily bad, you get better safety guarantees as a result but you also spend more time fighting the compiler and locked in design space trying to get a model that works (and even MORE time is spent if you want it to be readable and something that other people can grok quickly). I don't see this as an either/or situation. There's a continuum between do whatever the hell you want C and rigorously defined Idris code. Picking a spot on that line involves many trade-offs and everybody has to choose what's right for their situation. That means Go approach is sometimes superior to the Scala approach for a certain class of problems in certain domains. Edit: don't downvote me, tell me how I'm wrong.
- hnaccy 7y ago>The key point here is our programmers are Googlers, they’re not researchers. They’re typically, fairly young, fresh out of school, probably learned Java, maybe learned C or C++, probably learned Python. They’re not capable of understanding a brilliant language but we want to use them to build good software. So, the language that we give them has to be easy for them to understand and easy to adopt.
- parhamn 7y agoThe average skill of most software teams is probably not far if not lower. I've been on very good ones and very bad ones -- lots of the code becomes least-common-denominator/weakest-link quality.
- skybrian 7y agoThis isn't about good and bad, it's about experienced versus beginner, for certain values of "beginner". Not complete novices, but people who have already been programming in some other languages, but are new to Go. Think new college grads.
- Avshalom 7y agoGoogle: we hire morons!
- patientplatypus 7y agoI mean... If you don't like writing `if err!=nil {...}` throughout your code base surely you can just create some middleware function in its own package that has switch statements based on error cases. Checking for errors frequently in the running of the code is more or less a Good Thing.
- mevile 7y agoI don't see how a switch statement helps you avoid checking for errors when methods you use return errors, and a lot of methods return errors.
- patientplatypus 7y agoYou can pass functions to functions (https://play.golang.org/p/XNMtrDUDS0 https://play.golang.org/p/XNMtrDUDS0). So you can do (sans syntax): ErrorCheckerFunc(fn myParams -> MyFunc(myParams), "message") ErrorCheckerFunc(fn myParams2 -> MyFunc2(myParams2), "message2") etc... and then the actual function: ErrorCheckerFunc(fn myFunc, message){ returnVal, returnError = myFunc(); switchError: case error is foo: print error case error is bar: log error print "error logged" ... case n+1 etc // you can handle message in a similar way to get // cases by function names, and if you have elixir // style quote unquote metaprogramming in Golang you might just be able to get function names based on passed function - I don't think this is in the language spec though it may be possible to do some other way. if error not nil do switchError(error) return RuhRoh else return returnVal } It's not so bad, it's just a middleware.
- djur 7y agoI'm not clear on what exactly you're trying to represent here, but it looks like something that wouldn't work with Go's type system. ErrorCheckerFunc would need to always have the same return type and accept a function with the same type signature.
- 7y ago
- hnruss 7y agoDo or do not, there is no 'try'.
- unixsheikh 7y agoThis is great news. I really like how errors are handled in Go and I hated this proposal. The current implementation forces you to constantly think about errors at each single point and it is extremely good at standing out. This is something very valuable, not something that requires or needs to be hidden behind syntactic sugar. It improves the readability of the code and the quality of the software. If it ain't broke, don't fix it.
- pcwalton 7y agoGo does not force you to think about errors at every single point. If a function returns only an error (such as, for example, os.Mkdir), the language will happily let you drop the error on the floor.
- gjs278 7y agoyou still had to think about it when you decided to drop it to the floor by putting the _ saying "I acknowledge there was an error, but I don't care"
- matthewbauer 7y agoThis is underappreciated! I suppose you are less likely to care about errors if you aren't getting values from a function, but not always. I wonder if there is a proposal to force this case to be handled, like Haskell's -Wunused-do-bind?
- matthewbauer 7y agoFound it: https://github.com/golang/go/issues/20803 https://github.com/golang/go/issues/20803
- pcwalton 7y agoThere's go vet. But it's inconsistent with the Go warnings-are-errors philosophy. Ignoring the return value of os.Mkdir() is far more likely to be a bug than an unused import is.
- 7y ago
- pcwalton 7y agoI suspected this was coming, and it's unfortunate. If Go had implemented try, then in a year everyone would be happy using it and the controversy would have died down. I've seen this happen before. Unfortunately, the community that has sprung up around Go is more or less opposed to new language features on principle.
- helper 7y ago> Unfortunately, the community that has sprung up around Go is more or less opposed to new language features on principle. I think this comes straight from the original go team. Rob Pike had a talk[1] that is partly about why go doesn't keep adding features and why it doesn't have certain features that other languages have. I think people who like go have bought into the idea that the go team has made good trade-offs to make go code easier to read and maintain at the expense of expressibility. [1]: https://www.youtube.com/watch?v=rFejpH_tAHM https://www.youtube.com/watch?v=rFejpH_tAHM
- gridlockd 7y agoThe controversy may have died down, but the impact on code written would have been permanent. There's a lot of value to there being "one way to do things", even when it's not the best way from any particular point of view. Go holds this principle higher than most other languages and I think that should be either embraced, or one should look elsewhere - and I'm saying that as someone who "looked elsewhere".
- bmurphy1976 7y agoI think you make a reasonable point that is worthy of discussion. Unfortunately there's a group of people on this thread that are downvoting comments such as yours instead of discussing them. I'd like to see reasoned responses to your comment, i.e. tell us why you are wrong instead of the downvote brigading.
- didibus 7y agoAgreed, no one is forced to use Go. I think it is refreshing to see a language like Go. You don't want all languages to asymptotically approach each other in features. We need diversity in our languages, that way you have flavors to choose from.
- willbw 7y agoTry not. Do. Or do not. There is no try.
- deleted 7y ago[deleted]
- dr01d 7y agoThis is why we have nice things!
- staunch 7y agoThank you Go developers! Please keep the language minimal, opinionated, and never subject to the bikeshedding mobs! It wouldn't have been the end of the world but I'm glad to see Go still has alive the spirit that made it so popular in the first place.
- Zenst 7y agoI hope somebody submits a "Do" and a "Do Not" amendment. Think of Yoda.
- meddlepal 7y agoIt's rather disappointing that Go has managed to bungle error handling so badly in a language only a handful of years old.
- akvadrako 7y agoProbably something about ideology overriding practicality. Personally I find go error handling okay but that’s because I exclusively use panic().
- codr7 7y agoJust don't let any true believers near it or they'll tear you a new one. I've published plenty of Go code with a panic() here or there to handle fatal issues, and there's never a shortage of ignorant fools dropping in to lecture me. If I'm not supposed to use it, why is it even in there? To tempt me? That would fit with the glorification of pain and boredom, I guess.
- poweroftrue 7y agoJust try writing three Go programs with error handling, then, try other languages! I was pissed at first. However, now I cannot code in any language without overusing try and being scared of each line. Using Go's error handling is actually making your code smarter, I mean, you don't want your code to break with a weird message because of something stupid. The simplest example is adding a default-path whenever I'm reading a file, Go's error handling reminds me of what to do if this file doesn't exist! Or cannot read etc. Don't take my word for it, Go ;) try it.
- joeblubaugh 7y agoReminds me very much of “Simple, Elegant, Wrong”
- dnautics 7y agotry errors in elixir: with {:ok, val1} <- happy_path1(val0), {:ok, val2} <- happy_path2(val0, val1), {:ok, val3} <- happy_path3(some_val) do function_might_crash_let_it_crash!(some_val) happy_result() else {:error, :enoent} -> handle_notfound_error() {:error, :eperm} -> report_permission_error() _ -> raise("don't worry this process is supervised, let it crash!") end low cyclomatic complexity makes for a nice user experience, and you learn the philosophy of "if it doesn't work, just turn it off and on again". Why be scared? Just let it go. The VM has your back.
- eweise 7y agoNo wonder people are leaving in droves for Go++.
- kerng 7y agoWell, that seems like the most obvious feature add to Go.
- politician 7y agoI'm extremely happy about this, and am hopeful this approach to community feedback continues. I previously said that this was a fait accompli like Go modules, but now I will happily withdraw that criticism. /cheers
- cwojno 7y agoPersonally, I feel that the motivation for the issue is one of convenience. The most common use case is changing the flow control in the event of an error to return from the current stack. I'm not a fan of defining an error handler. This seems far too intrusive and cumbersome and a bridge too far. GoLand gets around this somewhat by adding in the Live Template of "err" being a macro expansion for the if err != nil { return }. However, it still adds those 3 lines below each requisite call. If they added a new keyword that took the place of this macro, would that be too intrusive? Clearly, this only works if you have named return values. It would be nice if there was a bash/Ruby-like chaining, such as: var1, var2, var3, err := call1(args) && var4, var5, var6, err := call2(args) && ... and more calls and so on ... return callN(args) Where "&&" would perform the if err != nil { return } in-line. Should the first call return a non-nil error as the last argument, flow would be returned to the caller. If not, the flow continues as normal. This could even be extended in the case of function chaining: return call3( call2( call1(args) && ) && ) The downside of using && is that it's overloading the && and may cause some compiler/developer confusion. This was just an example based on a familiar use case (bash); another token can be used. Rasky suggested something like this based on another proposal in the thread, but using "?" instead. Another way to approach this might be an overlay language analogous to Kotlin. There could be a Go dialect that compiled into Go that provided this feature. Or, possibly an optional "plugin" for go's compiler that added an intermediate transformation step prior to compilation based on new keywords, but this will frustrate debugging and lead to other surprises. Generators tried to do this, but it doesn't seem to have taken off, from the repos I've read. Just my 2c
- deleted 7y ago[deleted]
- alexbanks 7y agoThis thread is rife with "Go should have Try because I want Try" that also seem to be made by developers that do not write Go. It seems confusing to me that voices generally involved from Go are so demanding of its maintainers. Curious, are there full-time (or at least Primary) Go developers that are upset by the lack of Try?
- qtplatypus 7y agoI am a full time developer in go. I feel the lack of good error handling every time I write a function call and then have to use the same if statement to check its result.
- ngrilly 7y agoHave you contributed to the discussion about `try` in the GitHub issue tracker?
- apta 7y ago> Curious, are there full-time (or at least Primary) Go developers that are upset by the lack of Try? I use golang at an employer. error handling in golang is verbose, error prone, distracting, and difficult to make sense of when there is actually an error (composing). I've seen on several occasions now errors being mishandled (either dropped by accident, or by overwriting already existing error variables in the same scope). These issues don't happen with exceptions.
- abhink 7y agoIt's interesting that as a full time Go developer myself, my experience has been very different about the points you have mentioned. I personally think verbosity is good. For one, lack of verbosity catches my attention. If I am reviewing code that looks like some part of it is ignoring the error, I would try to find a reason about that error check exclusion. This also prevents errors being dropped by accident. About overwriting, again this has never been a problem for me (as far as I can recall). Error values are very much localised in almost all Go code I have seen and written. If a function returns an error it is either immediately acted upon or returned by the caller. As such, any overwriting done at a later stage is more or less for convenience sake.
- atombender 7y agoI appreciate this change of heart, as I wouldn't want a half-baked solution to make it into Go, but I hope they don't just stop there. What the try() proposal gets wrong is that it tries to automatically bounce the error back the stack, being equivalent to "if err != nil { return }", which is ofte reasonable, but at the same time lacks the flexibility that current Go code has in terms of augmenting the error, or indeed handling it: You'd end up with try() calls for some things, but not all, so it's just ironing out one wrinkle and not every wrinkle. The second argument to try() is too heavy-handed. What we need is easy, readable syntax for all cases. In current Go code, people like the "v, err := someFunc()" syntax because it allows the happy path to stay in the current scope, with the secondary syntax "if v, err :=" introducing a new scope to avoid polluting the parent scope. If you're in the current scope, your code stays flat and clean (although Go's love of shadowing cause subtle). In my opinion, we need a syntax that is similar to a "catch" block in other languages, but easier. Perhaps something like this: v := getName() check err: { return errors.Wrap(err, "could not get name") } This allows you to handle the error and augment it, while not introducing anything magical. It's exactly equivalent to an "if v, err :=", but without introducing a new scope and not polluting the current scope with an error variable. This syntax would happily support fallthrough: v := getName() check err: { log.Printf("could not get name, ignoring: %s", err) } // v is now the zero value And of course you could still support a syntax for introducing a new scope: if v := getName() { // v is now valid } check err: { // You can return or anything else } You could easily extend it to error types with some kind of matching syntax: v := getName() check err == io.EOF { // On EOF } check err: { // All other errors } The above syntaxes don't support chaining. I'm on the fence. I like Rust's "?" postfix syntax, and I think it could work: // This could be "monadic"; the first error short-circuits ceo := getPerson()?.getCompany()?.getCEO() check err: { return errors.Wrap(err, "couldn't get CEO") } But why not just let "." be smart about errors and fall through like this? ceo := getPerson().getCompany().getCEO() check err: { return errors.Wrap(err, "couldn't get CEO") } After all, "." can know if the function returns multiple values, and "." on a tuple (or whatever Go calls it) isn't valid, so why not "promote" the "." to a high-level operator here? The awkwardness of the try proposal goes deeper than just error handling, too, I think. One reason Go can't solve its error handling problem elegantly is because of its reliance of multiple, exclusive return types. Almost all functions with this signature: func getName() (string, error) ...obey the unwritten rule that the function returns either a valid value, or an error. If you get an error, the value is supposed to be unusable, and the way to check for it is to look at whether there was an error.† In many type systems, a situation where a return value can be either A or B is variously called a union, or discriminated union, or enum, or sum type, which is the term I prefer. It's always bugged me that Go's designers didn't go one step further and made sum types a first-class citizen, because I think it would fit Go rather nicely. TypeScript solves it this way: function getName(): string | number And you can also define types this way: type number = int | float64 This, incidentally, introduces the idea of optional values: function takesOptional(x: string | null) Back to error handling, it would be more natural for a function to declare itself this way: func getName() string | error After all, it returns a value or an error. It can never be the superposition of both. In this regime, anything that gets a value needs to explicitly check for what it is. "switch" on type would work, just like today, but that gets verbose for mere errors. So we just say that the "check" syntax as outlined above would work for any union that involves an error. In other words: func getThing() Person | Company | error { ... } thing := getThing() check err: { return errors.Wrap(err, "can't get thing") } We can do this because we can say that "error" is special and known to the compiler, just like make() etc. are special. Of course, sum types go beyond errors, and open other avenues that are very poorly served by Go right now. --- † This, unfortunately, isn't universally true. For example, io.Reader's Write() method's contract says that if it returns io.EOF, it may still have read a final amount of data into its buffer. Many get this wrong and ignore the data read. Which points to the problem of conventions that only seem like unwritten rules, but also highlights how the lack of strong type-system support creates the issue in the first place.
- mattxxx 7y agoI think this is the right decision. Error-handling the go-way focuses on whether a single operation failed, rather than how a set of operations failed. In Python or Java, you see a lot of try-catches around blocks of code, which can obfuscate where the source of the error is, despite having particular handling for the type of error. For systems code, I mostly care about whether something failed... like: - Was the socket opened? - Was the file created? - etc.
- kadendogthing 7y agoThis reads like script kiddies who became professional programmers and just want things done how they've always been done. Error handling in go is not concise, and calling it explicit is in insult to anyone with a modicum of abstract reasoning skills. Error handling in go is not explicit, it's verbose. Error handling in go is not concise, it's broad. Error handling in Go is not consistent, it's an exercise left up to diligent programmers. As golang's code base grows, you're going to see this mistake play out over and over and over again. Having a Result<T> construct would have been great for go.
- vegancap 7y agoQuite rightly, too! It's annoying for beginners, but you quickly see the utility in the if err != nil {} approach, or 'sad path' approach after a few years of using Go in production. You learn to love it! To be honest, there's very little I'd add to the Go language, if anything. It's very unique that most Go developers share that view of a language. With Javascript, for example, I can't wait for 'new stuff', I think that's sometimes symptomatic of a broader dissatisfaction.
- billylindeman 7y agoAgreed. When I first started writing go I thought "Wtf is this caveman language" And now years later I couldn't imagine going back to using exceptions. The non-linearity of exceptions creates such a cognitive load of picking up unfamiliar code, and this is where go really shines. I can dive into almost any go codebase and get a lay of the land very quickly. On another note, I've been enjoying rust's approach with Result<T,E> / the ? operator. Same principle with less visual bloat.
- ngrilly 7y ago> On another note, I've been enjoying rust's approach with Result<T,E> / the ? operator. For the record, the `try` proposal which was just declined, is almost equivalent to the `try!` macro in Rust, which was the "testbed" for the `?` operator.
- segmondy 7y agoLack of try and go's error handling is part of my attraction to go. Explicit handling of error is much better than implicit and having to guess how things might get handled.
- ngrilly 7y agotry may have drawbacks but not this one. try is perfectly explicit. There is no implicit error propagation.
- RandomInteger4 7y ago"Do or do not. There is no try." ~ Golang master Yoda
- mvndaai 7y agoI think the proposal's intent was great but had some serious issues. I created my own proposal that I think addresses the issues. I would love some constructive feedback. https://github.com/golang/go/issues/33161 https://github.com/golang/go/issues/33161
- OnlyRepliesToBS 7y ago'this is our language, not yours'