Re: [go-nuts] Best practice for sets in go?

2016-07-26 Thread Matt Harden
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 Muller 
wrote:

> 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?

2016-07-26 Thread Edward Muller
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.


Re: [go-nuts] Best practice for sets in go?

2016-07-26 Thread Jakob Borg
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?

2016-07-26 Thread Tyler Compton
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?

2016-07-26 Thread Sam Whited
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.