News for hackers. Stuff that matters.
Re:Go 1.18 by randomswede on Wednesday March 16, 2022 @04:50AM (#30696621)
There is a slight difference between the two. With a map[†]bool, you can do something like:

if myset[thing] { ... }

With a map[T]struct(), you end up with:

if _, ok := myset[thing]; ok { ... }

Sometimes, the saving in space is TOTALLY worth the extra verbosity. Sometimes, the slight clarity from "non-existent keys return the zero value" wins.

Re:Go 1.18 by thegeekpirate on Wednesday March 16, 2022 @05:58AM (#30696975)
You've also opened yourself up to bugs by allowing the map values to be "false".

Using a "set's" value in an if statement doesn't make sense either, compared to

    if _, exists := something[item]; exists { ... }
which is explicit regarding what's actually going on.

As Rob said, "Clear is better than clever." https://www.youtube.com/watch?v=PAAkCSZUG1c&t=875s

I also don't want to be hunting down whoever creates a map[T]bool and doesn't leave a comment explaining it's a set ;)

Hopefully we won't have to worry about it for much longer regardless, since I imagine we'll be using proper sets (with methods) some point in the near future.

Re:Go 1.18 by randomswede on Thursday March 17, 2022 @05:05AM (#30709069)
I would say that "exists in the set" is determined only and exactly by "mySet[thing]" returning true, not that there happens to be a key in the map.

But, that's one of those "requires extensive documentation" (and ideally, wrapping in a custom type and provide methods for checking and manipulating the set(s)).

Re:Go 1.18 by yencabulator on Friday March 18, 2022 @03:59PM (#30726813)
Now every range over your set is likely to be a bug. `map[T]bool` is simply a bad design to use.
Re:Go 1.18 by randomswede on Monday March 21, 2022 @09:37AM (#30753955)
How? Why? If you use the map[T]bool, you obviously need to pay attention to the bool value, even in a range. Whereas in map[T]struct{} you don't need to pay attention to the values.

In either way, even with that type of data type underlying a set, I would (probably) provide a functional API to interact with it.

Re:Go 1.18 by yencabulator on Tuesday March 22, 2022 @11:19AM (#30767138)

    m["x"] = foo()
    for k := range {
        // if foo returned false, this is buggy
    }
Re:Go 1.18 by randomswede on Wednesday March 23, 2022 @05:11AM (#30776534)
Yes, as I said, if you use a map[T]bool, you need to use something like:

for k, v := range m { if v { } }

But it also allows you to use "if m[key] { ... }". It is literally a trade-off for what convenience you want. And in both cases, you should (probably) wrap an abstraction around the raw map.

Re:Go 1.18 by morelisp on Wednesday March 16, 2022 @05:52AM (#30696938)
Well, now there's no excuse for not having `myset.Contains(thing)` (though there really wasn't before either) which is even clearer.