Live data from Hacker News

Go 1.21 Release Candidate

go.dev

111–120 of 236 posts

Re: Go 1.21 Release Candidate

#111
post #18

It is interesting to see them add things like the "clear" function for maps and slices after suggesting to simply loop and delete each key one at a time for so long. Is this a result of the generics work that makes implementation easier vs. the extra work of making a new "magic" function (like "make", etc.)?

From the spec [1], it was because the loop doesn't work to clear a map with a NaN key.

[1] https://github.com/golang/go/issues/56351

Re: Go 1.21 Release Candidate

#112

Earlier quoted context omitted.

If you already have your own functions or variables named max, min, or clear in-scope, they will shadow the new built-in functions and your code will continue to use your own version of the functions. No breakage to existing identifiers that match the new function names. (This is the same behavior as the append built-in function today, for example. These things in Go are _not_ reserved keywords, they are simply globa…

Lets be honest, its a terrible choice

In what way? Overall as a language, identifier shadowing is a feature of the language in nested scopes. Are you saying built-in identifiers (that aren't language keywords) should be treated specially and work differently than user-declared identifiers?

Re: Go 1.21 Release Candidate

#113
post #33

Wait is this now heap allocating a value in every iteration of every loop? I hope that allocation is optimized out in every case where there isn't a closure over the loop variable?

Regardless of how the compiler is optimising this, I 100% agree that the old behaviour is unexpected and it’s caught me at least once. Really happy to see this (until recently) unexpected change.

I don't actually use Go, but I have used many other languages where it is like the old behavior. I learned once that I have to build the closure correctly to get the value I want and know now to do it. Don't have any statistics on whether I made that mistake again, but anecdotally I can't remember a case where I have. In their analysis they have found a lot of cases with that mistake, though. So I guess fair enough.

However, I wonder what it will mean if someone who mostly writes Go will now use another language? Will they be more prone to make that mistake?

Re: Go 1.21 Release Candidate

#114
post #2

This is a big release. Lots of new packages. The language is changing

It is a big release, and the number of new stdlib packages (4) is relatively high for a Go release. That said, apart from the addition of some minor builtins (min, max, clear), the language isn't changing. That happened back in 1.18 with the introduction of generics.

Re: Go 1.21 Release Candidate

#115
post #104

Earlier quoted context omitted.

I wonder if it's possible to use slog in 1.20 already, is there a back-port? I'm changing logging on the service right now and it just makes sense to use it now , but entire service can't move to pre-release version of go.

Indeed it's in "golang.org/x/exp/slog"

https://pkg.go.dev/golang.org/x/exp/slog#hdr-Levels seems to fall into the same trap that drives me _starkraving_ about the 18,000 different(!) golang logging packages: there doesn't seem to be a sane way of influencing the log level at runtime if the author doesn't have the foresight/compassion to add a command-line flag or env-var to influence it. A similar complaint about the "haha I log json except this other dep that I import who logs using uber/zap so pffft if you try to parse stdout as json"

Re: Go 1.21 Release Candidate

#116

Earlier quoted context omitted.

That `clear` on a slice sets all values to their type's zero value is going to be extremely confusing especially coming from other languages (Rust, C#, C++, Java, ...) where the same-named function is used on list-ish types to set their length to zero. Doubly-so when `clear` on a map actually seems to follow the convention of removing all contained elements.

Sure, although as a Go user, the behavior described is exactly what I’d expect. These new functions are no different from functions that you could write yourself.

I'm a go user, and think it's dumb that:

    clear(f)
    fmt.Println(len(f))
will have different results if f is a slice and a map.

Re: Go 1.21 Release Candidate

#117

Why is map copy "dst, src" vs "src, dst"?

Copy operations in Go are normally destination first, source second. This includes builtins like copy() and library functions like io.Copy(). Making it "src, dest" would make this one case the opposite of all the others. Note that the order mimics variable assignment. You copy an integer with: var src, dest int dest = src // dest first, src second I appreciate the consistency.

[deleted]

Re: Go 1.21 Release Candidate

#119
post #63

Earlier quoted context omitted.

Making them builtins allows them to work as you’d expect with cases like, func clamp(x float64) float64 { return max(0, min(1, x)) } With ordinary functions, the arguments are assigned types too soon, and you get integer types for 0 and 1 in the above code. In C++ you might make the types explicit: template T clamp(T x) { return std::max (0, std::min (1, x)); } That’s not meant to be exactly the way you’d write these…

That doesn't seem to be true, unless I'm misunderstanding something. https://go.dev/play/p/ymM0tD3aGYg?v=gotip Obviously these sample functions don't take into account all the intricacies of float min/max functions.

You can

    const x = min(a, b)
assuming a and b are const.

Re: Go 1.21 Release Candidate

#120

Earlier quoted context omitted.

Sure, although as a Go user, the behavior described is exactly what I’d expect. These new functions are no different from functions that you could write yourself.

I'm a go user, and think it's dumb that: clear(f) fmt.Println(len(f)) will have different results if f is a slice and a map.

I guess, but that seems expected to me at this point, and consistent within the semantics of how slices and maps work (and other values).

Maps are kind of like

    type map *struct{ len int; ... }
Slices are kind of like

    type slice struct{ len int; ... }
We get a lot of convenience by having the pointers auto-dereferenced, but the cost is that the semantics are still different and there are no syntactic markers to remind us of the fact.

I don't think any language has really given us something that is completely intuitive here. Python's semantics with the list type are a constant surprise to newcomers. C++’s semantics surprise newcomers. Rust's semantics surprise newcomers. Surprises all around. The best you can hope for is something that is internally consistent.

The slice in Go is more or less equivalent to &[] in Rust or std::span in C++. The whole idea of passing a pointer by value is key to understanding the semantics of most modern programming languages. Like, is Java pass-by-value or pass-by-reference? You can argue the point, but whatever label you decide is appropriate for Java, it’s useful to think of Java as passing pointers by value. Same with Python, Rust, Go, etc. This is not intuitive for people who are new to programming.

Post reply on HN