Re: [go-nuts] Best practice for sets in go?
Sets are in an unfortunate situation in Go. They're so easy to create from maps that it's hard to justify creating a special type for them, but the struct{}/bool dichotomy has good arguments on both sides. The result is that there is no idiomatic set type. I'm starting to think that it's best to always create/use a custom set type, just to make the usage clear and eliminate the possibility of having the "false" bug. For deduplication specifically, I find closures useful: seen := make(map[string]struct{}) first := func(s string) bool { if _, ok := seen[s]; !ok { seen[s] = struct{}{} } return ok } for _, v := range blah { if first(v) { // ... } } On Tue, Jul 26, 2016 at 10:37 AM Edward Mullerwrote: > I encourage people to use the later form because of the duality of a bool > (true or false) and the fact that it implies meaning. When you see the bool > you have to start considering the false path. I'd much prefer the extra few > bytes for the longer inclusion checks because there is no ambiguity in the > check. > > On Tue, Jul 26, 2016 at 9:27 AM Tyler Compton wrote: > >> In my opinion, struct{} should always be used for placeholders. I also >> use it when sending to a channel where the data itself doesn't matter. >> struct{} looks gross but it's very expressive in this case and I think most >> all Go programmers are familiar with its meaning. >> >> map[string]bool suggests that the bool value has some kind of >> significance. Sure, the documentation you put in probably says otherwise, >> but the bool type is still unnecessary indirection. >> >> This issue is made worse if one uses the if m[key] { ... } idiom for the >> reason that Sam Whited brought up. Plus, then the bool has a meaning, but >> it's only for the purpose of slightly shortening code instead of using a >> well-known Go pattern. Why bother making the meaning of the map more >> complicated? >> >> if _, ok = m[key]; ok { >> } >> >> Is something Go programmers are used to. >> >> if m[ok] { >> } >> >> Requires that the programmer take a look at the map and its documentation >> to see what's going on unless they're already used to that pattern in the >> code base. >> >> On Tuesday, July 26, 2016 at 7:07:08 AM UTC-7, Sam Whited wrote: >> >>> On Tue, Jul 26, 2016 at 6:35 AM, Dave Cheney wrote: >>> > If saving one byte per entry is important for your application, the >>> latter is your choice. The former has nicer properties that you can use the >>> single value form of map access, >>> > >>> > if m[key] { >>> >// found >>> > } >>> > >>> > I'd say the former is the right choice for 97.25% of general use >>> cases. >>> >>> I'd agree with this, except that I don't trust that one guy in the >>> office not to sneak past something that somehow puts a false in the >>> map and causes bugs later. Arguably that's a review problem, but even >>> so one or two extra bytes of code (`_, ok = m[key]; ok') seems like a >>> small price to pay for safety guarantees and to save a few bytes of >>> memory. >>> >>> (though as you said, it hardly matters either way; I just prefer to >>> recommend the struct{} version to new people) >>> >>> —Sam >>> >>> >>> -- >>> Sam Whited >>> pub 4096R/54083AE104EA7AD3 >>> >> -- >> You received this message because you are subscribed to the Google Groups >> "golang-nuts" group. >> To unsubscribe from this group and stop receiving emails from it, send an >> email to golang-nuts+unsubscr...@googlegroups.com. >> For more options, visit https://groups.google.com/d/optout. >> > -- > You received this message because you are subscribed to the Google Groups > "golang-nuts" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to golang-nuts+unsubscr...@googlegroups.com. > For more options, visit https://groups.google.com/d/optout. > -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [go-nuts] Best practice for sets in go?
I encourage people to use the later form because of the duality of a bool (true or false) and the fact that it implies meaning. When you see the bool you have to start considering the false path. I'd much prefer the extra few bytes for the longer inclusion checks because there is no ambiguity in the check. On Tue, Jul 26, 2016 at 9:27 AM Tyler Comptonwrote: > In my opinion, struct{} should always be used for placeholders. I also use > it when sending to a channel where the data itself doesn't matter. struct{} > looks gross but it's very expressive in this case and I think most all Go > programmers are familiar with its meaning. > > map[string]bool suggests that the bool value has some kind of > significance. Sure, the documentation you put in probably says otherwise, > but the bool type is still unnecessary indirection. > > This issue is made worse if one uses the if m[key] { ... } idiom for the > reason that Sam Whited brought up. Plus, then the bool has a meaning, but > it's only for the purpose of slightly shortening code instead of using a > well-known Go pattern. Why bother making the meaning of the map more > complicated? > > if _, ok = m[key]; ok { > } > > Is something Go programmers are used to. > > if m[ok] { > } > > Requires that the programmer take a look at the map and its documentation > to see what's going on unless they're already used to that pattern in the > code base. > > On Tuesday, July 26, 2016 at 7:07:08 AM UTC-7, Sam Whited wrote: > >> On Tue, Jul 26, 2016 at 6:35 AM, Dave Cheney wrote: >> > If saving one byte per entry is important for your application, the >> latter is your choice. The former has nicer properties that you can use the >> single value form of map access, >> > >> > if m[key] { >> >// found >> > } >> > >> > I'd say the former is the right choice for 97.25% of general use cases. >> >> I'd agree with this, except that I don't trust that one guy in the >> office not to sneak past something that somehow puts a false in the >> map and causes bugs later. Arguably that's a review problem, but even >> so one or two extra bytes of code (`_, ok = m[key]; ok') seems like a >> small price to pay for safety guarantees and to save a few bytes of >> memory. >> >> (though as you said, it hardly matters either way; I just prefer to >> recommend the struct{} version to new people) >> >> —Sam >> >> >> -- >> Sam Whited >> pub 4096R/54083AE104EA7AD3 >> > -- > You received this message because you are subscribed to the Google Groups > "golang-nuts" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to golang-nuts+unsubscr...@googlegroups.com. > For more options, visit https://groups.google.com/d/optout. > -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [go-nuts] Best practice for sets in go?
2016-07-26 18:27 GMT+02:00 Tyler Compton: > if _, ok = m[key]; ok { > } > > Is something Go programmers are used to. > > if m[ok] { > } > > Requires that the programmer take a look at the map and its documentation to > see what's going on unless they're already used to that pattern in the code > base. If this map is part of some sort of external API I'm inclined to agree. (Except that a map[something]struct{} is a crappy external API sort of type and should probably be a StringSet or whatever with relevant methods on it.) However, in my code these sort of maps usually pop up in deduplication loops and similar: seen := make(map[string]bool) for _, v := range whatever { seen[v] = true } // ... for _, v := range somethingelse { if seen[v] { // ... } } and there I think the bool value makes the code read much nicer without any risk for confusion. //jb -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [go-nuts] Best practice for sets in go?
In my opinion, struct{} should always be used for placeholders. I also use it when sending to a channel where the data itself doesn't matter. struct{} looks gross but it's very expressive in this case and I think most all Go programmers are familiar with its meaning. map[string]bool suggests that the bool value has some kind of significance. Sure, the documentation you put in probably says otherwise, but the bool type is still unnecessary indirection. This issue is made worse if one uses the if m[key] { ... } idiom for the reason that Sam Whited brought up. Plus, then the bool has a meaning, but it's only for the purpose of slightly shortening code instead of using a well-known Go pattern. Why bother making the meaning of the map more complicated? if _, ok = m[key]; ok { } Is something Go programmers are used to. if m[ok] { } Requires that the programmer take a look at the map and its documentation to see what's going on unless they're already used to that pattern in the code base. On Tuesday, July 26, 2016 at 7:07:08 AM UTC-7, Sam Whited wrote: > > On Tue, Jul 26, 2016 at 6:35 AM, Dave Cheney> wrote: > > If saving one byte per entry is important for your application, the > latter is your choice. The former has nicer properties that you can use the > single value form of map access, > > > > if m[key] { > >// found > > } > > > > I'd say the former is the right choice for 97.25% of general use cases. > > I'd agree with this, except that I don't trust that one guy in the > office not to sneak past something that somehow puts a false in the > map and causes bugs later. Arguably that's a review problem, but even > so one or two extra bytes of code (`_, ok = m[key]; ok') seems like a > small price to pay for safety guarantees and to save a few bytes of > memory. > > (though as you said, it hardly matters either way; I just prefer to > recommend the struct{} version to new people) > > —Sam > > > -- > Sam Whited > pub 4096R/54083AE104EA7AD3 > -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [go-nuts] Best practice for sets in go?
On Tue, Jul 26, 2016 at 6:35 AM, Dave Cheneywrote: > If saving one byte per entry is important for your application, the latter is > your choice. The former has nicer properties that you can use the single > value form of map access, > > if m[key] { >// found > } > > I'd say the former is the right choice for 97.25% of general use cases. I'd agree with this, except that I don't trust that one guy in the office not to sneak past something that somehow puts a false in the map and causes bugs later. Arguably that's a review problem, but even so one or two extra bytes of code (`_, ok = m[key]; ok') seems like a small price to pay for safety guarantees and to save a few bytes of memory. (though as you said, it hardly matters either way; I just prefer to recommend the struct{} version to new people) —Sam -- Sam Whited pub 4096R/54083AE104EA7AD3 -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.