I'd add one more to this list: proper enum types. We use enums heavily to force devs who use our code into good choices, but the options are currently: 1) Use int-type enums with iota: no human-readable error values, no compile-time guard against illegal enum values, no exhaustive `switch`, and no autogenerated ValidEnumValues for validation at runtime (we instead need to create ValidEnumValues and remember to update…
Personally I’ve run into more problems with strict enum types in distributed systems in a team setting, than I have with Go’s lack of them. In that setting, strict enums are usually over-strict and eventually you back yourself into a corner in terms of being able to roll out new enum values. When there’s no clear winner in terms of tradeoffs, I prefer to leave it out of the language like Go has done.
What I'd like to see in Go 2.0
61–70 of 223 posts
Re: What I'd like to see in Go 2.0
#62Earlier quoted context omitted.
I'm not sure what you mean. There's always going to be a race condition between ctx.Done and thingCh, just depending on whether there's data available. This race condition is unavoidable. I guess you're thinking of "what if thingCh and ctx.Done activate simultaneously?" There's no real difference between happening simultaneously and happening one after another. As for your other point, you can just write code like se…
Right, which is noted in the post. That verbosity is, well, verbose. I generally need this in 20% of things I write.
Re: What I'd like to see in Go 2.0
#63This is a great post, and I agree with much of what he said (range shouldn't copy - I would love a range that iterates by const-reference by default, to lift a phrase from C++). Deterministic select I hard disagree with. The code in the blog post is race-y, and needs to be fixed, not select. If anything, making select deterministic will introduce _more_ subtle bugs when developers rely on that behavior only to find o…
How would you fix that code?
for {
if _, ok :=
Which goes along w/ https://github.com/golang/go/wiki/CodeReviewComments#indent-... of "Indent error flow".edit: nvm, your break would be blocked until one of the other channels produced a value. you'd need to check for the doneCh redundantly again in the select.
Re: What I'd like to see in Go 2.0
#64Earlier quoted context omitted.
You should be able to use "replace" to use your forked module instead of the original and you don't have to change anything.
unfortunately replace is not supported well with modules. and they are hell bent on not supporting it well.
If you're doing some kind of global find/replace on fork, then something's definitely not right.
Re: What I'd like to see in Go 2.0
#65Re: What I'd like to see in Go 2.0
#66Earlier quoted context omitted.
I don't think you would need a 2.0 (backward-incompatible language change) for any of this.
Exhaustive switch seems likely to be backward incompatible if done well. What you want here is something akin to Rust's match behaviour on enumerated types. If your alternatives aren't exhaustive, it doesn't compile. Now, Rust is doing that because match is an expression . Your day matching expression needs a value if this is a Thursday, so not handling Thursday in your day matching expression is nonsense - even thou…
This would only make sense on an enum type, which would be a completely new thing, so it can be introduced without breaking backward compatibility. Constants and switch on non-enum values would stay, because they are useful independent of enum types.
Re: What I'd like to see in Go 2.0
#67Earlier quoted context omitted.
This compiles: type Test int const ( T1 Test = 0 T2 = 1 ) func TestSomething(t Test) {} ... TestSomething(17) So this isn't a good suggestion, because you can easily pass any int value and will not get a compiler error. You may as well be using strings at that point.
Fwiw a literal 17 in a function call, let alone anywhere outside an equation or constant definition is a code smell that should never make it past review. I see your point however.
Also:
variableDefinedInAFarAwayModule := 17
...
TestSomething(variableDefinedInAFarAwayModule)
It's not always as clear as a constant value being passed to an incorrect type.Re: What I'd like to see in Go 2.0
#68Earlier quoted context omitted.
> Use int-type enums with iota: […] no compile-time guard against illegal enum values Create a new int type and use that for your enums. While you still can create an illegal enum value, you basically have to be looking for trouble. It’s not going to happen accidentally. It’s even harder if it’s an unpunished type in a different package. See: https://github.com/donatj/sqlread/blob/91b4f07370d12d697d18a...
This compiles: type Test int const ( T1 Test = 0 T2 = 1 ) func TestSomething(t Test) {} ... TestSomething(17) So this isn't a good suggestion, because you can easily pass any int value and will not get a compiler error. You may as well be using strings at that point.
Other languages take a stricter approach, and maybe that's better. Not defending (although I like Go), but it's really more a language philosophy than a singular defect.
As the other commenter noted, this should fail code review and you should be using the provided constants, and it should be clear to you. And if you disagree (which again is totally valid), you should use a stricter language—there's plenty out there!
Re: What I'd like to see in Go 2.0
#69Can someone explain this one? I couldn't see why go gave this result. > What is the value of cp? If you said [A B C], sadly you are incorrect. The value of cp is actually: [C C C]
Re: What I'd like to see in Go 2.0
#70Earlier quoted context omitted.
> We use enums heavily to force devs who use our code into good choices Beware, tho, that with many languages today you’re not really doing that even when they advertise enums e.g. in both C# and C++, enums are not type-safe (not even `enum class`). Iota is, at least, a fair acknowledgement of that. > with a FromString() function That seems like way a step too far, is there any such “default method” today? And I don’…
Really not sure what you're talking about. If you use enums in a real language like Swift, Kotlin, Rust, etc., you can only construct the values of the enum. There are no ways to get around it.
Have you considered reading?