7 ms·
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
by nu11ptr 3y ago
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.)?
- Waterluvian 3y agoIt might also be that they’ve worked their way down the priority list and are getting to these features that are largely just to tidy up code.
- stefan_ 3y agoClearing a container is usually a much simpler and faster operation than looping through all and removing them individually. That's not a question of tidying something up.
- onionisafruit 3y agoThere were compiler optimizations for clearing by iterating. I haven’t looked at the code, but I suspect this won’t be much more efficient than iterating was with the optimizations.
- yencabulator 3y agoI expect both will result in the same code; the only difference is that the clear built-in can handle maps with NaN keys.
- maximilianburke 3y agoThat `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.
- klodolph 3y agoSure, 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.
- Jabbles 3y agoThe builtin clear() will handle cases like deleting NaN from a map.
- maccard 3y agoI'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.
- klodolph 3y agoI 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.
- steveklabnik 3y ago> The slice in Go is more or less equivalent to &[] in Rust or std::span in C++. My understanding is, to use the Rust/C++ term, slices in Go are owned, but they are not in Rust or C++. That is, they're a pointer + length in the latter two, but a pointer, length, and capacity in Go.
- philosopher1234 3y agoOne aspect of this is that it was formerly impossible to delete NaNs from a map[float64]T, unless you had the nan already.
- earthboundkid 3y agoEven with the NaN, the NaN wasn't equal to itself, so it still wouldn't delete. Really, they just should have forbidden float64 key'd maps, but too late for that, I guess.
- alex_lav 3y ago> 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. Slowly walking back dogmatic positions is just how the Go team works. I say this as a person that wrote Go full time for a handful of years.
- yencabulator 3y agoNo, it's because a use case was discovered that the for loop approach can't handle: NaN keys.
- alex_lav 3y agoI would argue Go's inability to manage NaN keys is irrelevant to the desire for "clear", in that I would argue that the NaN keys issue should be fixed _regardless_ of clear.
- stouset 3y agoIn my experience, that's exactly how this plays out every single time. Dev: Can we have a function to clear a map? Go: No, it's easy enough to write the 5 lines of code to just do it yourself every time. Dev: Okay, I don't see why I should have to write those 5 lines every time but fine. Isn't looping over everything going to be slower than just… having a function that can empty the internals? Go: We've implemented a compiler optimization to detect this and rewrite it to the faster code it would have been if it we were to implement it. Dev: Isn't that… way harder than just writing the method? Anyway, I noticed this solution doesn't actually always work because of this edge case. Go: Just handle the edge case every time then. Dev: That's the point. I can't. And around and around we go.
- alex_lav 3y agoI used to really like Go. Now that I don't work with it, I find that the further I go on without it, and with using other tools, the less and less I'd want to go back.
- 3y ago
- skybrian 3y agoFrom 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 https://github.com/golang/go/issues/56351
- deleted 3y ago[deleted]
- slantedview 3y ago> after suggesting to simply loop and delete each key one at a time for so long Those were always bad alternatives to a real design problem, they just didn't have a good alternative to offer at the time.