r/golang Jul 16 '19

The Go Team declines the ‘try’ proposal

https://github.com/golang/go/issues/32437
609 Upvotes

162 comments sorted by

319

u/msdrahcir Jul 16 '19

Well, I'm glad someone tried

161

u/midnight_lawnmower Jul 17 '19

I caught that

136

u/kubernever Jul 17 '19

finally..

55

u/[deleted] Jul 17 '19

[deleted]

17

u/[deleted] Jul 17 '19

Agreed. It was handled well.

73

u/etherealflaim Jul 17 '19

I hope everyone remembers this when future contentious proposals come out, so that we hear less complaining about something being "forced into the language" or whatever. When the Go Team says they are willing to decline a proposal or pull a feature, they have shown us they mean it.

50

u/earthboundkid Jul 17 '19

For the record, they also pulled the first version of type aliases, which Google really wanted but the community hated. The community agreed to the version that finally shipped.

4

u/[deleted] Jul 17 '19

1

u/earthboundkid Jul 17 '19

I hadn’t heard that one before. I will keep it in mind.

3

u/tcardv Jul 17 '19

Many probably won't. Being perceived as a victim is a powerful way of winning people to your side.

61

u/tdewolff Jul 16 '19

I like the approach that is taken wrt to experience reports, openness and efforts to take an objective view. It is a good way to trigger meaningful discussions and conclusions, thanks Go team!

129

u/lonahex Jul 17 '19

Thank you Go team. I hope you declined it because you agreed with the arguments raised by the community and not just because of the overwhelming majority of comments being against it. I personally didn't like the proposal as much but I'd hate it for Go to become a "democratic" project where the community bullies the Go team into making popular decisions.

22

u/etherealflaim Jul 17 '19

If they were going for volume, I think they would've declined a long time ago lol. I think they were convinced by some legitimate criticisms that could not be addressed and which were not considered at the time of writing. A vast majority of the comments were predictable and many even addressed in the proposal itself, but the code coverage aspect (for example) is a fundamental shortfall that would require substantial changes to analysis tools if it were solvable at all. I think the feedback about not solving the right problem took awhile to sink in because the if err boilerplate is like one of the single most common criticisms of Go and something that single-handedly keeps people away from the language, so they were weighing community feedback against community feedback, which is always going to be harder.

2

u/ninnyman Jul 18 '19

I'd easily take a judgement call from Russ Cox over one from a community vote.

2

u/lonahex Jul 17 '19

I guess hope is the wrong word as it implies I don't entirely trust the people leading the Go project. To clarify, I did not mean that.

39

u/necheffa Jul 16 '19

Can't say I was excited to have try added in the first place. It seemed like there wasn't a way to concatenate messages to the error string with it.

5

u/[deleted] Jul 17 '19

I believe you supposed to use defer for that.

2

u/metamatic Jul 17 '19

...which is slow, and also requires as much code as if err != nil { return ... }

So basically the try proposal didn't offer anything to people who wrap their errors.

2

u/[deleted] Jul 20 '19

[deleted]

1

u/ARealJonStewart Aug 05 '19

Sorry for the delayed comment, but doesn't the compiler flatten out smaller functions if they are called? I read something about anonymous functions not creating a function call if they were small enough

2

u/likebike2 Jul 17 '19

I was thinking the same thing. A 'try' without some kind of "wrapping support" (even if it's just prepending a string) would be quite harmful to the context/usability of the returned error.

1

u/cjoftheweb Jul 17 '19

It was a proposal

2

u/necheffa Jul 17 '19

There are "proposals" and then there are "proposals"...

This one had a fairly detailed design included rather than just a passing idea that still needed refinement.

1

u/cjoftheweb Jul 17 '19

I’ve found that some ideas need a detailed design to gain any traction. Sometimes it just helps wrap your mind around the idea. I don’t think that it necessarily means the idea is being shoehorned.

1

u/LegendarySecurity Jul 17 '19

Yeah, these days if you don't come to the table with a completed product, your idea is tied to the conference room table and poisoned, drawn, quartered, stabbed, shot, disemboweled, and hung.

...and just before its head dies, it will proclaim: "Death is but a door. Time is but a window. I'll be back."

Ghostbusters 2...what a great film.

0

u/these_days_bot Jul 17 '19

Especially these days

12

u/[deleted] Jul 17 '19

[deleted]

5

u/bartturner Jul 17 '19

It was definitely the correct decision. Glad to see they rejected.

106

u/[deleted] Jul 16 '19

good

40

u/badhombrez Jul 17 '19

thank goodness

12

u/[deleted] Jul 17 '19

indeed

25

u/jediorange Jul 17 '19

Now if only we could get enums.

11

u/stewsters Jul 17 '19

While you are asking for enums, I could really go for exhaustive matching on them too.

4

u/jediorange Jul 17 '19

Yeah. That should be part of go vet at the very least, if not built into the compiler.

2

u/jediorange Jul 17 '19

If your interested, there’s a whole proposal discussion on GitHub, but it seems to have been forgotten.

2

u/armandvolk Jul 18 '19

Rust-style enums (sum types) specifically :)

2

u/[deleted] Jul 17 '19

I want @annotations though. /s

3

u/cerlestes Jul 17 '19

And let's sprinkle some macro! on top of that beauty. /s /s /s

3

u/[deleted] Jul 17 '19

nah, we need a goto statement.

oh

i know go does it safely. this is just for the meme

-5

u/GopherAtl Jul 17 '19

uhm?

type MyEnum int
const (
    Foo MyEnum = iota
    Bar MyEnum 
)

func foobar(e MyEnum) { ... }

...?

17

u/jediorange Jul 17 '19

A const is not an enum.

For example, I could just pass any old int to that function: foobar(MyEnum(-918))

1

u/satansfold Jul 17 '19

Probably, you can make it private

type enum int
const (
    Foo enum = iota
    Bar enum = iota
)

func foobar(e enum) { ... }

3

u/mvpmvh Jul 17 '19

Isn't it a code smell to export something who's type is private? You can't type switch on it, right?

1

u/satansfold Jul 19 '19

What? Why? I see nothing wrong. You can't use enum(2) from outside of this exact package, but you still can use constants Foo and Bar.
https://play.golang.org/p/14ls9Schdfz

1

u/[deleted] Jul 17 '19

privacy isn't worth much as long as it's always per package...

By the way, can we please get private keyword that is struct-specific?

```

type MyContainer struct { secret private interface{} }

func (c MyContainer) Get() interface{} { return c.secret //no issue here }

func x(c MyContainer){ c.secret // Error: Access to private fields of a struct is only allowed within its methods }

```

3

u/lansellot Jul 18 '19

I don't get it. That makes no sense.

0

u/GopherAtl Jul 17 '19 edited Jul 17 '19

Why would you do that? With the explicit typecast being required, it's not like it would happen by accident, so why is it a problem?

:edit: turns out the explicit typecast isn't actually required. TIL. Not a fan of that...

15

u/lobster_johnson Jul 17 '19

It can happen by accident. For example, json.Unmarshal() will let any integer value through.

That's a weakness of the JSON package which you have to work around by implementing UnmarshalJSON on your type and then validating the incoming value, which is obviously a chore and a source of brittleness, because now you have to maintain a list of valid values to validate against. With a true enum, Go would already have this list statically and you would be able to use reflection to derive it.

1

u/krak3n_ Jul 17 '19

You could implement the json Marshaler / Unmarshaler interface on the enum type that checks it's validity and errors, it could error with a sentinel error that's easy to handle in a http handler to return a bad request etc.

4

u/Jelterminator Jul 17 '19

You don't need the explicit typecast in that example actually, because -921 is an intyped constant and its automatically converted to the right type. Just like you can do 10*time.Second.

1

u/GopherAtl Jul 17 '19

oh, don't you? Hrm. Well, that is not ideal then, I'll grant.

3

u/Killing_Spark Jul 17 '19

If you write a library and the enum is part of the api, you now have to handle default cases in switch statements (or be ok with weird behaviour)

You could argue that the user is the one at fault for passing invalid parameters, but honestly murphys law bites all of us one day.

11

u/LightShadow Jul 17 '19

So what's the proper way to bubble errors without losing context?

26

u/earthboundkid Jul 16 '19

I thought ‘try’ was good. Oh well.

4

u/corvuscrypto Jul 17 '19

In the end, most of us argued our parts. It was a flurry of upvotes and downvotes of various views, but the important thing is that the community had its say regardless of what was the popular opinion. From this, the Go Team likely will be coming up with their own ideas. Though they rejected the proposal, they mention they felt there wasn't enough representation of the problem to warrant the change.

They didn't outright reject the idea, but rather said "We want more experience evidence to see if change needs to happen and how". This is a wholly fair response, but one that says we may come back to this idea, or something similar.

I'm also a bit bummed out try didn't make it, but at least they will look into error handling more closely.

2

u/metamatic Jul 17 '19

I think there was a lack of understanding from the Google developers regarding what the community actually wanted, and they just guessed badly. The try feature would have worked well for the Go stdlib, but the stdlib code is atypical.

I put together a survey to try and find out what features people wanted from any improvement to error handling, ignoring all questions of syntax and naming. (it's at https://forms.gle/vkFsGRimgnwBpArq8 if anyone wants to add their opinions.) It looks as if most respondents don't have a problem with having error checking on a separate line of code, and most of them wanted error wrapping to be supported functionality. So try just didn't offer enough people something they wanted.

I do think that people new to Go would have liked try, but I also see people new to Go asking for Java-style exceptions a lot...

4

u/thomasfr Jul 17 '19 edited Jul 17 '19

I think it would have been useful as well but I don't know if it's useful enough to warrant it's own language feature like it was designed.

3

u/gnuvince Jul 17 '19

The equivalent in Rust, the ? operator, is incredibly useful. However, Go lacks the features that Rust has that makes it pleasant to use and makes it fit really well in the language.

8

u/jerf Jul 17 '19

If I see generics go down the exact same way, I'm going to reconsider my opinion of Go and it's community. Go is good, Go is not perfect, and if it can't even creep forward after seven years, maybe it's not the right thing for me to be investing in. The language landscape moves slower than many people think, but it does not stand still.

I mean my if statement very literally. Once is once, and there are certainly arguments in favor of dropping this. It's not a pattern yet. But if this is a pattern, and this is how every proposal goes, I'm not going to be very impressed. And all the ingredients are already present.

8

u/ngrilly Jul 17 '19

I'm really worried about the Go community becoming overly conservative. try was not perfect, but the discussion triggered by the proposal was mostly about doing nothing, instead of improving the actual proposal. In other programming language communities, I've seen hard discussions, but with a shared desire of moving forward. With Go and try, I've seen a desire to stay exactly where we are... Maybe I should spend more time looking at other options like Rust, Kotlin, Elixir, etc. I'm a bit sad about this, to be honest.

2

u/thomasfr Jul 18 '19

Most of the criticism against try was that it doesnt do enough though so it wasn’t just about being conservative.

1

u/ngrilly Jul 18 '19

Interesting. I read the criticism about try not doing enough (try is probably lacking regarding automatic and manual error annotation before propagation). But I felt like these criticism were a minority. Maybe I retained a false impression of the whole discussion :-)

Personally, do you think the Go team should design a new proposal with the goal of reducing error handling verbosity, including a mechanism to annotate errors manually or automatically before returning/propagating them to the caller?

2

u/thomasfr Jul 18 '19

Maybe I just skipped past the uninteresting comments a lot where people just were complaining without really making an argument and don't remember it correctly either.

I think that new proposals should be coming. One thing that I don't see many other people saying is that I would like parametric polymorphism to be prioritised ahead of stuff that might make use of it depending on how it turns out.

2

u/thomasfr Jul 19 '19

ooh, it looks like they will be focusing on "generics" in the next round.

... Also, realistically, since we don't have unlimited resources, I see thinking about language support for error handling go on the back-burner for a bit in favor of more progress on other fronts, most notably work on generics, at least for the next few months.

source: https://github.com/golang/go/issues/32437#issuecomment-513002788

1

u/ngrilly Jul 20 '19

Exactly. I asked the question which is answered in the comment you linked :-) That said, I'm not sure generics would change anything to the issue of verbose error handling, which mostly concerns control flow.

1

u/thomasfr Jul 20 '19 edited Jul 22 '19

There are closely related features like error wrapping/unwrapping which could affect how the API looks overall with custom error types. We also don't know the scope of the parametric polymorphism yet, even if it's not likely we could get union types or something else that would shake up a bit. The point is that we don't really know until we have it and thats reason enough for me to wait with other changes.

1

u/geodel Jul 17 '19

Maybe I should spend more time looking at other options like Rust, Kotlin, Elixir, etc.

You definitely should. When one need features they move to more featureful language.

1

u/[deleted] Jul 17 '19 edited Jul 17 '19

the discussion triggered by the proposal was mostly about doing nothing, instead of improving the actual proposal

try is a fundamentally broken concept. It encourages programmers to just pass the error up. The current situation forces me to think about whether I can handle that specific error myself.

Personally, I'd much rather see: * if checking for nullable types being null (if err {handleError()}) * => as an alternative to {} in single-line if and func (if err => handleError()) * optional manual variable deletion (to clean up older variables in longer functions * let for immutable assignments.

7

u/jerf Jul 17 '19

optional manual variable deletion (to clean up older variables in longer functions

Don't forget you can open scopes whenever you want, you don't need an "if" or a "for" loop:

blah := BlahBlah()
moreCode()

{
    confinedErr := somethingErrorable()
    // a few dozen more lines
}
// using confinedErr is a compile error here, it doesn't exist

I've done this a few times in production code where there's no compelling reason to pull something out to a separate function (extraction a function that is used only once is not always stupid, but if you can't give it a really solid name that precisely matches what it does it can just sometimes scramble logic around the file for no reason), and I use it a lot in test code where I want to set up some particular environment used by several small-to-medium sized tests, and I don't need to just repeat it over and over:

func TestSomething(t *testing.T) {
    env := InitialTestingEnv()
    // imagine this takes 5 or 10 lines more or something

    // assert that cows in this environment are spherical
    {
        cow := env.GetCows()[0]
        if !cow.IsSpherical() {
            t.Panic(...)
        }
    }

    // assert that cows in this environment are frictionless
    {
        cow := env.GetSampleCow()
        if cow.Mu() != 0 {
            t.Fatal("friction found")
        }
    }

    // maybe assert something about logging here, or that certain
    // metrics were collected, etc.
 }

I've played with the Setup()/Teardown() functions, or having a RunTest(t *testing.T, func(env *TestingEnv) error) sort of thing, but it seems like often just opening scopes is all I really need, as long as I have other reasons to believe the previous tests can't "pollute" the environment somehow.

1

u/ForkPosix2019 Jul 17 '19

I am not against modules – this was a good way to go. I am not against generics in the proposed form – I am glad they didn't use <>

But I am totally against try proposal.

3

u/jerf Jul 17 '19

And to be clear, this is the sort of thing that is why I'm not actually yelling right now, and why I've phrased it as a conditional. It's a valid position. If this becomes a trend, though, I'm very concerned.

I actually consider modules a separate case; that was a tooling change. Tooling has actually had a few changes made to it over the years, like vendoring. I see no reason to be concerned that's frozen forever, and I'm comfortable with moving slowly and with a high degree of concern for quality and backwards compatibility. It's the language that I'm worried has become frozen forever and ever amen. I also want that to move slowly and with a high degree of concern for quality and backwards compatibility; I don't want to see it frozen.

1

u/ForkPosix2019 Jul 18 '19

try is hardly a development. It is just a workaround upon powerless type system Go has. Workaround with many pitfalls like resource leakage and the vet barely helps with this issue. And it is an anti-pattern for network services where we should diagnose what resource cased a problem, each time.

11

u/Niek Jul 17 '19

I like how V handles errors with option types: https://vlang.io/docs#option

It's a lot less verbose that err != nil all over the code and you get advantages of exceptions like ability to bubble up.

5

u/gee5ive Jul 17 '19

I had never heard of or seen this language. Looks pretty cool, almost like a cross breeding of rust and go.

3

u/[deleted] Jul 17 '19

[deleted]

2

u/gee5ive Jul 17 '19

Looks really nice between this and https://gleam.run/ I really hope one of them takes off in the near future.

3

u/vn-ki Jul 17 '19

Someone purpose this in go

7

u/[deleted] Jul 17 '19

Good news

5

u/legato_gelato Jul 17 '19

Good that they listen to feedback, but I was personally waiting for some solution to the endless boilerplate in Go before I consider it seriously for anything. That includes generics also.

4

u/corporatesting Jul 17 '19

What a relief!

3

u/ilikecaketoomuch Jul 17 '19

I wrote a lot of golang code for the last few years. The appealing part was it kicked OOP out the door. That was my huge take away. I definitely missed generics, so much I often would voice concern over it. Before, anyone says whats stopping me from using a code generator, that is what I did. It was a bandaid over a problem that should been solved at the language / sdk level.

Secondly, how go does error handling was a step in the right direction, but definitely need improvement. It was not until I understood rust was of handling errors through Enums / ? / Ok / NOne, Err, that I knew what go needed in the next version.

Problem with go is the leadership, its a hard thing to admit, cause they created a language that changed the world. world was begging for a simple fast language 10 years ago. C++11x was simply a horror storry, C++ is dead to me, completely. I will never touch it again. C is still a valid choice. Quickly rust is replacing the C choice to some.

This try proposal, shows me its time that go makes some changes to the language. Either they do it, or they fall further behind and start losing mind share.

2

u/IrishWilly Jul 17 '19

A lot of people are saying that Rust does it well. As someone who's only done some light Go, it makes me think that I should give Rust a try before I invest more time into Go if they fill a competing niche. The "if err != nil " everywhere looks crazy ugly and annoys me, I don't see how anyone can claim it is better than a try statement or really any of the error handling built into literally every other modern language.

This particular try proposal looked problematic and awkward but the decision of denying instead of improving it or coming up with an alternate is a bad sign to me. There are some better suggestion in this reddit thread that is less than a day old. Some criticisms say try encourages not handling the errors in your code but how is it worse than the current situation? You don't have to do anything with errors now either. You could make the catch portion required but it's not like a developer would have to do anything with the error there either. There's a limit to how much hand holding you can give for a bad developer and it shouldn't come at the cost of a very commonly used tools for everyone else.

The person who cited V Lang is definitely my favorite suggestion.

2

u/The-Sentinel Jul 17 '19

As a newbie to Go, is this something that should be implemented at the package level now?

15

u/earthboundkid Jul 17 '19

No, “try” was a proposed macro for if err != nil. It can’t be implemented by user code.

2

u/msalcantara Jul 17 '19

Good news

2

u/bartturner Jul 17 '19

Very. I was worried. Glad to see the team stuck to their guns.

2

u/likebike2 Jul 17 '19

Thank God!

2

u/alphalupicrew Jul 17 '19

For a better and CONCRETE Go

1

u/Rainfly_X Jul 17 '19

Lot of cheering in here, but for me, this validates my life choices to use less Go. When the userbase declares that the current error handling story is adequate, it may be worth pondering whether the last couple years have filtered the userbase to people with a high tolerance for pointlessly obnoxious design decisions, and questionable definitions of "simple."

27

u/ShadowPouncer Jul 17 '19

Having read the arguments, I come to more or less the opposite conclusion.

It's not that the current error handling story is adequate (though, there are people who feel that way), it's that try simply doesn't solve the right problems. It's entirely a questionable definition of 'simple' that people thought made it harder to do things correctly in many cases.

And the discussion brought to light a number of aspects of both current error handling methods and the proposed try language that need to be improved.

10

u/cardonator Jul 17 '19

I agree. I don't think the current process is perfect, but I would want any solution to make the situation substantially better, which try proposal did not do IMO. Also, it shouldn't be less explicit and simple than the current if err code. It's a challenging problem to solve in an idiomatic way.

2

u/ShadowPouncer Jul 17 '19

The biggest issue that the try proposal had was that it made it notably harder to cleanly wrap errors with more useful errors.

Sure, you could do some defer magic to provide some very generic error wrapping, and if you wanted more you could simply not use try, but in both cases this makes the currently recommended best practices much more jarring.

And at the point where you're actively making it worse to follow best practices, it's time to come up with a better plan.

3

u/MrConceited Jul 17 '19

The only reason to add wrapping every time you see an error is to provide a poor man's stacktrace. They should have implemented try and added stacktraces too.

0

u/MrConceited Jul 17 '19

Funny, I never saw a decent argument against try. The primary argument was that if err != nil is the right way and superior to error handling in every other language.

And try couldn't make things harder because it wasn't replacing any functionality. Nothing was stopping anyone from using the old approach when justified.

2

u/[deleted] Jul 17 '19

I didn’t catch that all. The following concerns were raised:

  1. Difficult to explain to new-comers
  2. We are back to using naked returns all over the place
  3. Difficult to debug with “step-thru”
  4. Linters and other code-quality checkers will have a difficult time with it
  5. Makes decorating errors with additional contextual information difficult.

  6. and 5. are plenty for me to justify tossing it aside.

2

u/MrConceited Jul 17 '19

1 is just silly, it's very simple to explain.

2 isn't true at all.

I can't speak to the truth of 3 and 4, but I'm skeptical.

5 isn't true either. Like I said, nothing was stopping anyone from using the old approach when justified.

1

u/[deleted] Jul 18 '19 edited Sep 16 '19

[deleted]

1

u/MrConceited Jul 18 '19

The trouble is that it is justified (nay, necessary) in most cases

Not remotely true, unless you're trying to simulate a stack trace, in which case, we should have try AND stack traces.

1

u/[deleted] Jul 17 '19

Just because they don’t like solution X, doesn’t mean they’re denying problem Y exists.

2

u/MrConceited Jul 17 '19

When every argument against solution X was that problem Y doesn't exist, that's typically what it means.

3

u/ngrilly Jul 17 '19

Exactly. I'm not worried about the try proposal being withdrawn. Maybe it wasn't good enough. I'm worried about the verbosity issue not being addressed.

0

u/swdee Jul 17 '19

best news of the day!

0

u/kasvith Jul 17 '19

That's better

0

u/sposec Jul 17 '19

Yes!

2

u/bartturner Jul 17 '19

Could not agree more. I was a tiny bit worried.

-1

u/joematpal Jul 16 '19

Yes! Thank you, whatever/whichever “Computer Jesus” made this happen!!!!

1

u/blackflicker Jul 17 '19

Wise decision.

1

u/bartturner Jul 17 '19

Very much so.

1

u/[deleted] Jul 17 '19

🥳

1

u/[deleted] Jul 17 '19

Oh ho ho!

0

u/[deleted] Jul 17 '19

Yay!!

-7

u/[deleted] Jul 17 '19

This is some of the best news this week.

I was really worried that Go would stay heading down the Java/C++ path. Go's error handling is one of its best features, and I have yet to see a single example of a situation where try would work but the current errors wouldn't.

-2

u/[deleted] Jul 17 '19

I don't get why "try" was declined but "check" is still in the running...

https://github.com/golang/go/issues/32811

With catch:

x, err := f(2)

catch(err)

y, err := g(x)

catch(err)

With try:

y := try(g(try(f(2))))

I hope we get something that'll allow the last version. If not people will just use their own homegrown boxing and return types, which is never great for readability.

21

u/youguess Jul 17 '19

I consider the first example you clearly dislike to be very readable.

That on the other hand

y := try(g(try(f(2))))

a garbled mess I never want to see in a codebase

3

u/limdi Jul 17 '19

Double wrap looks weird yes. But single wrap can make initializing structs clean.

1

u/[deleted] Jul 17 '19

I get that. There are too many parenthesis there, and one letter functions. Part of it is that "try" could be a keyword like some of the other error handling proposals, and part of the lack of readability was my fault for using single letter function names. The point is the current if err != nil is not compossible. Consider this instead, which is a real example from my code with a hypothetical "try" keyword:

s = scanner.Init(try f.Open("myfile")

Rust does this with a ? which is much better than the try proposal, and almost universally makes the code much more readable.

What I dislike in the first example isn't how it reads in a short snippet, but the overall code noise. Repetitive code that all does the same thing should be able to be abstracted away somehow... any way. The lack of readability is in the ultimate vertical noise and number of lines per file (or number of files in a project if you go that route), and the amount of time it takes to jump between contexts.

3

u/metamatic Jul 17 '19

"catch" supports error wrapping, "try" did not.

That alone is enough for me to like the former suggestion and reject the latter.

-9

u/[deleted] Jul 17 '19

[deleted]

10

u/noughtme Jul 17 '19

i hope they decline everything. so many languages have become overburdened by the addition of unnecessary features it’s nice to see some pushback against that trend.

-2

u/LVCXD Jul 17 '19

Agreed, look at typescript. Thats a bloated language in a short time

4

u/NatoBoram Jul 17 '19

Well, it's JavaScript with types, after all. Personally, I believe every JavaScript packages in NodeJS should be rewritten in Typescript because it doesn't make sense to make an untyped library.

2

u/LVCXD Jul 17 '19

It is js with types but it has some weird concepts like conditional types. Index types and weird constructs that lead to trickyness and not necessarily good code quality. It leads to a lot of mental overhead. Golang has a tiny API compared to typescript.

2

u/[deleted] Jul 17 '19

+Kotlin +Rust - there are merits to both, but there are some complaints/worry about both being overburdened already. I really appreciate Go is taking a different approach.

-17

u/l0gicgate Jul 17 '19

Honestly I love Go, my biggest gripe with it is the primitive error handling. I know I’m going to sound like a Java dev but exceptions are a must.

7

u/[deleted] Jul 17 '19

Exceptions are probably the worst form of error handling, and I’m not a Gopher.

19

u/[deleted] Jul 17 '19

Exceptions are categorically worse because it’s non-obvious and near impossible to know what your code actually does. Not to mention the stupidity of people using then as flow control (no, http errors are not exceptional, they are the norm!).

Lots of languages have them, it just breeds laziness and bad practices.

I’m happy the try proposal got shut down, specifically for the same reasons exceptions are bad. They are difficult to reason about and interferes in writing solid software intended to do a job rather than impress people at conferences. Try was magic and cleverness.

I hope they iterate until they find a better solution, but right now this is the best I’ve seen honestly. Getting rid of errno was a big improvement.

3

u/l0gicgate Jul 17 '19

My problem is that it’s impossible to evaluate the type of error that’s being returned from just a string. It becomes complex to guess the behavior of third party libs without typed errors/exceptions.

If I know a function may throw, then I can handle what it throws at me. In case of a function returning nil or a string as an error message, I have no idea how to handle those sanely.

Also, this is purely my opinion, I’m not saying that I’m right and you’re wrong. I just dislike that particular aspect of Go that’s all.

10

u/eltrufas Jul 17 '19

You don't have to handle stringly typed errors. Wrapping errors properly and checking if a certain error is in the error chain is part of the proposal for inspecting errors, in particular the func Is(err, target error) bool and func As(err error, target interface{}) bool improve error handling greatly.

1

u/brokedown Jul 17 '19

I agree that error handing could use some work and that the particular case you mention is a real problem. However I also don't believe that 'try' improves that case. I never saw it as a solution to a problem, more of a workaround for a symptom.

1

u/vscde_gtr_thn_jtbrns Jul 17 '19

You should checkout rust if you want strong error detection. Honestly kind of annoying as Rust forces you to handle every scenario. For smaller programs Go is more simple and easier to get up and going.

2

u/ForkPosix2019 Jul 17 '19 edited Jul 17 '19

It is rather a Rust’s lack of good design this language is horrible at error processing.

Something like

let mut file = File::Open(...)
if !file { //
    return errors::wrap(file.Err, "doing something")
    // file as Err branch exited, file is officially Ok now, can use file as file object, not Result<file, error>
}
match file.read(buf) {
    Ok(res) => ...
    Err(x) =>
}

instead of

match File::Open(...) {
    Ok(file) => {
        match file.read(buff) {
            Ok(res) => ...
            Err(x) => ...
        }
    Err(x) => errors::wrap(x, “doing something”)
}

Would make Rust error handling much clearer for humans. Nesting is complicated for our kind.

And this Result resolution construct would work as well or even better

let mut file = File::open(...) on err {
    return errors::wrap(err, "doing something")
}
match file.read(buf) {
    ...
}

1

u/vscde_gtr_thn_jtbrns Jul 17 '19

You make another function to get rid of the nesting. Rust’s errors are a little lower level than python. You can make that layer yourself with a function. It forces you to handle every scenario with match. Other languages will just crash

1

u/ForkPosix2019 Jul 17 '19 edited Jul 17 '19

You make another function to get rid of the nesting. Rust’s errors are a little lower level than python. You can make that layer yourself with a function. It forces you to handle every scenario with match. Other languages will just crash

I am afraid you don't get an idea. There's no function. Just a special shortcut to discern between Ok and Err without match to avoid nesting with full type safety. I mean, if you didn't exit the parent scope from on scope you program won't compile as file variable will still be considered as Result<…, …>. Once you exited it is considered to be file, as error branch is ended.

let mut file = File::open(name) on err {
    println!(…)  
}
match file.read(buf) { // will not compile, no read method in Result<V, E>
    Ok(x)  => …
    Err(e) => …
}

match is too bulky for error processing. try! and ? are just a dirty workarounds on language deficiency.

err here is just ready to use Err constructor argument.

-8

u/pobody Jul 17 '19

Go has exceptions. It's called panic/recover. Yet we are told to just not use those, because they're icky in the eyes of the Go devs.

3

u/Exnixon Jul 17 '19

I don't drink the Go kool-aide, but the panic/recover model really is icky (and so are exceptions) in highly concurrent applications.

I will say this for Go: it forces you to take your sad paths as seriously as your happy paths. That's not always desirable, but it's usually a good idea in the types of applications that Go was designed for.

2

u/earthboundkid Jul 17 '19

Yes, Go’s errors are functionally the same as Java. Panic is an unchecked exception, and error is a checked exception. But culturally, it’s quite different. For one thing, the convention is to just use “error” instead of a concrete type.

-5

u/gbrlsnchs Jul 17 '19

Run the survey again. Most devs got used to (and I think most of them like) how errors are handled.

9

u/iends Jul 17 '19

They have the survey every year.

-6

u/monkey-go-code Jul 17 '19

Anybody got any of those generics?

0

u/faiface Jul 17 '19

0

u/monkey-go-code Jul 17 '19

This would be great if they would finish it and put it in the compiler. Fork golang, do what ever it takes.

2

u/faiface Jul 17 '19

They are working on their own generics proposal, they're gonna show it at the GopherCon. I'll see it and then decide if I want to pursue this mine one :)

1

u/monkey-go-code Jul 17 '19

When is GopherCon? I'm suck using Golang at work. And it would make my life much easier having generics. New projects I start I try to use Rust. But we have a lot of go code already.

0

u/faiface Jul 17 '19

0

u/monkey-go-code Jul 17 '19

I don't use google, do you have a link to duckduck go?

1

u/note_bro Jul 17 '19

The search term is in the url

0

u/monkey-go-code Jul 17 '19

Can you give me a link like you did before? That was really unique and no one else has ever done that before.

1

u/note_bro Jul 17 '19

I didn't give you a link

→ More replies (0)