Earlier quoted context omitted.
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.
Depending on code review instead of a static type system does not scale. Look at all of the memory safety security vulnerabilities that are solved by "simply making sure to manage memory correctly." Also: variableDefinedInAFarAwayModule := 17 ... TestSomething(variableDefinedInAFarAwayModule) It's not always as clear as a constant value being passed to an incorrect type.
What I'd like to see in Go 2.0
181–190 of 223 posts
Re: What I'd like to see in Go 2.0
#182Earlier quoted context omitted.
> user code could simulate non-deterministic I'm curious how? > Not vice versa There are pretty common patterns for this. At least for real word cases where you might have one special channel that you always want to check. Ugly, but in relation to the previous question, I don't see how one is doable and one isn't?
> > user code could simulate non-deterministic > I'm curious how? if rand.Intn(2) == 0 { select { case: chan3_whichItreatTheSameAsChan2 } } else { select { case: 0xFF ->chan3_whichItreatTheSameAsChan2 // a higher priority case: Yes, it increases verbosity to the other way, but no performance loss.
Re: What I'd like to see in Go 2.0
#183Earlier quoted context omitted.
I don’t understand why Scala chose “var” for mutable variables. A variable is not defined by being mutable—it is defined by being variable, i.e. not a constant. And it is immutable in math (where we don’t have to care about performance). So “val” is also a “var”, conceptually.
if it is not constant, it must be variable i.e. changing. Mutation = change.
In the line of code above, `y` is an immutable variable. It does not mutate, yet it "varies" as different values of x come in.
Re: What I'd like to see in Go 2.0
#184Earlier quoted context omitted.
Also, this isn't semantically correct. In order to ensure that `conditionaA` is _always_ preferred over `conditionB`, you must also check if `conditionA` has received a value inside of `conditionB`: select { case a :=
It would be easier to discuss with a more concrete example. If I ever had to write code like the above I would reconsider the design and try to come up with something simpler.
Honestly the whole first select seems redundant; any code that relies on this is broken as there's no other synchronization points to hang onto. You simply can't pretend the clock on the wall has anything to with the values transiting the program unless you introduce an actual synchronization point.
But OK, maybe you do have some strange performance case where this matters? In that case the whole thing could be more succinctly solved by looping on `for ctx.Err() == nil` instead of infinitely. Exactly as suggested at the start of the thread. (This would also likely be faster unless the context is under massive contention.)
It also leaks the timer until it fires if the context cancels, which seems like it would be more of a practical performance problem than any overhead to the additional select.
Re: What I'd like to see in Go 2.0
#185Earlier quoted context omitted.
No, they are very different conceptually. - A const is an abstracted value. - A variable is an allocated piece of memory.
Isn't that an implementation choice? Like in C++, a const is absolutely allocated since you can get a pointer to one. And then you can do horrible stuff like const_cast that pointer and mutate the value, and the possibility of that occurring prevents the compiler from doing certain const-related optimizations.
Re: What I'd like to see in Go 2.0
#186> Alternatively, Go 2.0 could implement "frozen" global variables A more general change would be to implement the "var" and "val" distinction that exists in some languages. const x = 1 // x is a compile time alias for the untyped abstract number 1 var x := 1 // define x at runtime to be (int)1, x is mutable val x := 1 // define x at runtime to be (int)1, x is immutable Then the globals can be defined with "val".
the val and const cases should hardly be different if the compiler has constant folding, except maybe for the typing.
> Constant expressions may contain only constant operands and are evaluated at compile time.
and a "const" can only be defined with a constant expression.
So the difference would be that a "val" can be assigned a value that is evaluated at runtime.
Re: What I'd like to see in Go 2.0
#187I'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…
type SignedInteger interface {
~int | ~int8 | ~int16 | ~int32 | ~int64
}
Interfaces that contain type sets are only allowed to be used in generic constraints. However, a future extension might permit the use of type sets in regular interface types:> We have proposed that constraints can embed some additional elements. With this proposal, any interface type that embeds anything other than an interface type can only be used as a constraint or as an embedded element in another constraint. A natural next step would be to permit using interface types that embed any type, or that embed these new elements, as an ordinary type, not just as a constraint.
> We are not proposing that today. But the rules for type sets and methods set above describe how they would behave. Any type that is an element of the type set could be assigned to such an interface type. A value of such an interface type would permit calling any member of the corresponding method set.
> This would permit a version of what other languages call sum types or union types. It would be a Go interface type to which only specific types could be assigned. Such an interface type could still take the value nil, of course, so it would not be quite the same as a typical sum type.
> In any case, this is something to consider in a future proposal, not this one.
This along with exhaustive type switches would bring Go something close to the sum types of Rust and Swift.
Re: What I'd like to see in Go 2.0
#188Earlier quoted context omitted.
Swift solved this problems with [non-exhaustive enums]( https://github.com/apple/swift-evolution/blob/main/proposals... ).
Is it solved? How do you decide which enums are final and which ones need to be non-exhaustive to allow evolving the code? I think that Go's decision stems from protocol buffers as they allow to push new values through old binaries, which is a must once you grow enough. https://developers.google.com/protocol-buffers/docs/proto3#e...
When clients use `switch` on a non-frozen enum from outside its defining module, Swift emits a warning if they don't have an `@unknown default:` case... so consumers of your enum will have to have default logic for handling new cases in order to avoid this warning. (Not for frozen enums though, for frozen ones it's enough to just cover the known cases in calling code, since the expectation will be that you can't update them.)
So basically, if you don't bother thinking much about the problem, you can just avoid adding `frozen` and you'll probably get reasonable behavior where you can add more cases later. Using `frozen` should only be the case if there is some sort of logical impossibility for there to be more cases. Something like how `Optional` has .some and .none, but it's pretty obvious that nobody's going to go add a new case to it (what would a new case even mean?) Same with Result, and probably a bunch of other types I can't think of at the moment.
Also worth noting that Swift treats intra-library code very differently than code that links from another library... if you use your own enums in your own module and don't make them public, it treats them as if they're always frozen... which is nice because it's your internal code and you can always update your own usages without having to worry about compatibility.
Re: What I'd like to see in Go 2.0
#189Earlier quoted context omitted.
Oooor the language can have proper type-safe enumerated types of some sort, and if you're in a domain where that's an issue you don't use them.
Go is focused on the distributed systems domain though. It's fine, even desirable, to have languages focused on particular domains, that make design decisions based on the constraints of the domain. In this domain, closed enums are footguns with costly consequences if you get it wrong.
Re: What I'd like to see in Go 2.0
#190Earlier quoted context omitted.
No, they are very different conceptually. - A const is an abstracted value. - A variable is an allocated piece of memory.
Isn't that an implementation choice? Like in C++, a const is absolutely allocated since you can get a pointer to one. And then you can do horrible stuff like const_cast that pointer and mutate the value, and the possibility of that occurring prevents the compiler from doing certain const-related optimizations.
If I understand you correctly, you claim you can get a pointer to a Go const. This is not the case. For example, the following code will not compile:
const a int = 1
var b *int = &a
./prog.go:5:15: cannot take the address of a
See https://go.dev/play/p/QPxP-tF6qIs for a live example.