Re: [go-nuts] Where is my type?

2024-04-24 Thread burak serdar
In the first case, the interface contains a value of type S, which is
not writable. The value contained in the interface is not addressable.
So Unmarshal creates a new map and fills that. In the second case the
interface contains *S, which is writable, so unmarshal fills it in via
reflection.

On Wed, Apr 24, 2024 at 10:46 AM cpu...@gmail.com  wrote:
>
> Every time I feel I've come to terms with how Go works I round a corner and 
> hit a wall, even after doing this for >5 years. Here's one.
>
> Consider this simple code (https://go.dev/play/p/bph5I80vc99):
>
> package main
>
> import (
> "encoding/json"
> "fmt"
> )
>
> type S struct {
> Foo int
> }
>
> func update(v any) {
> if err := json.Unmarshal([]byte(`{"Foo": 42}`), ); err != nil {
> panic(err)
> }
> fmt.Printf("%v %T\n", v, v)
> }
>
> func main() {
> var val S
>
> // map[Foo:42] map[string]interface {}
> update(val)
>
> // &{42} *main.S
> update()
> }
>
> Why would calling by value change the type of the value passed to map? I 
> would expect an interface with a dynamic type of main.S, but its 
> map[string]interface{}, or json.Unmarshal makes it so.
>
> Insights appreciated :)
>
> --
> 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.
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/golang-nuts/980466d2-1686-4b79-aec1-45b592db2caan%40googlegroups.com.

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAMV2RqrUtoauyu8dHGrrVppY%3DeTVP7dCZkb%2Br_Ax696UuJy6dQ%40mail.gmail.com.


Re: [go-nuts] Re: xml to json, parsing xml

2024-04-23 Thread burak serdar
In general, you cannot convert xml to json. They have incompatible
models. XML elements are ordered similar to a JSON array, but in many
cases you want to map XML elements to JSON objects, which are
unordered name-value collections. Also, there is no JSON equivalent of
an XML attribute.

If you want to work with XML, either use xml marshaling, or find a
third-party DOM library.

On Tue, Apr 23, 2024 at 10:29 AM Don Caldwell  wrote:
>
> Disclaimer - I am very new to golang.
> I puzzled about this for a few days. After some struggle, I got a little 
> program working that parses
> arbitrary xml into a structure that json can understand. You can find it here:
> https://github.com/dfwcnj/gxmldecode
>
> On Thursday, October 7, 2021 at 10:06:30 AM UTC-4 RS wrote:
>>
>> What is the best approach to convert xml to json?
>> However I need above all to parse a very complex xml to see if related 
>> properties are existing.
>> I thought maybe converting it to Json maybe make it easier.
>>
>>
> --
> 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.
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/golang-nuts/90c0dd22-2d81-4393-b534-651a2376f386n%40googlegroups.com.

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAMV2RqowOgbOnmGxsWegOuJ-_crQcNhsjj1Gxk3pAXhBmtNK5Q%40mail.gmail.com.


Re: [go-nuts] Why can't I use an interface which needs another interface inside of it

2024-03-13 Thread burak serdar
On Wed, Mar 13, 2024 at 10:31 AM Rodrigo Araujo  wrote:
>
> Do you mean b.GetChilder? In this case, package A will depend on package B 
> and I don't think this is a good approach.

Why would it not be a good approach? You have a package declaring
interfaces, and if you have another package using those interfaces,
you import the first package in the second. Placing common interfaces
in a package everyone else imports is a common way to deal with this
problem.


>
> Em qua., 13 de mar. de 2024 às 11:28, Brian Hatfield  
> escreveu:
>>
>> Client.GetChild() must return GetChilder, not Child.
>>
>> On Wed, Mar 13, 2024 at 10:02 AM Rodrigo Araujo  wrote:
>>>
>>> Given the code bellow, I'm trying to keep my packages completely separated, 
>>> without knowing each other, but the code doesn't work. I just can get it 
>>> running when I define (or use) an interface from one package inside code of 
>>> the other package.
>>> Here is the error:
>>> cannot use client (variable of type *a.Client) as b.GetChilder value in 
>>> struct literal: *a.Client does not implement b.GetChilder (wrong type for 
>>> method GetChild)
>>> have GetChild() *a.Child
>>> want GetChild() b.GetDataercompilerInvalidIfaceAssign
>>>
>>> package a // file: a/a.go
>>>
>>> import "fmt"
>>>
>>> type Client struct{}
>>>
>>> func (c *Client) GetChild() *Child {
>>> return {}
>>> }
>>>
>>> type Child struct{}
>>>
>>> func (c *Child) GetData() {
>>> fmt.Println("from GetData")
>>> }
>>>
>>>
>>> package b // file: b/b.go
>>>
>>> type GetDataer interface {
>>> GetData()
>>> }
>>>
>>> type GetChilder interface {
>>> GetChild() GetDataer
>>> }
>>>
>>> type Processor struct {
>>> Client GetChilder
>>> }
>>>
>>> func (p *Processor) Process() {
>>> card := p.Client.GetChild()
>>> card.GetData()
>>> }
>>>
>>>
>>> package main // file: main.go
>>>
>>> import (
>>> "interfaces/a"
>>> "interfaces/b"
>>> )
>>>
>>> func main() {
>>> client := {}
>>> processor := {
>>> Client: client,
>>> }
>>> processor.Process()
>>> }
>>>
>>>
>>> Why this doens't work? Some kind of limitation on interfaces usage?
>>> How is the best approach (idiomatic golang) to tacke this kind of problem?
>>>
>>>
>>> --
>>> 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.
>>> To view this discussion on the web visit 
>>> https://groups.google.com/d/msgid/golang-nuts/41be202c-f205-4adf-aecc-0f8e681e2490n%40googlegroups.com.
>
>
>
> --
> Att.
> --
> Rodrigo Araujo
> --
>
> --
> 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.
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/golang-nuts/CAEwyvWHKZboz2KQvU7o_yneYhY31r3HBxqSQJw-B-vkuRvxHXw%40mail.gmail.com.

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAMV2Rqr6PmqU%2BHNaNwW8fOZrv6SZw7cf2pacoR_tzvd3hd0MDA%40mail.gmail.com.


Re: [go-nuts] How to have a raw parameter value in cobra?

2024-02-25 Thread burak serdar
Somewhere in your main, you should be calling rootCmd.Execute(). Instead:

func main() {
   // first, make sure there are at least 2 args. Then, process the
1st parameter
   // Then
   rootCmd.SetArgs(os.Args[2:])
   rootCmd.Execute()
}

On Sun, Feb 25, 2024 at 1:50 PM David Karr  wrote:
>
> But where would that be done?  I'm not certain of the exact role of the 
> "rootCmd.Execute()" function, or the optional "Run" function in the Command 
> object. Neither of those appear to be executed, when I just run " 
>   subcommand, and that gets printed, but nothing else.
>
> On Sunday, February 25, 2024 at 10:52:10 AM UTC-8 burak serdar wrote:
>>
>> You can do rootCmd.SetArgs(os.Args[2:]), and process the first
>> parameter yourself.
>>
>> On Sun, Feb 25, 2024 at 11:43 AM David Karr  wrote:
>> >
>> > I am not a new programmer, but I am pretty new to golang, having only 
>> > written a couple of small applications, and that was several months ago. 
>> > I'm trying to construct an application using Cobra, using some nonstandard 
>> > conventions. Is it better to ask a question like this in an issue in the 
>> > Cobra github site?
>> >
>> > The application I am trying to write will be used extremely often, and I 
>> > want to minimize the required syntax.
>> >
>> > I want to set up a command line like the following:
>> >
>> >
>> >
>> > The parameter right after the application name will always be present. I 
>> > don't want it to be a flag. After that parameter value will be a 
>> > subcommand, followed by additional parameters, also not flags. There are 
>> > some situations where I want to allow for flags, but that will be uncommon.
>> >
>> > It's not clear to me how to cleanly set up this organization. Is it simply 
>> > not practical to do with Cobra? Should I just do ad hoc parameter 
>> > processing?
>> >
>> > --
>> > 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...@googlegroups.com.
>> > To view this discussion on the web visit 
>> > https://groups.google.com/d/msgid/golang-nuts/14b9efb1-7fbb-45a6-8e0e-56f25be310a3n%40googlegroups.com.
>
> --
> 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.
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/golang-nuts/9d8fac62-f70a-488d-8bf9-7800b5d44d34n%40googlegroups.com.

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAMV2RqoOs2TacBQ6iLxybwP6Wv74WDmTUk%2B2WR2kYFKmJQrFoQ%40mail.gmail.com.


Re: [go-nuts] How to have a raw parameter value in cobra?

2024-02-25 Thread burak serdar
You can do rootCmd.SetArgs(os.Args[2:]), and process the first
parameter yourself.

On Sun, Feb 25, 2024 at 11:43 AM David Karr  wrote:
>
> I am not a new programmer, but I am pretty new to golang, having only written 
> a couple of small applications, and that was several months ago. I'm trying 
> to construct an application using Cobra, using some nonstandard conventions. 
> Is it better to ask a question like this in an issue in the Cobra github site?
>
> The application I am trying to write will be used extremely often, and I want 
> to minimize the required syntax.
>
> I want to set up a command line like the following:
>
>
>
> The parameter right after the application name will always be present. I 
> don't want it to be a flag. After that parameter value will be a subcommand, 
> followed by additional parameters, also not flags. There are some situations 
> where I want to allow for flags, but that will be uncommon.
>
> It's not clear to me how to cleanly set up this organization.  Is it simply 
> not practical to do with Cobra?  Should I just do ad hoc parameter processing?
>
> --
> 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.
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/golang-nuts/14b9efb1-7fbb-45a6-8e0e-56f25be310a3n%40googlegroups.com.

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAMV2RqrshNcSUdBiMrCTP8GkEc3mHre3eBXN2W%2BK%3DDiwoiWvCQ%40mail.gmail.com.


Re: [go-nuts] Equality of interface of an empty struct - why?

2024-02-22 Thread burak serdar
On Thu, Feb 22, 2024 at 10:39 AM Axel Wagner
 wrote:
>
>
>
> On Thu, Feb 22, 2024 at 6:06 PM burak serdar  wrote:
>>
>> I don't think this case really applies here. I get that comparison of
>> a==b may or may not be true. The problem is that if a==b at some point
>> in a program, it should be the case that a==b for all other cases in
>> that same program.
>
>
> Why? I mean, I get that it makes sense intuitively, but how does this follow 
> from the spec? That sentence says "a comparison of two pointers to zero sized 
> values may or may not be true". It does not qualify that statement in any way.

We are comparing two interfaces containing pointers to zero-size
structs. If those pointers are not equal, then the interfaces should
not be equal as well.

Maybe the spec should be clarified to say "for a compilation of a
program, two pointers to zero-size variables may or may not be equal",
because otherwise it implies that if you have

x:= a==b
y:= a==b

x may or may not be true. If a==b, then that should hold for every
execution of that program, and throughout the program.


>
>>
>> That is, if a==b, then
>> interface{}(a)==interface{}(b), and vice versa. But what we have here
>> is a!=b but interface{}(a)==interface{}(b)
>>
>> On Thu, Feb 22, 2024 at 9:50 AM Axel Wagner
>>  wrote:
>> >
>> > Hm actually, the spec allows for this, technically speaking: 
>> > https://go.dev/ref/spec#Comparison_operators
>> >
>> > > Pointers to distinct zero-size variables may or may not be equal.
>> >
>> > Arguably, this genuinely would allow comparison of pointers to zero-sized 
>> > variables to have any behavior whatsoever (including being random). But it 
>> > certainly is confusing.
>> >
>> >
>> > On Thu, Feb 22, 2024 at 5:46 PM Axel Wagner 
>> >  wrote:
>> >>
>> >> I see. Sorry, I was jumping to conclusions and didn't quite get what you 
>> >> mean. That is my fault.
>> >>
>> >> I agree that this looks confusing and is arguably a bug. I filed 
>> >> https://github.com/golang/go/issues/65878, thanks for pointing it out.
>> >>
>> >> On Thu, Feb 22, 2024 at 5:20 PM burak serdar  wrote:
>> >>>
>> >>> Creating  an interface is not creating a pointer to a zero sized 
>> >>> variable.
>> >>>
>> >>> a==b  prints false. That means, a and b point to different locations
>> >>> Bar(a)==Bar(b) prints true. If a!=b, then Bar(a) must be different from 
>> >>> Bar(b)
>> >>>
>> >>> On Thu, Feb 22, 2024 at 9:15 AM Axel Wagner
>> >>>  wrote:
>> >>> >
>> >>> > If you expect that, you are misreading the spec. There is no guarantee 
>> >>> > of any behavior here. An implementation is allowed to flip a coin, 
>> >>> > every time you create a pointer to a zero-sized variable, and either 
>> >>> > return a unique pointer or a singleton. I think you may assume that  
>> >>> > == , always. But apart from that, who knows.
>> >>> >
>> >>> > Zero-sized variables *may* have the same address. They don't *have* to.
>> >>> >
>> >>> > On Thu, Feb 22, 2024 at 5:12 PM burak serdar  
>> >>> > wrote:
>> >>> >>
>> >>> >> On Thu, Feb 22, 2024 at 9:00 AM Axel Wagner
>> >>> >>  wrote:
>> >>> >> >
>> >>> >> > Note that in the Spec section I quoted above it says "Two distinct 
>> >>> >> > zero-size variables may have the same address in memory" (emphasis 
>> >>> >> > mine).
>> >>> >> > There is no guarantee, that all zero-sized values have the same 
>> >>> >> > address (otherwise, you'd get into inefficiencies when taking the 
>> >>> >> > address of a zero-sized field in a larger struct, or when 
>> >>> >> > converting a zero-capacity slice into an array-pointer). But it is 
>> >>> >> > allowed.
>> >>> >> > If you require two pointers returned from different code paths to 
>> >>> >> > be different, for correctness, then you have to make them point at 
>> >>> >> > something that has non-zero size. Otherwise, all potential 
>> >>> >> > combinations are valid according to the s

Re: [go-nuts] Equality of interface of an empty struct - why?

2024-02-22 Thread burak serdar
I don't think this case really applies here. I get that comparison of
a==b may or may not be true. The problem is that if a==b at some point
in a program, it should be the case that a==b for all other cases in
that same program. That is, if a==b, then
interface{}(a)==interface{}(b), and vice versa. But what we have here
is a!=b but interface{}(a)==interface{}(b)

On Thu, Feb 22, 2024 at 9:50 AM Axel Wagner
 wrote:
>
> Hm actually, the spec allows for this, technically speaking: 
> https://go.dev/ref/spec#Comparison_operators
>
> > Pointers to distinct zero-size variables may or may not be equal.
>
> Arguably, this genuinely would allow comparison of pointers to zero-sized 
> variables to have any behavior whatsoever (including being random). But it 
> certainly is confusing.
>
>
> On Thu, Feb 22, 2024 at 5:46 PM Axel Wagner  
> wrote:
>>
>> I see. Sorry, I was jumping to conclusions and didn't quite get what you 
>> mean. That is my fault.
>>
>> I agree that this looks confusing and is arguably a bug. I filed 
>> https://github.com/golang/go/issues/65878, thanks for pointing it out.
>>
>> On Thu, Feb 22, 2024 at 5:20 PM burak serdar  wrote:
>>>
>>> Creating  an interface is not creating a pointer to a zero sized variable.
>>>
>>> a==b  prints false. That means, a and b point to different locations
>>> Bar(a)==Bar(b) prints true. If a!=b, then Bar(a) must be different from 
>>> Bar(b)
>>>
>>> On Thu, Feb 22, 2024 at 9:15 AM Axel Wagner
>>>  wrote:
>>> >
>>> > If you expect that, you are misreading the spec. There is no guarantee of 
>>> > any behavior here. An implementation is allowed to flip a coin, every 
>>> > time you create a pointer to a zero-sized variable, and either return a 
>>> > unique pointer or a singleton. I think you may assume that  == , 
>>> > always. But apart from that, who knows.
>>> >
>>> > Zero-sized variables *may* have the same address. They don't *have* to.
>>> >
>>> > On Thu, Feb 22, 2024 at 5:12 PM burak serdar  wrote:
>>> >>
>>> >> On Thu, Feb 22, 2024 at 9:00 AM Axel Wagner
>>> >>  wrote:
>>> >> >
>>> >> > Note that in the Spec section I quoted above it says "Two distinct 
>>> >> > zero-size variables may have the same address in memory" (emphasis 
>>> >> > mine).
>>> >> > There is no guarantee, that all zero-sized values have the same 
>>> >> > address (otherwise, you'd get into inefficiencies when taking the 
>>> >> > address of a zero-sized field in a larger struct, or when converting a 
>>> >> > zero-capacity slice into an array-pointer). But it is allowed.
>>> >> > If you require two pointers returned from different code paths to be 
>>> >> > different, for correctness, then you have to make them point at 
>>> >> > something that has non-zero size. Otherwise, all potential 
>>> >> > combinations are valid according to the spec.
>>> >>
>>> >> Yes. But in that case, you'd expect either  a==b and Bar(a)==Bar(b) to
>>> >> be both true, or both false. In this case, one is true and the other
>>> >> is not.
>>> >>
>>> >>
>>> >> >
>>> >> > On Thu, Feb 22, 2024 at 4:53 PM burak serdar  
>>> >> > wrote:
>>> >> >>
>>> >> >> The compiler can allocate the same address for empty structs, so I
>>> >> >> actually expected a==b to be true, not false. However, there's
>>> >> >> something more interesting going on here because:
>>> >> >>
>>> >> >> a := {}
>>> >> >> b := {}
>>> >> >> fmt.Printf("%t\n", *a == *b)
>>> >> >> fmt.Printf("%t\n", a == b)
>>> >> >> fmt.Printf("%p %p\n", a, b)
>>> >> >> x := Bar(a)
>>> >> >> y := Bar(b)
>>> >> >> fmt.Printf("%t\n", Bar(a) == Bar(b))
>>> >> >> fmt.Printf("%t\n", x == y)
>>> >> >>
>>> >> >> Prints:
>>> >> >>
>>> >> >> true
>>> >> >> true
>>> >> >> 0x58e360 0x58e360 // Note that a and be are pointing to the same 
>>> >> >> address
>>> >>

Re: [go-nuts] Equality of interface of an empty struct - why?

2024-02-22 Thread burak serdar
Creating  an interface is not creating a pointer to a zero sized variable.

a==b  prints false. That means, a and b point to different locations
Bar(a)==Bar(b) prints true. If a!=b, then Bar(a) must be different from Bar(b)

On Thu, Feb 22, 2024 at 9:15 AM Axel Wagner
 wrote:
>
> If you expect that, you are misreading the spec. There is no guarantee of any 
> behavior here. An implementation is allowed to flip a coin, every time you 
> create a pointer to a zero-sized variable, and either return a unique pointer 
> or a singleton. I think you may assume that  == , always. But apart from 
> that, who knows.
>
> Zero-sized variables *may* have the same address. They don't *have* to.
>
> On Thu, Feb 22, 2024 at 5:12 PM burak serdar  wrote:
>>
>> On Thu, Feb 22, 2024 at 9:00 AM Axel Wagner
>>  wrote:
>> >
>> > Note that in the Spec section I quoted above it says "Two distinct 
>> > zero-size variables may have the same address in memory" (emphasis mine).
>> > There is no guarantee, that all zero-sized values have the same address 
>> > (otherwise, you'd get into inefficiencies when taking the address of a 
>> > zero-sized field in a larger struct, or when converting a zero-capacity 
>> > slice into an array-pointer). But it is allowed.
>> > If you require two pointers returned from different code paths to be 
>> > different, for correctness, then you have to make them point at something 
>> > that has non-zero size. Otherwise, all potential combinations are valid 
>> > according to the spec.
>>
>> Yes. But in that case, you'd expect either  a==b and Bar(a)==Bar(b) to
>> be both true, or both false. In this case, one is true and the other
>> is not.
>>
>>
>> >
>> > On Thu, Feb 22, 2024 at 4:53 PM burak serdar  wrote:
>> >>
>> >> The compiler can allocate the same address for empty structs, so I
>> >> actually expected a==b to be true, not false. However, there's
>> >> something more interesting going on here because:
>> >>
>> >> a := {}
>> >> b := {}
>> >> fmt.Printf("%t\n", *a == *b)
>> >> fmt.Printf("%t\n", a == b)
>> >> fmt.Printf("%p %p\n", a, b)
>> >> x := Bar(a)
>> >> y := Bar(b)
>> >> fmt.Printf("%t\n", Bar(a) == Bar(b))
>> >> fmt.Printf("%t\n", x == y)
>> >>
>> >> Prints:
>> >>
>> >> true
>> >> true
>> >> 0x58e360 0x58e360 // Note that a and be are pointing to the same address
>> >> true
>> >> true
>> >>
>> >>
>> >> But:
>> >> a := {}
>> >> b := {}
>> >> fmt.Printf("%t\n", *a == *b)
>> >> fmt.Printf("%t\n", a == b)
>> >> //fmt.Printf("%p %p\n", a, b)  // Comment out the print
>> >> x := Bar(a)
>> >> y := Bar(b)
>> >> fmt.Printf("%t\n", Bar(a) == Bar(b))
>> >> fmt.Printf("%t\n", x == y)
>> >>
>> >>
>> >> Prints:
>> >>
>> >> true
>> >> false
>> >> true
>> >> true
>> >>
>> >>
>> >> On Thu, Feb 22, 2024 at 3:56 AM Brien Colwell  wrote:
>> >> >
>> >> > I'm confused by this output. It appears that the interface of two 
>> >> > different pointers to an empty struct are equal. In all other cases, 
>> >> > interface equality seems to be the pointer equality. What's going on in 
>> >> > the empty struct case?
>> >> >
>> >> > ```
>> >> > package main
>> >> >
>> >> > import "fmt"
>> >> >
>> >> > type Foo struct {
>> >> > }
>> >> >
>> >> > func (self *Foo) Hello() {
>> >> > }
>> >> >
>> >> > type FooWithValue struct {
>> >> > A int
>> >> > }
>> >> >
>> >> > func (self *FooWithValue) Hello() {
>> >> > }
>> >> >
>> >> > type Bar interface {
>> >> > Hello()
>> >> > }
>> >> >
>> >> > func main() {
>> >> > a := {}
>> >> > b := {}
>> >> > fmt.Printf("%t\n", *a == *b)
>> >> > fmt.Printf("%t\n", a == b)
>> >> > fmt.Printf("%t\n", Bar(a) == Bar(b

Re: [go-nuts] Equality of interface of an empty struct - why?

2024-02-22 Thread burak serdar
On Thu, Feb 22, 2024 at 9:00 AM Axel Wagner
 wrote:
>
> Note that in the Spec section I quoted above it says "Two distinct zero-size 
> variables may have the same address in memory" (emphasis mine).
> There is no guarantee, that all zero-sized values have the same address 
> (otherwise, you'd get into inefficiencies when taking the address of a 
> zero-sized field in a larger struct, or when converting a zero-capacity slice 
> into an array-pointer). But it is allowed.
> If you require two pointers returned from different code paths to be 
> different, for correctness, then you have to make them point at something 
> that has non-zero size. Otherwise, all potential combinations are valid 
> according to the spec.

Yes. But in that case, you'd expect either  a==b and Bar(a)==Bar(b) to
be both true, or both false. In this case, one is true and the other
is not.


>
> On Thu, Feb 22, 2024 at 4:53 PM burak serdar  wrote:
>>
>> The compiler can allocate the same address for empty structs, so I
>> actually expected a==b to be true, not false. However, there's
>> something more interesting going on here because:
>>
>> a := {}
>> b := {}
>> fmt.Printf("%t\n", *a == *b)
>> fmt.Printf("%t\n", a == b)
>> fmt.Printf("%p %p\n", a, b)
>> x := Bar(a)
>> y := Bar(b)
>> fmt.Printf("%t\n", Bar(a) == Bar(b))
>> fmt.Printf("%t\n", x == y)
>>
>> Prints:
>>
>> true
>> true
>> 0x58e360 0x58e360 // Note that a and be are pointing to the same address
>> true
>> true
>>
>>
>> But:
>> a := {}
>> b := {}
>> fmt.Printf("%t\n", *a == *b)
>> fmt.Printf("%t\n", a == b)
>> //fmt.Printf("%p %p\n", a, b)  // Comment out the print
>> x := Bar(a)
>> y := Bar(b)
>> fmt.Printf("%t\n", Bar(a) == Bar(b))
>> fmt.Printf("%t\n", x == y)
>>
>>
>> Prints:
>>
>> true
>> false
>> true
>> true
>>
>>
>> On Thu, Feb 22, 2024 at 3:56 AM Brien Colwell  wrote:
>> >
>> > I'm confused by this output. It appears that the interface of two 
>> > different pointers to an empty struct are equal. In all other cases, 
>> > interface equality seems to be the pointer equality. What's going on in 
>> > the empty struct case?
>> >
>> > ```
>> > package main
>> >
>> > import "fmt"
>> >
>> > type Foo struct {
>> > }
>> >
>> > func (self *Foo) Hello() {
>> > }
>> >
>> > type FooWithValue struct {
>> > A int
>> > }
>> >
>> > func (self *FooWithValue) Hello() {
>> > }
>> >
>> > type Bar interface {
>> > Hello()
>> > }
>> >
>> > func main() {
>> > a := {}
>> > b := {}
>> > fmt.Printf("%t\n", *a == *b)
>> > fmt.Printf("%t\n", a == b)
>> > fmt.Printf("%t\n", Bar(a) == Bar(b))
>> >
>> > c := {A: 1}
>> > d := {A: 1}
>> > fmt.Printf("%t\n", *c == *d)
>> > fmt.Printf("%t\n", c == d)
>> > fmt.Printf("%t\n", Bar(c) == Bar(d))
>> > }
>> > ```
>> >
>> > Prints (emphasis added on the strange case):
>> >
>> > ```
>> > true
>> > false
>> > **true**
>> > true
>> > false
>> > false
>> > ```
>> >
>> >
>> > --
>> > 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.
>> > To view this discussion on the web visit 
>> > https://groups.google.com/d/msgid/golang-nuts/d93760c9-61a7-4a3c-9b5c-d89f023d2253n%40googlegroups.com.
>>
>> --
>> 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.
>> To view this discussion on the web visit 
>> https://groups.google.com/d/msgid/golang-nuts/CAMV2Rqrq21ymUJ00ni_JV%3Dkv6itqZg51GoWM5zJNjcGU1BKcuA%40mail.gmail.com.

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAMV2RqrRNT9CmWbhMYTOV4fmnAvLULTw0cVe%3Dd4adfTLO6gQoA%40mail.gmail.com.


Re: [go-nuts] Equality of interface of an empty struct - why?

2024-02-22 Thread burak serdar
The compiler can allocate the same address for empty structs, so I
actually expected a==b to be true, not false. However, there's
something more interesting going on here because:

a := {}
b := {}
fmt.Printf("%t\n", *a == *b)
fmt.Printf("%t\n", a == b)
fmt.Printf("%p %p\n", a, b)
x := Bar(a)
y := Bar(b)
fmt.Printf("%t\n", Bar(a) == Bar(b))
fmt.Printf("%t\n", x == y)

Prints:

true
true
0x58e360 0x58e360 // Note that a and be are pointing to the same address
true
true


But:
a := {}
b := {}
fmt.Printf("%t\n", *a == *b)
fmt.Printf("%t\n", a == b)
//fmt.Printf("%p %p\n", a, b)  // Comment out the print
x := Bar(a)
y := Bar(b)
fmt.Printf("%t\n", Bar(a) == Bar(b))
fmt.Printf("%t\n", x == y)


Prints:

true
false
true
true


On Thu, Feb 22, 2024 at 3:56 AM Brien Colwell  wrote:
>
> I'm confused by this output. It appears that the interface of two different 
> pointers to an empty struct are equal. In all other cases, interface equality 
> seems to be the pointer equality. What's going on in the empty struct case?
>
> ```
> package main
>
> import "fmt"
>
> type Foo struct {
> }
>
> func (self *Foo) Hello() {
> }
>
> type FooWithValue struct {
> A int
> }
>
> func (self *FooWithValue) Hello() {
> }
>
> type Bar interface {
> Hello()
> }
>
> func main() {
> a := {}
> b := {}
> fmt.Printf("%t\n", *a == *b)
> fmt.Printf("%t\n", a == b)
> fmt.Printf("%t\n", Bar(a) == Bar(b))
>
> c := {A: 1}
> d := {A: 1}
> fmt.Printf("%t\n", *c == *d)
> fmt.Printf("%t\n", c == d)
> fmt.Printf("%t\n", Bar(c) == Bar(d))
> }
> ```
>
> Prints (emphasis added on the strange case):
>
> ```
> true
> false
> **true**
> true
> false
> false
> ```
>
>
> --
> 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.
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/golang-nuts/d93760c9-61a7-4a3c-9b5c-d89f023d2253n%40googlegroups.com.

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAMV2Rqrq21ymUJ00ni_JV%3Dkv6itqZg51GoWM5zJNjcGU1BKcuA%40mail.gmail.com.


Re: [go-nuts] Is there a way to cast interface to embedded type?

2024-02-09 Thread burak serdar
On Fri, Feb 9, 2024 at 1:37 PM Christopher C
 wrote:
>
> I have a base struct that implements an interface. There are multiple other 
> structs that embed this base struct.  I would like to pass the an interface 
> into a function that can cast it as the base struct and call some functions 
> tied to the base struct.

No, because type assertion tests the type of the object contained in
an interface, and that object is not the base object.

However, you can put whatever functions you are planning to call in
that base object into another interface, and call that:

type Base struct {...}

func (Base) A() {}
func (Base) B() {}

type HasA interface {
  A()
}

func f(in HasA) {
   type hasB interface {
  B()
   }
   b,ok:=in.(hasB)
   if ok {
  b.B()
  }
}




>
> Something like this...
> https://go.dev/play/p/DUzXr31s8Pn
>
> --
> 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.
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/golang-nuts/1ded992c-3f90-4c30-99a5-532e573cf16fn%40googlegroups.com.

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAMV2Rqr2fhqDEOxD3jhe8U1fZ1GFvNoNRHanpAykfa8UVfFtyw%40mail.gmail.com.


Re: [go-nuts] Incorrect "missing return" error for an edge case

2024-01-08 Thread burak serdar
Thank you both. I should've looked at the spec first.

On Sun, Jan 7, 2024 at 10:34 PM 'Dan Kortschak' via golang-nuts
 wrote:
>
> On Mon, 2024-01-08 at 06:21 +0100, 'Axel Wagner' via golang-nuts wrote:
> > The "missing return" error is defined in the spec, by requiring a
> > function to end in a terminating statement:
> > https://go.dev/ref/spec#Terminating_statements
> > The list is necessarily not complete. So it is necessarily more
> > advisory than anything else. What things to put in is mainly limited
> > by how much complexity it would be to specify it and how important we
> > deem it. Specifying this case seems pretty hard to specify (note that
> > `i` could be modified in the loop body, so this always terminating
> > requires some pretty complex statements about what is or is not in
> > the loop body - in particular, if you want to do it on a purely
> > syntactical level).
> > It also also can be replaced by `func TestMethod() int { return 0 }`,
> > which is strictly better, more readable code, so I wouldn't even
> > necessarily agree that it's a false-positive error message: You
> > *should* fix that.
> >
> >
> >
> > On Mon, Jan 8, 2024 at 5:32 AM burak serdar 
> > wrote:
> > > This question came up on Stack Overflow today:
> > >
> > > The following code is giving a "missing return" error where it
> > > shouldn't:
> > >
> > > func TestMethod() int {
> > >for i := 0; i < 10; i++ {
> > >return 0
> > >}
> > > }
> > >
> > > Looks like an overlooked case in control flow analysis.
> > >
>
> The case here is covered by point 5 of the terminating statements
> definition. It is a for loop with a loop condition, so it is not a
> terminating statement.
>
> --
> 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.
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/golang-nuts/dc021e72298ce84c5a979b6d974cf72abd482c6c.camel%40kortschak.io.

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAMV2RqrEZj8RvDfix22UnW4pFOigQeeE2ZqBDnz8ObiSOKmeoQ%40mail.gmail.com.


[go-nuts] Incorrect "missing return" error for an edge case

2024-01-07 Thread burak serdar
This question came up on Stack Overflow today:

The following code is giving a "missing return" error where it shouldn't:

func TestMethod() int {
   for i := 0; i < 10; i++ {
   return 0
   }
}

Looks like an overlooked case in control flow analysis.

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAMV2RqosYR2bo-j5Xg77BCf-HKeBV3679zFNLrpoV5GwKntX%2BQ%40mail.gmail.com.


Re: [go-nuts] Go type assertion for MongoDB []bson.M{}/primitive.A type

2023-11-16 Thread burak serdar
Something like this:

type Author struct {
  ID primitive.ObjectID `bson:"_id"`
  CreatedAt time.Time `bson:"created_at"`
   ...
}

type Data struct  {
   Author []Author `bson:"author"`
}


Then you read the results into var result []Data

On Thu, Nov 16, 2023 at 10:39 AM Tong Sun  wrote:
>
> Thanks for the hint. would you elaborate a bit more please as I'm still 
> unsure how to do it. and the closes hits that I found are
>
> https://stackoverflow.com/questions/71739971/unmarshalling-a-bson-d-object-golang
> https://www.mongodb.com/docs/drivers/go/current/fundamentals/bson/
>
>
> But neither covers how to unmarshal bson.M types. I got either:
>
> cannot use r (variable of type interface{}) as []byte value in argument to 
> bson.Unmarshal: need type assertion
>
> Or with:
>
> r := val["author"].(primitive.A)[0]
> var a1 author
> bson.Unmarshal(r.([]byte), )
> a = append(a, a1)
>
> I'm getting:
>
> panic: interface conversion: interface {} is primitive.M, not []uint8
>
>
> On Thursday, November 16, 2023 at 12:20:13 PM UTC-5 burak serdar wrote:
>
> val["author"].(primitive.A)[0] is correct, but the type of that
> expression is not author, it is bson.M. You might consider using a
> tagged struct to unmarshal this.
>
> On Thu, Nov 16, 2023 at 10:11 AM Tong Sun wrote:
> >
> > Further on with the question
> > https://stackoverflow.com/questions/60072372/filtering-values-out-of-a-bson-m-in-golang/
> > where the answer says to use `range server.installed` while the comment says
> >
> > server.host undefined (type string has no field or method subject)
> >
> > This is what I've tried with the MongoDB `[]bson.M{}` type results 
> > (obtained from like `$lookup`):
> >
> > The []bson.M{} type of result I'm getting is:
> >
> > [map[_id:ObjectID("65529d178688bac31b739f82") 
> > author:[map[_id:ObjectID("65529d168688bac31b739f81") 
> > created_at:1699912982379 name:Mehran updated_at:1699912982379]] 
> > author_id:ObjectID("65529d168688bac31b739f81") created_at:1699912983386 
> > name:Test pages:124 updated_at:1699912983386]]
> >
> > I've made several attempts but was unable to access the author field of the 
> > lookup result in Go.
> >
> > a := []author{}
> > for _, val := range result { a = append(a, val["author"].(primitive.A)[0]) }
> >
> > If using val.author, I'm getting val.author undefined (type primitive.M has 
> > no field or method author)
> > If using val["author"], I'm getting invalid operation: cannot index 
> > val["author"] (map index expression of type interface{})
> > If using val["author"].(primitive.A)[0], I'm getting cannot use 
> > val["author"].(primitive.A)[0] (variable of type interface{}) as author 
> > value in argument to append: need type assertion
> >
> >
> > And how to go about to fix this "need type assertion" just stumbled me, as 
> > I've tried val["author"].(primitive.A).([]main.author)[0], or 
> > []author(val["author"].(primitive.A))[0], but I'm getting invalid 
> > operation: cannot call non-function val["author"].(primitive.A) (comma, ok 
> > expression of type primitive.A)
> >
> > and I've now run out of ideas how to fix it.
> > Please help
>
> --
> 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.
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/golang-nuts/d3d75521-c618-45f1-a734-59730cf01364n%40googlegroups.com.

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAMV2Rqq0uWtRQin7YQ17PjhNrcYx_cZsvK2fW%2BQaoo%3DWRmViRw%40mail.gmail.com.


Re: [go-nuts] Go type assertion for MongoDB []bson.M{}/primitive.A type

2023-11-16 Thread burak serdar
 val["author"].(primitive.A)[0] is correct, but the type of that
expression is not author, it is bson.M. You might consider using a
tagged struct to unmarshal this.

On Thu, Nov 16, 2023 at 10:11 AM Tong Sun  wrote:
>
> Further on with the question
> https://stackoverflow.com/questions/60072372/filtering-values-out-of-a-bson-m-in-golang/
> where the answer says to use `range server.installed` while the comment says
>
> server.host undefined (type string has no field or method subject)
>
> This is what I've tried with the MongoDB `[]bson.M{}` type results (obtained 
> from like `$lookup`):
>
> The []bson.M{} type of result I'm getting is:
>
> [map[_id:ObjectID("65529d178688bac31b739f82") 
> author:[map[_id:ObjectID("65529d168688bac31b739f81") created_at:1699912982379 
> name:Mehran updated_at:1699912982379]] 
> author_id:ObjectID("65529d168688bac31b739f81") created_at:1699912983386 
> name:Test pages:124 updated_at:1699912983386]]
>
> I've made several attempts but was unable to access the author field of the 
> lookup result in Go.
>
> a := []author{}
> for _, val := range result { a = append(a, val["author"].(primitive.A)[0]) }
>
> If using val.author, I'm getting val.author undefined (type primitive.M has 
> no field or method author)
> If using val["author"], I'm getting invalid operation: cannot index 
> val["author"] (map index expression of type interface{})
> If using val["author"].(primitive.A)[0], I'm getting cannot use 
> val["author"].(primitive.A)[0] (variable of type interface{}) as author value 
> in argument to append: need type assertion
>
>
> And how to go about to fix this "need type assertion" just stumbled me, as 
> I've tried val["author"].(primitive.A).([]main.author)[0], or 
> []author(val["author"].(primitive.A))[0], but I'm getting invalid operation: 
> cannot call non-function val["author"].(primitive.A) (comma, ok expression of 
> type primitive.A)
>
> and I've now run out of ideas how to fix it.
> Please help
>
>
> --
> 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.
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/golang-nuts/4c9bfd40-4de6-4423-9c0e-31b79b144bd5n%40googlegroups.com.

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAMV2Rqr55hWi0XwSunq%3D4eJ6OMG1bT45T0ac4p%3D1KneAC96rCQ%40mail.gmail.com.


Re: [go-nuts] Re: Is "When in doubt, use a pointer receiver" misleading advice?

2023-11-14 Thread burak serdar
I do not agree that this is because how the compiler works. A value
receiver is equivalent to pass-by-value argument, that is:

rcp.version()

is equivalent to:

RPC.version(rpc)

thus, creating the copy of the rpc variable. So, the compiler may
choose to avoid the race by not copying it, or by inlining the version
function, but according to the spec, it is passed by value, i.e., it
is copied.


On Tue, Nov 14, 2023 at 4:16 PM burak serdar  wrote:
>
> It is a data race because calling rpc.version() makes a copy of rpc,
> which causes reading the field rpc.result concurrently while it is
> being written by the goroutine.
>
> On Tue, Nov 14, 2023 at 3:59 PM Mike Schinkel  wrote:
> >
> > On Monday, November 13, 2023 at 11:28:00 PM UTC-5 Dan Kortschak wrote:
> >
> > https://dave.cheney.net/2015/11/18/wednesday-pop-quiz-spot-the-race
> >
> >
> > Thanks for that link.
> >
> > However, after studying it for well more than an hour I cannot figure out 
> > why it is a data race, and unfortunately Dave Cheney didn't explain it in 
> > his post.
> >
> > Robert Engels seems to be saying this isn't conceptually a data race but it 
> > is an unfortunate artifact of how the compiler works?
> >
> > -Mike
> >
> > --
> > 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.
> > To view this discussion on the web visit 
> > https://groups.google.com/d/msgid/golang-nuts/241c13d1-9d9a-4028-9bce-ba856405f9edn%40googlegroups.com.

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAMV2RqrJHvfcKVnbb8Rh1vacevkNssE1qo0vG1XTW4OVB0TEMQ%40mail.gmail.com.


Re: [go-nuts] Re: Is "When in doubt, use a pointer receiver" misleading advice?

2023-11-14 Thread burak serdar
It is a data race because calling rpc.version() makes a copy of rpc,
which causes reading the field rpc.result concurrently while it is
being written by the goroutine.

On Tue, Nov 14, 2023 at 3:59 PM Mike Schinkel  wrote:
>
> On Monday, November 13, 2023 at 11:28:00 PM UTC-5 Dan Kortschak wrote:
>
> https://dave.cheney.net/2015/11/18/wednesday-pop-quiz-spot-the-race
>
>
> Thanks for that link.
>
> However, after studying it for well more than an hour I cannot figure out why 
> it is a data race, and unfortunately Dave Cheney didn't explain it in his 
> post.
>
> Robert Engels seems to be saying this isn't conceptually a data race but it 
> is an unfortunate artifact of how the compiler works?
>
> -Mike
>
> --
> 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.
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/golang-nuts/241c13d1-9d9a-4028-9bce-ba856405f9edn%40googlegroups.com.

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAMV2RqouBOHsik282BAesvPX2in0i02F4cGFHj1qfywsySTidw%40mail.gmail.com.


Re: [go-nuts] When to share an interface, and when not to.

2023-09-26 Thread burak serdar
On Tue, Sep 26, 2023 at 6:18 AM Jerry Londergaard
 wrote:
>
>
> Do I need to be re-defining this interface everywhere? I guess
> an alternative would be to just re-use the `C.DoThinger`, but I feel like 
> this doesn't seem right as now A is directly importing C, which seems to 
> 'break' the abstraction provided by B:


It looks like you can at least get rid of the definition in package A.
It already has a dependency on B.

If an interface is common enough, you can define it in a common
package imported by other packages. A common pattern I use is to
define interfaces and models at the package root level and then create
additional packages under it for the actual implementation(s). That
is,

package C

type Something interface {...}

type Model struct {...}

Then, the package C/D would have the implementation of the package.

But at the end of the day, it is subjective. There is no single right answer.





>
> --
> package A
> import (
> "B",
> "C"
> )
>
> func Run(dt C.DoThinger) {
> B.Call(dt)
> }
> ```
>
> We could obviously define the interface elsewhere in one place, and have A, B 
> and C share use of it. This doesn't seem like the end of the world, as any of 
> the consumers of that interface can define a new local interface if the 
> shared one becomes unsuitable for them.
>
> My current implementation (the example given), is to reduce coupling between 
> packages. Should I be thinking about this differently? Should I be concerned 
> that I'm not adhering to DRY?
>
> --
> 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.
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/golang-nuts/a0436c1c-b24b-4c64-a4bc-12993c25c360n%40googlegroups.com.

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAMV2RqpgBVfF%3DrboFr0j6gw2%3Dh5BWkbSGxm0nvjZvtX1FpwT-Q%40mail.gmail.com.


Re: [go-nuts] Ensure context timeout behaviour from caller, or callee ?

2023-09-20 Thread burak serdar
On Wed, Sep 20, 2023 at 5:04 PM Jerry Londergaard
 wrote:
>
> Are you comfortable though, *relying* on this behaviour down the stack to 
> enforce the timeout that was declared
> further up the stack (leaving potentially leaked goroutines out of it...)?

That's the nature of handling requests using this layered approach. As
you move down layers in a concurrent program, those that are at a
higher layer set the context for the lower layers. Those that are
lower the stack are not enforcing timeouts or cancellations, they are
merely getting a notification of it.

>
>> If the new goroutine cannot check context cancellation, then the
>> goroutine starting that new goroutine can deal with cancellation like
>> you did, hoping that the new goroutine eventually ends.
>
>
> Ok, I think you're referring to this example of mine 
> https://go.dev/play/p/EGNlJqo3hY5
>
>> I usually use
>> the former, but the latter has its uses if you are calling a
>> third-party library or some operation you cannot cancel.
>
>
> This is close to the heart of the question. My example of that third-party 
> library is the database one,
> and it seems to say (based on its suggested usage) "You shouldn't need to 
> handle your context timeout, we'll make sure we do".
> Which, maybe works fine in that specific case, but in general feels a bit 
> awkward. It seems you would agree?

I am a bit confused about what you are asking here. I find it awkward
and risky if I cannot pass down a cancelable context down the stack
where things may not return. But then, that's the only way to deal
with such third-party code. If goroutines leak, they leak, and
eventually you run out of memory, crash, and restart. Sometimes
failing and recovering is cheaper than fixing.

>
>>
>> If that operation never ends, the goroutine leaks.
>
>
> That's a good point. If you don't run code in a goroutine you can never leak 
> goroutines :-p
> It seems to me though, that if we are running things in goroutines, and 
> passing down the context,
> and the code being run in those goroutines isn't listening for cancellation 
> signals,
> which results in the running goroutine becoming leaked, then that feels like 
> a bug in that code (i.e not the callers responsibility).

>
>
>
>
> On Thu, 21 Sept 2023 at 05:34, burak serdar  wrote:
>>
>> On Wed, Sep 20, 2023 at 7:47 AM Jerry Londergaard
>>  wrote:
>> >
>> > When using a context.WithTimeout, I always felt that it should be the 
>> > function where the context was created should be the one that ensures that 
>> > it (the current function) does not block longer than intended. That is to 
>> > say, it should call context.WithTimeout(), and then run the subsequent 
>> > code in a goroutine (passing in the context most likely), whilst using a 
>> > select multiplexer to listen to when the context is cancelled (by the 
>> > timeout), and then resume. Here's an example of this 
>> > https://go.dev/play/p/EGNlJqo3hY5
>> >
>> > However, when I was looking at this on the go database docs, it seems to 
>> > say to push that logic further down the stack to the 'child' (or callee) 
>> > https://go.dev/doc/database/cancel-operations#:~:text=Canceling%20database%20operations%20after%20a%20timeout
>> >
>> > I think this is an alternative implementation of my first example, that is 
>> > analogous to what the database package is suggesting 
>> > https://go.dev/play/p/DABt-Z36T-F
>> >
>> > Whilst I understand that the child should listen for the signal and 
>> > clean-up what it's doing in the event of the cancellation, that's doesn't 
>> > feel like the same thing as the caller *relying* on that behaviour for the 
>> > caller function to resume running.
>> >
>> > How should I think about this? Am I missing something here?
>>
>> Both patterns have their uses. If the new goroutine can periodically
>> check context cancellation and needs to do some cleanup, then it is
>> best to pass the context down, clean up, and return on cancellation.
>> If the new goroutine cannot check context cancellation, then the
>> goroutine starting that new goroutine can deal with cancellation like
>> you did, hoping that the new goroutine eventually ends. I usually use
>> the former, but the latter has its uses if you are calling a
>> third-party library or some operation you cannot cancel. If that
>> operation never ends, the goroutine leaks.
>>
>> >
>> > --
>> > You received this message because you are subscribed to the Google Groups 
>> > "golang-nuts"

Re: [go-nuts] Ensure context timeout behaviour from caller, or callee ?

2023-09-20 Thread burak serdar
On Wed, Sep 20, 2023 at 7:47 AM Jerry Londergaard
 wrote:
>
> When using a context.WithTimeout, I always felt that it should be the 
> function where the context was created should be the one that ensures that it 
> (the current function) does not block longer than intended. That is to say, 
> it should call context.WithTimeout(), and then run the subsequent code in a 
> goroutine (passing in the context most likely), whilst using a select 
> multiplexer to listen to when the context is cancelled (by the timeout), and 
> then resume. Here's an example of this https://go.dev/play/p/EGNlJqo3hY5
>
> However, when I was looking at this on the go database docs, it seems to say 
> to push that logic further down the stack to the 'child' (or callee) 
> https://go.dev/doc/database/cancel-operations#:~:text=Canceling%20database%20operations%20after%20a%20timeout
>
> I think this is an alternative implementation of my first example, that is 
> analogous to what the database package is suggesting 
> https://go.dev/play/p/DABt-Z36T-F
>
> Whilst I understand that the child should listen for the signal and clean-up 
> what it's doing in the event of the cancellation, that's doesn't feel like 
> the same thing as the caller *relying* on that behaviour for the caller 
> function to resume running.
>
> How should I think about this? Am I missing something here?

Both patterns have their uses. If the new goroutine can periodically
check context cancellation and needs to do some cleanup, then it is
best to pass the context down, clean up, and return on cancellation.
If the new goroutine cannot check context cancellation, then the
goroutine starting that new goroutine can deal with cancellation like
you did, hoping that the new goroutine eventually ends. I usually use
the former, but the latter has its uses if you are calling a
third-party library or some operation you cannot cancel. If that
operation never ends, the goroutine leaks.

>
> --
> 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.
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/golang-nuts/f45936f2-36b3-46cb-aa93-9bbbf9438843n%40googlegroups.com.

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAMV2Rqr%2BsMQk8ho5gJToqoY%3DnqdDpFUt5t_S8cZzhgDHLJTNSQ%40mail.gmail.com.


Re: [go-nuts] Download large Zip file via sftp

2023-08-23 Thread burak serdar
On Wed, Aug 23, 2023 at 6:37 AM Phillip Siessl 
wrote:

> Hi
>
> i have some issues when i try to download a larger zip file (5GB) via the
> sftp package in go.
> about 20% of the time it runs through smoothly but the other 80% i get a
> panic with
> "fatal error: concurrent map writes writing to file" or "fatal error:
> concurrent map read and map write".
>

There are no map operations in the code you included. The error is
happening somewhere else. The panic should include enough information to
tell where it is coming from.


>
> this is the code for the download function:
>
> func DownloadZip(sc sftp.Client, remoteFile, localFile string) (err error)
> {
>
> fmt.Fprintf(os.Stdout, "Downloading [%s] to [%s] ...\n", remoteFile,
> localFile)
> srcFile, err := sc.OpenFile(remoteFile, (os.O_RDONLY))
> if err != nil {
> fmt.Fprintf(os.Stderr, "Unable to open remote file: %v\n", err)
> return
> }
>
> defer srcFile.Close()
> fmt.Println("Create locale file")
> dstFile, err := os.Create(localFile)
> if err != nil {
> fmt.Fprintf(os.Stderr, "Unable to open local file: %v\n", err)
> return
> }
> defer dstFile.Close()
> fmt.Println("Copy remote file")
> bytes, err := io.Copy(dstFile, srcFile)
> if err != nil {
> fmt.Fprintf(os.Stderr, "Unable to download remote file: %v\n", err)
> os.Exit(1)
> }
> fmt.Println("Save local file")
> fmt.Fprintf(os.Stdout, "%d bytes copied\n", bytes)
>
> return
> }
>
>
> If anybody has some ideas i would be very happy. thx
>
> --
> 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.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/7afc7aed-a362-4e93-aeec-d5a42005c10cn%40googlegroups.com
> 
> .
>

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAMV2RqrsPjb_dDC66KWOjytfiLi1MkJRqHi51vybmTKvyp7LNQ%40mail.gmail.com.


Re: [go-nuts] Is atomic.CompareAndSwap a read-aquire (even if it returns false)?

2023-08-20 Thread burak serdar
Based on the following description in the memory model, CAS counts as a
read:

"Some memory operations are read-like, including read, atomic read, mutex
lock, and channel receive. Other memory operations are write-like,
including write, atomic write, mutex unlock, channel send, and channel
close. Some, such as atomic compare-and-swap, are both read-like and
write-like."

On Sun, Aug 20, 2023 at 6:06 AM Antonio Caceres Cabrera <
juliocacerc...@gmail.com> wrote:

> Hi Gophers,
>
> I have a question about a more subtle part of the language, the memory
> model regarding atomic operations.
> The memory model doc on go.dev states:
> >If the effect of an atomic operation *A* is observed by atomic operation
> *B*, then *A* is synchronized before *B*.[...]
>
> I.e. "observing side-effects" by another atomic operation establishes a
> synchronizes-before and therefore a happen-before relationship between the
> write and the observation of that side-effect.
>
> My question is basically: Do only atomic *Loads* count as auch an
> "observation" or does CompareAndSwap also count here? Is there a
> happens-before between a Store and a later CompareAndSwap (independent of
> whether the CAS returns false or true?).
>
> I asked myself this because the documentation also makes a comparison to
> C++ and Java:
> >The preceding definition has the same semantics as C++’s sequentially
> consistent atomics and Java’s volatile variables.
>
> However, there is a small difference between the C++ CAS
> (compare_exchange) and Go's.
> In C++, if the swap fails (because the value of the atomic is not the
> provided expected old value), it will change the old value (which it
> receives as a reference) to the new value of the atomic. This makes it
> clear that it counts as a read in any case. In Go (and other languages,
> e.g. Java), CompareAndSwap does not do this. Thus, one could get the idea
> that maybe CompareAndSwap doesn't count as a "read" as far as memory model
> and compiler reorderings and so on are concerned, because it does not read
> the current value of the atomic on a "program level", returning nothing to
> the "user", it only reads (compares to) it internally in its inner workings.
>
> My question is thus: Does atomic.CompareAndSwap count as a read in this
> context and is there a happens-before relationship between a previous store
> and a later compare-and-swap (both if the CAS fails or succeeds?)
>
> Thank you all for reading this wall of text.
> -Antonio
>
> --
> 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.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/633df394-27f1-4416-9602-3c09ade78fban%40googlegroups.com
> 
> .
>

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAMV2Rqo6xmn-%3DYC4GFwgQhuGY15PnNOLcQro7%2B5D-e_4wm0zqA%40mail.gmail.com.


Re: [go-nuts] Best IDE for GO ?

2023-08-20 Thread burak serdar
On Sun, Aug 20, 2023 at 1:52 AM TheDiveO  wrote:

> well, our "(major) engineering orgs" leave the choice of IDE to our devs.
> Devs have different styles, so as long as they meed the demand, who cares.
>

I second that. IDE is a personal choice. For years, I've been using Emacs
to edit code, and that's what I still feel most comfortable with for most
development tasks. When I need to debug something, I use VSCode, but I find
editing code using VSCode very disturbing.

That said, based on the experience I have mentoring other developers using
IDEs, I agree with the viewpoint that IDEs promote productivity, but with
superficial knowledge. If you do not take the time to learn how certain
things work, the code you write may not be correct. Many questions on Stack
Overflow are simply answered by pointers to API docs, but people don't read
them because of code completion and code suggestion features of the IDEs.


>
> On Saturday, August 19, 2023 at 11:17:35 PM UTC+2 Robert Engels wrote:
>
>> Reread what I wrote. Vim with autocomplete, etc is not a simple text
>> editor with syntax coloring.
>>
>> Still every major software engineering org in the world uses an ide (or
>> multiple). I guess they don’t know what they are doing.
>>
>> Btw, Googles current IDE is based on VSCode.
>>
>> > On Aug 19, 2023, at 3:24 PM, Jan Mercl <0xj...@gmail.com> wrote:
>> >
>> > On Sat, Aug 19, 2023 at 10:06 PM Christian Stewart
>> >  wrote:
>> >
>> >> Autocomplete and a go language server (gopls) add a ton of speed
>> because you don't need to look up the docs for function and variable names.
>> And go to definition improves speed navigating code significantly.
>> >
>> > - Using autocomplete and go-to-definiton does not require VSCode or
>> > any other IDE.
>> > - I do use autocomplete and go-to-definition. When I said I use no
>> > IDE, that does not mean I don't use those features.
>> > - The speed of typing/inputting code is overally a rather negligible
>> > factor of the total time cost of developing/debugging and maintaining
>> > any non-toy project. IOW, it's not a significant metric of
>> > productivity.
>> >
>> >> But vim-go can do both, so why not just use it?
>> >
>> > Because I use govim? ;-)
>> >
>> > (But not for my large projects, gopls chokes on them still too often
>> > to tolerate it.)
>> >
>> > --
>> > 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...@googlegroups.com.
>> > To view this discussion on the web visit
>> https://groups.google.com/d/msgid/golang-nuts/CAA40n-XusymW6gb5OnDa_7QWAWPFSkwKYQMYUm-d7419EZ%2BGkQ%40mail.gmail.com.
>>
>>
> --
> 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.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/8d5b52de-ddee-461a-9ed5-9b0968382d17n%40googlegroups.com
> 
> .
>

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAMV2RqqGw-iK4KwVkzkkp9V-5OkGjNwHTQ8RO0HPePC27G23QA%40mail.gmail.com.


Re: [go-nuts] Clarification on code snippet

2023-08-04 Thread burak serdar
On Fri, Aug 4, 2023 at 10:33 AM alchemist vk  wrote:

> Hi folks,
>  In below code, I am invoking receiver api show() via a simple uInteger
> type variable instead of pointer, by which it expects to be invoked . Go
> being  strict with type casing and I was expecting a compiler error. But to
> my surprise, it compiled and executed successfully.  Can you folks please
> explain this behavior.
>
>
>
>
>
>
>
>
> *package mainimport "fmt"type uInteger intfunc main() {var x uInteger
> = 10x.show()*
>

Above, the variable x is addressable, so the compiler passes  to show().

To call a pointer receiver method of a variable, that variable has to be
addressable (it doesn't have to be a pointer), so the compiler knows how to
pass the address of it. Here's how it is described in the spec:

https://go.dev/ref/spec#Method_values


>
>
>
>
> *}func (x *uInteger) show() {   fmt.Printf("In show, x = %d\n", *x)}*
>
> Thanks in Advance,
> Venkatesh
>
> --
> 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.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/CAJr0cerqTGvQA56yQWVYW3F2Ms5vbwq3YyO%2But%3DzJ%2BM4rqf81A%40mail.gmail.com
> 
> .
>

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAMV2Rqq%2BZi7ioHi4PPXTmQ7du45LRJaEiSSWJpf1zeH%2Bq3Wjeg%40mail.gmail.com.


Re: [go-nuts] Hard-to-explain race detector report

2023-06-08 Thread burak serdar
On Wed, Jun 7, 2023 at 2:19 PM Sven Anderson  wrote:

>
>
> Caleb Spare  schrieb am Mi. 7. Juni 2023 um 19:22:
>
>> On Wed, Jun 7, 2023 at 2:33 AM Sven Anderson  wrote:
>> >
>> > That’s not only a read/write race, it’s also a write/write race. Every
>> request to the server creates a new Go routine that might increment
>> newConns in parallel, so it may get corrupted. Same for lines 39/40.
>> >
>> > You might claim, that for infrastructural reasons, there can be no
>> concurrent requests to your server, but that would just mean that the race
>> is not triggered, it’s there nevertheless.
>>
>> The race detector reports on races that actually happened, not races
>> that could happen.
>>
>
> A race condition is a condition, not an event, so I think „happened“ is
> not correct, but maybe someone who knows the heuristics of the race
> detector better can clear that up.
>

The race detector reports when shared memory is accessed concurrently from
multiple goroutines. So it detects when a memory race happens. In this case
however, what is reported is a concurrent write-after-read. Is that really
a memory race?


>
> And why would it matter then if it understands the causalities of TCP? One
> must be incorrect: Either your understanding of the TCP causalities or of
> how the race detector is working, because it does indeed report something,
> right? ;-)
>
>
> >
>> > Caleb Spare  schrieb am Mi. 7. Juni 2023 um 01:31:
>> >>
>> >> Can  someone explain why the following test shows a race between the
>> >> indicated lines?
>> >>
>> >>
>> https://github.com/cespare/misc/blob/b2e201dfbe36504c88e521e02bc5d8fbb04a4532/httprace/httprace_test.go#L12-L43
>> >>
>> >> The race seems to be triggered by the very last line of the test:
>> >>
>> >> get(client1)
>> >>
>> >> If I comment that out, then the race detector doesn't complain. But
>> >> then it seems that a read of a variable which happens before an HTTP
>> >> request which causes a write of the variable ultimately races with the
>> >> original read, which doesn't make sense.
>> >>
>> >> It seems like a false positive (perhaps the race detector doesn't
>> >> understand causality across a TCP connection?), but so far I've never
>> >> seen the race detector have a false positive, so I think I must be
>> >> missing something.
>> >>
>> >> I wrote a slightly simpler test (see TestHTTPRace2 right below in the
>> >> same file) which tries to make the race happen using a regular HTTP
>> >> handler and a single client and the race detector doesn't complain.
>> >>
>> >> Caleb
>> >>
>> >> --
>> >> 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.
>> >> To view this discussion on the web visit
>> https://groups.google.com/d/msgid/golang-nuts/CAGeFq%2B%3DZGE5agaLYDgsdYvykbaWwHgjtKJf9q%2B1YJhR26%3DY45Q%40mail.gmail.com
>> .
>> >>
>>
>> --
> 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.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/CAFwXxZTO0fsRRK%3DiShNL1xjbaXN7tDc8wN_uAy3J3FQXPwK7Pg%40mail.gmail.com
> 
> .
>

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAMV2RqqicsyJv7%3DKAa4atEc%3DB%3DrdahbNw%2BzqPO7Q6CzZobCgPQ%40mail.gmail.com.


Re: [go-nuts] Hard-to-explain race detector report

2023-06-07 Thread burak serdar
On Wed, Jun 7, 2023, 12:33 PM Sven Anderson  wrote:

> That’s not only a read/write race, it’s also a write/write race. Every
> request to the server creates a new Go routine that might increment
> newConns in parallel, so it may get corrupted. Same for lines 39/40.
>

The write/write race will happen only if the increment is done from with
the new goroutine. If the increment is done after accepting a connection
but before starting a new goroutine there is no write/write race, right?

But that is not the problem here. Race detector is complaining about a
concurrent write after read


> You might claim, that for infrastructural reasons, there can be no
> concurrent requests to your server, but that would just mean that the race
> is not triggered, it’s there nevertheless.
>
> Caleb Spare  schrieb am Mi. 7. Juni 2023 um 01:31:
>
>> Can  someone explain why the following test shows a race between the
>> indicated lines?
>>
>>
>> https://github.com/cespare/misc/blob/b2e201dfbe36504c88e521e02bc5d8fbb04a4532/httprace/httprace_test.go#L12-L43
>>
>> The race seems to be triggered by the very last line of the test:
>>
>> get(client1)
>>
>> If I comment that out, then the race detector doesn't complain. But
>> then it seems that a read of a variable which happens before an HTTP
>> request which causes a write of the variable ultimately races with the
>> original read, which doesn't make sense.
>>
>> It seems like a false positive (perhaps the race detector doesn't
>> understand causality across a TCP connection?), but so far I've never
>> seen the race detector have a false positive, so I think I must be
>> missing something.
>>
>> I wrote a slightly simpler test (see TestHTTPRace2 right below in the
>> same file) which tries to make the race happen using a regular HTTP
>> handler and a single client and the race detector doesn't complain.
>>
>> Caleb
>>
>> --
>> 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.
>> To view this discussion on the web visit
>> https://groups.google.com/d/msgid/golang-nuts/CAGeFq%2B%3DZGE5agaLYDgsdYvykbaWwHgjtKJf9q%2B1YJhR26%3DY45Q%40mail.gmail.com
>> .
>>
>> --
> 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.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/CAFwXxZSzEUtf9M-b0nNYa%2B%3DiaxK%2BmfnJk%3DASKDp1kj2Cx7WqQA%40mail.gmail.com
> 
> .
>

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAMV2RqqXFDCFzugXXq-Q0fbTYKqZ1t5KSu06LUtEesRsbja87w%40mail.gmail.com.


Re: [go-nuts] Hard-to-explain race detector report

2023-06-07 Thread burak serdar
On Tue, Jun 6, 2023 at 5:31 PM Caleb Spare  wrote:

> Can  someone explain why the following test shows a race between the
> indicated lines?
>
>
> https://github.com/cespare/misc/blob/b2e201dfbe36504c88e521e02bc5d8fbb04a4532/httprace/httprace_test.go#L12-L43
>
> The race seems to be triggered by the very last line of the test:
>
> get(client1)
>
> If I comment that out, then the race detector doesn't complain. But
> then it seems that a read of a variable which happens before an HTTP
> request which causes a write of the variable ultimately races with the
> original read, which doesn't make sense.
>

I ran that test. As you said, the race detector complains about the
concurrent write to a variable that was read before in another goroutine.

It is technically what the race detector calls a race because it is
unsynchronized concurrent access to a shared variable. It does look like a
false-positive though.


>
> It seems like a false positive (perhaps the race detector doesn't
> understand causality across a TCP connection?), but so far I've never
> seen the race detector have a false positive, so I think I must be
> missing something.
>
> I wrote a slightly simpler test (see TestHTTPRace2 right below in the
> same file) which tries to make the race happen using a regular HTTP
> handler and a single client and the race detector doesn't complain.
>
> Caleb
>
> --
> 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.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/CAGeFq%2B%3DZGE5agaLYDgsdYvykbaWwHgjtKJf9q%2B1YJhR26%3DY45Q%40mail.gmail.com
> .
>

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAMV2Rqpj%2BpGo49kbfWp%2BF4WrdP_xYpKyjfWuLaOx9vi8hQ1Nhw%40mail.gmail.com.


Re: [go-nuts] Re: Amateur's questions about "Go lang spec"

2023-06-03 Thread burak serdar
On Sat, Jun 3, 2023 at 1:40 PM peterGo  wrote:

>
> Kamil Ziemian,
>
> // list of prime numbers
> primes := []int{2, 3, 5, 7, 9, 2147483647}
>
> The variable prime is a list of some prime numbers starting with the
> lowest and ending with the highest prime numbers that can safely be
> represented an int. An int may either 32 or 64 bits.
>
> Please explain the joke.
>

Could it be that 9 is not prime?


>
>
> Note: “Explaining a joke is like dissecting a frog. You understand it
> better but the frog dies in the process.”
> ― E.B. White
>
> peter
> On Saturday, June 3, 2023 at 3:13:28 PM UTC-4 Kamil Ziemian wrote:
>
>> Is this example found in the "Composite literals" section of Go Spec a
>> joke?
>> // list of prime numbers
>> primes := []int{2, 3, 5, 7, 9, 2147483647 <(214)%20748-3647>}
>>
>> I checked on the internet and 2147483647 <(214)%20748-3647> is a prime
>> number (https://en.wikipedia.org/wiki/2,147,483,647), so this element is
>> fine.
>>
>> Best regards
>> Kamil
>>
>> czwartek, 4 maja 2023 o 16:38:50 UTC+2 Kamil Ziemian napisał(a):
>>
>>> You convince me to your point Axel Wagner. At the same time if we look
>>> at examples in Go Spec, I think their can be improved.
>>> "A0, A1, and []string
>>> A2 and struct{ a, b int }
>>> A3 and int A4, func(int, float64) *[]string, and A5
>>>
>>> B0 and C0
>>> D0[int, string] and E0
>>> []int and []int
>>> struct{ a, b *B5 } and struct{ a, b *B5 }
>>> func(x int, y float64) *[]string, func(int, float64) (result *[]string),
>>> and A5"
>>> I mean, first we need to check that A0, A1 and []string are the same
>>> type and after few examples like D0[int, string] is the same as E0, we have
>>> stated []int and []int are the same type. If you convince yourself that A0
>>> is the same as A1 and both are the same as []string, checking that []int
>>> has the same type as []int is quite trivial. I would prefer that examples
>>> would start from basic cases like []int is []int and []A3 is []int (if this
>>> one is true) and progress to more convoluted like D0[int, string] is E0.
>>>
>>> Best regards,
>>> Kamil
>>>
>>> czwartek, 4 maja 2023 o 14:12:25 UTC+2 Axel Wagner napisał(a):
>>>
 Personally, I'd rather add more examples of "self-evidently equal
 types". In my opinion, all the type aliases in that block confuse matters
 quite a bit.

 "[]int and []int are identical" is not actually self-evident at all. It
 is self-evident that any sensible definition of type identity *should* make
 them identical. But it's not self-evident that the given definition *does*.
 Spelling that out in the example, means you are nudged to look at the
 definition and see how their identity follows (by finding "Two slice types
 are identical if they have identical element types").

 In fact, whenever you define an equivalence relation, proving that it
 is reflexive is the very first step. And it's not always trivial. For
 example, `==` on `float64` is *not* reflexive. It seems obvious that NaN ==
 NaN *should* hold from how it's spelled - but it doesn't.

 So, I disagree that the examples should limit themselves to cases where
 it's non-obvious that the two types should be identical.

 On Thu, May 4, 2023 at 12:35 PM Kamil Ziemian 
 wrote:

> There is a second such example just below "[]int and []int", but to
> understand it we need some more type declarations, I listed them below.
> `type (
> A0 = []string
> A1 = A0
> A2 = struct{ a, b int }
> A3 = int
> A4 = func(A3, float64) *A0
> A5 = func(x int, _ float64) *[]string
>
> B0 A0
> B1 []string
> B2 struct{ a, b int }
> B3 struct{ a, c int }
> B4 func(int, float64) *B0
> B5 func(x int, y float64) *A1
>
> // Unimportant part.
> )`
> The line in question is
> "struct{ a, b *B5 } and struct{ a, b *B5 }"
> which is true, but again feel out of place. I only start grasping
> rules of types identity, but I make guess that it should be something like
> "struct{ a, b *A5 } and struct{ a, b *B5 }"
>
> Of course it my just be that I'm just stupid. Feel free to inform me
> that indeed I have no idea what is going on in the Go Spec.
>
> Best regards,
> Kamil
> czwartek, 4 maja 2023 o 12:20:35 UTC+2 Kamil Ziemian napisał(a):
>
>> Hello,
>>
>> In the section "Type identity" of Go Spec we read a list of type
>> declarations
>> `type (
>> A0 = []string
>> A1 = A0
>> A2 = struct{ a, b int }
>> A3 = int
>> A4 = func(A3, float64) *A0
>> A5 = func(x int, _ float64) *[]string
>>
>> // Part unimportant for my point.
>> )`
>> and then we have list of types that are identical. Among them we can
>> find text
>> "[]int and []int"
>> It is obviously true, but feel out of place. I make a humble guess
>> that authors intended something along the lines
>> "[]A3 and []int"
>> 

Re: [go-nuts] Using struct{} for context keys

2023-05-28 Thread burak serdar
Two values A and B are equal (A==B) if A and B have the same type and the
same values. In a code where

 a:=clientContextKey{}
  b:=clientContextKey{}

a==b is true, because they have the same types, and they have the same
values (i.e. the empty value).

Note however:

a:={}
b:={}

It is not guaranteed that a==b, neither is it guaranteed that a!=b. The
compiler may choose to allocate the same address for the zero-size
variables a and b, or it may not,

On Sun, May 28, 2023 at 7:01 AM cpu...@gmail.com  wrote:

> I've recently stumbled across code like this
> https://go.dev/play/p/u3UER2ywRlr:
>
> type clientContextKey struct{}
>
> ctx := context.Background()
> ctx = context.WithValue(ctx, clientContextKey{}, "foo")
> _, ok := ctx.Value(clientContextKey{}).(string)
>
> Naively, I had expected this to fail since I assumed that
> clientContextKey{} would create a new variable instance every time it was
> used and hence the keys would not match.
>
> Why does this use of instantiating the struct type work here?
>
> Thanks,
> Andi
>
> --
> 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.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/55783f87-bad8-4ca4-9c4a-d8686ae156abn%40googlegroups.com
> 
> .
>

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAMV2RqoMjPmdo1Xri%3DFAz%2BkXwub-Xo7DPyaX%3DB9%2BSG7fKmbDxg%40mail.gmail.com.


Re: [go-nuts] Experience with building JS and Python bindings for a Go library

2023-05-22 Thread burak serdar
On Mon, May 22, 2023 at 6:35 PM Taco de Wolff  wrote:

> I would like to know if anyone has experience with building bindings for
> JavaScript (NodeJS) and Python for a Go library. Who has worked on this, or
> does anybody know of libraries that have succeeded?
>

I used the following two libraries for running JS from Go:

There is a V8 binding using Cgo: https://github.com/rogchap/v8go
And there is a pure Go JS interpreter: https://github.com/robertkrimen/otto


> In particular, I have successfully built working JS and Python bindings
> (see https://github.com/tdewolff/minify/tree/master/bindings), but I have
> two problems:
>
> - How does the Go standard library (CGO) work in conjunction with
> forked/worker threads of JS/Python? See
> https://github.com/tdewolff/minify/issues/518#issuecomment-1256812343
> - How can I prebuild binaries for Windows for a JS binding? In particular,
> node-gyp allows you to build addons which is working fine for Linux/MacOS,
> however they only permit using MSVC on WIndows and Go/CGO only can use GCC.
> I'm suspecting this is behind an error we have (Error: Module did not
> self-register)
>
> I would love to hear about example or people with experience! Thanks in
> advance!
>
> --
> 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.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/7c18fb1e-1737-447c-9a86-04d52cf0b2f9n%40googlegroups.com
> 
> .
>

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAMV2Rqpj%3DFeu-WdBNv7CXMLe1P-C4QvPL3Rip6yGisH8TQ0TpA%40mail.gmail.com.


Re: [go-nuts] Immediately Cancel Goroutine?

2023-04-12 Thread burak serdar
On Wed, Apr 12, 2023 at 7:29 AM Frank  wrote:

> Hi Gophers,
>
> So I've run into a situation where my code would run for a rather long
> time (10minutes - ~1 hour). And I want to cancel it halfway sometimes. I
> know I can use channel/context can check for channel message to return
> early. But this requires explicitly checking for channel status and would
> introduce many messy code blocks. Is it feasible (and good) for me to
> listen to some signal and use panic to stop the execution once signal
> received?
>

There are ways to reduce the boilerplate code. For instance:

func LongTask(ctx context.Context) {
   canceled:=func() bool {
  select {
case <-ctx.Done(): return true
default:
  }
 return false
  }
  ...
  if canceled() {
  return
   }
}

Or, if this involves lots of nesting, you can define:

 canceled:=func() {
  select {
case <-ctx.Done(): panic(errCanceled)
default:
  }
  }

so every now and then you can simply call canceled(). If you do this
though, you need to recover:

go func() {
   defer func() {
   if r:=recover(); r!=nil {
  if errors.Is(r,errCanceled) {
 // canceled
  } else {
panic(r)
 }
   }
   }()
   LongTask(ctx)
}()


There is no way you can immediately stop a goroutine. Handling of a signal
has to happen in a separate goroutine, and you would still need to check
periodically in the actual goroutine you want to cancel.


> Thanks!
> Frank
>
> --
> 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.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/d8bb51be-4f21-4658-93a9-d0e197b9bdden%40googlegroups.com
> 
> .
>

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAMV2RqrKAo4br2jrUxEN4%3DL-y0AX-wVW4DOBMcRbc3KK4RZakA%40mail.gmail.com.


Re: [go-nuts] Map of Types is impossible, is there any alternative solution?

2023-04-11 Thread burak serdar
You can do:

var messageProcessors = map[uint8]func([]byte) Message {
  0: processorForType0,
  1: processorForType1,
  ...
}

Then:

output:=messageProcessors[id](payload)

Of course, with the appropriate error checks.

On Tue, Apr 11, 2023 at 3:13 PM Bèrto ëd Sèra 
wrote:

> I do know there's no way to use
> var rule = map[uint8]Message{
> 0: thisType,
> 1: thatType,
> 4: someOtherType,
> .
> }
>
> type Message interface {
> 
> Become(data []byte)
> 
> }
>
> type thisType struct {
> data []byte
> }
> func (my *thisType) Become(data []byte) { }
> type thatType struct {
> data []byte
> }
> func (my *thatType) Become(data []byte) { }
>
> WHAT I'M TRYING TO DO IS: I receive a data packet via UDP, it has an Id
> byte, a payload and ends with a crc32.
> |id|payload|crc32
>
> Upon reception I need to encapsulate the payload into a struct, and choose
> the right type of struct depending on the value of the ID byte. Different
> kinds of payloads get managed by different types of structs, the interface
> ensure all needed structs implement a common API.
>
> I wonder if there's a way to do what I'm trying to do without using a
> switch. Anything as declarative as a map would make things a lot easier for
> anyone who isn't familiar with the code.  However, I see no way to use a
> map for this.
>
> Thanks in advance
> Berto
>
> --
> 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.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/48c7bcaf-8836-44ce-9ccc-df2c53c90365n%40googlegroups.com
> 
> .
>

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAMV2RqoJk%2BpsZmVVi-enohqQzY%3Dh0uYX7b3ak0S9GkPuO%2Bemhg%40mail.gmail.com.


Re: [go-nuts] Interesting "select" examples

2023-04-03 Thread burak serdar
Below is part of a generic ordered fan-in for data pipelines. It works by
reading data from multiple channels using one goroutine for each channel,
sending that data element to another goroutine that does the actual
ordering, but in the mean time, pauses the pipeline stage until all
out-of-order data elements are sent.

func orderedFanIn[T sequenced](done <-chan struct{}, channels ...<-chan T)
<-chan T {
  fanInCh := make(chan fanInRecord[T])
  wg := sync.WaitGroup{}
  for i := range channels {
pauseCh := make(chan struct{})
wg.Add(1)
// Create one goroutine for each incoming channel
go func(index int, pause chan struct{}) {
  defer wg.Done()
  for {
var ok bool
var data T
select {
case data, ok = <-channels[index]:
  if !ok {
return
  }
  // Send data to the ordering goroutine with the pause channel
  fanInCh <- fanInRecord[T]{
index: index,
data:  data,
pause: pause,
  }
case <-done:
return
}
// Pause the pipeline stage until the ordering goroutine writes to the
pause channel
select {
  case <-pause:
  case <-done:
return
}
 }
}(i, pauseCh)
}

On Sun, Apr 2, 2023 at 9:44 PM Nigel Tao  wrote:

> I'm working on a multi-threaded C++ project. We have the equivalent of
> Go's channels, and are considering whether we also need to implement
> the equivalent of Go's select.
>
> Does anyone have interesting, non-trivial examples of a Go select
> statement in real code?
>
> By non-trivial, I mean that a lot of the selects that I've seen have
> exactly two cases, one of them doing "real work" and the other being
> either (1) "default" or (2) a timeout/cancel channel (e.g.
> ctx.Done()).
>
> In our C++ API, our channel send/recv methods already have
> try_send/try_recv equivalents for (1) and a timeout/cancel mechanism
> for (2).
>
> bcmills' "Rethinking Classical
> Concurrency Patterns"
> (https://drive.google.com/file/d/1nPdvhB0PutEJzdCq5ms6UI58dp50fcAN/view)
> uses select to implement higher level ResourcePool / WorkerPool APIs
> but select is arguably a private implementation detail. While it might
> not be as beautiful under the hood, I think we can already present
> similar APIs using C++'s std::counting_semaphore.
>
> r's "A Concurrent Window System"
> (https://swtch.com/~rsc/thread/cws.pdf) discusses select'ing from
> separate window, keyboard and mouse channels but this could arguably
> instead be a single channel of heterogenous elements (e.g. in C++, a
> std::variant).
>
> It's more interesting to select over both input and output channels,
> and output channels may become "ready to communicate" without new
> input. But again, it may be possible to work around that by downstream
> actors sending "I'm ready to receive" events onto the upstream actor's
> heterogenous input channel.
>
> The most interesting selects I have so far is the
> golang.org/x/net/http2 source code, whose internals have a bit of a
> learning curve. If anyone has other examples, please share.
>
> --
> 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.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/CAOeFMNWBtuEci9oPUFNa0v0gDC%3DV6Xb0N05Jyxo%3DxN2ywJALGA%40mail.gmail.com
> .
>

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAMV2Rqq-_Xg_npzoJk89V2bbuo-oDH5kXQnGqPGixBGnQhjMmg%40mail.gmail.com.


Re: [go-nuts] HTTP client - streaming POST body?

2023-03-22 Thread burak serdar
On Wed, Mar 22, 2023 at 8:32 PM 'Christian Stewart' via golang-nuts <
golang-nuts@googlegroups.com> wrote:

> you can achieve this using an io.Pipe. The io.Pipe function returns a
> connected pair of *PipeReader and *PipeWriter, where writes to the
> *PipeWriter are directly read from the *PipeReader. The Write call on the
> *PipeWriter will block until the data is read from the *PipeReader.
>
> pr, pw := io.Pipe()
>
> Pass the pr as the body and write to the pw.
>

And when you are done generating the content, close pw.

>
> On Wed, Mar 22, 2023, 7:06 PM 'Jim Smart' via golang-nuts <
> golang-nuts@googlegroups.com> wrote:
>
>> The issue here, isn’t that I am uploading a big file — that’s easy.
>>
>> As I said in my initial post:
>>
>> > The use case here is that I'm wishing to send very large UPDATE/INSERT
>> queries/commands to an HTTP endpoint, and the body content of those
>> queries/commands is actually generated from a database.
>>
>> The content I wish to push to the server, is /generated/ content. So
>> really what I want is a something I can directly write into.
>>
>> I am trying to avoid generating my upload content into a buffer first.
>> Because the data can be very large.
>>
>> — It’s easy to say “write a reader” but writing it as a reader involves
>> doing complete inversion of control on my code, and isn’t really feasible.
>> I can’t easily make the code I have which has complex logic to build the
>> upload data using Writes, into something that is then driven by Reads.
>>
>> Which is why I asked if it was possible to somehow Write straight down
>> the connection.
>>
>>
>> — Thanks for the suggestions all the same.
>>
>> /J
>>
>>
>> --
>> 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.
>> To view this discussion on the web visit
>> https://groups.google.com/d/msgid/golang-nuts/C5B2823D-2458-4F91-A09D-6B12F74CD8B3%40jimsmart.org
>> .
>>
> --
> 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.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/CA%2Bh8R2pTUXsWPpywxhRJi_Bs3ZP0hmVP%3DkqZMe6FwJWJS-3BDg%40mail.gmail.com
> 
> .
>

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAMV2RqoO26VS-G05Y6U-b4VKJMUQPvMMun7SMZtbU0djJMQqEw%40mail.gmail.com.


Re: [go-nuts] Why can't a regexp.Regexp be const

2023-02-13 Thread burak serdar
This compiles just fine, but the regexp compilation fails:

https://go.dev/play/p/QvC8CIITUU6

On Mon, Feb 13, 2023 at 4:49 PM Pat Farrell  wrote:

> This won't compile
>
> var ExtRegex =
> regexp.MustCompile("(M|m)(p|P)(3|4))|((F|f)(L|l)(A|a)(C|c))$")
>
> with a
> ./prog.go:10:18:
> regexp.MustCompile("((M|m)(p|P)(3|4))|((F|f)(L|l)(A|a)(C|c))$") (value of
> type *regexp.Regexp) is not constant
>
> while
> const pat = "((M|m)(p|P)(3|4))|((F|f)(L|l)(A|a)(C|c))$"
> var ExtRegex = regexp.MustCompile(pat)
>
> Works fine.
> So, why can't the regexp be a constant?
> Is there some state that is kept in the regexp.Regexp store?
>
> And perhaps more importantly, what is the proper go style to
> have a compiled regexp?
> I could put the var statement outside all blocks, so its in effect
> a package variable. But I think having package variable is bad form.
>
> I'm using the regexp in a loop for all the strings in all the files in a
> directory tree.
> I really don't want to compile them for ever pass thru the lines
>
> Thanks
> Pat
>
> --
> 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.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/39ae6e9f-1c27-45cd-93c2-39a3b75cc6a3n%40googlegroups.com
> 
> .
>

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAMV2Rqpd0f1Ua1zsaJwYCNWJW_jZKUs5Vf-_wqPJ0o1cc39EOQ%40mail.gmail.com.


Re: [go-nuts] Upgradable RLock

2023-01-29 Thread burak serdar
On Sun, Jan 29, 2023 at 7:34 PM Diego Augusto Molina <
diegoaugustomol...@gmail.com> wrote:

> From times to times I write a scraper or some other tool that would
> authenticate to a service and then use the auth result to do stuff
> concurrently. But when auth expires, I need to synchronize all my
> goroutines and have a single one do the re-auth process, check the status,
> etc. and then arrange for all goroutines to go back to work using the new
> auth result.
>
> To generalize the problem: multiple goroutines read a cached value that
> expires at some point. When it does, they all should block and some I/O
> operation has to be performed by a single goroutine to renew the cached
> value, then unblock all other goroutines and have them use the new value.
>
> I solved this in the past in a number of ways: having a single goroutine
> that handles the cache by asking it for the value through a channel, using
> sync.Cond (which btw every time I decide to use I need to carefully re-read
> its docs and do lots of tests because I never get it right at first). But
> what I came to do lately is to implement an upgradable lock and have every
> goroutine do:
>


So how about using sync.Once:

type CacheEntry struct {
  Auth AuthInfo
  once sync.Once
}

Cache would be a map[CacheKey]*CacheEntry. When AuthInfo expires, you
simply replace it with a new one:

func (c *Cache) Expire(key CacheKey) {
  c.Lock()
  defer c.Unlock()
  c.cache[key]={}
}

func (c *Cache) Get(key CacheKey) Auth {
   c.RLock()
   entry:=c.cache[key]
c.RUnlock()
if entry==nil {
  c.Lock()
  entry=c.cache[key]
  if entry==nil {
 c.cache[key]={}
  }
  c.UnLock()
   }
entry.Do(func() {
// Authenticate
})
return entry.Auth
}



>
> **
> func (x implem) getProtectedValue() (someType, error) {
> // acquires a read lock that can be upgraded
> lock := x.upgradableLock.UpgradableRLock()
> // the Unlock method of the returned lock does the right thing
> // even if we later upgrade the lock
> defer lock.Unlock()
>
> // here we have read access to x.protectedValue
>
> // if the cached value is no longer valid, upgrade the lock
> // and update it
> if !isValid(x.protectedValue) && lock.TryUpgrade() {
>   // within this if, we know we *do* have write access
>   // to x.protectedValue
> x.protectedValue, x.protectedValueError = newProtectedValue()
> }
>
> // here we can only say everyone has read access to x.protectedValue
> // (the goroutine that got the lock upgrade could still write
> // here but as this code is shared, we should check the result
> // of the previous lock.TryUpgrade() again)
>
> return x.protectedValue, x.protectedValueError
> }
> **
>
> The implementation is quite simple:
> **
> // Upgradable implements all methods of sync.RWMutex, plus a new
> // method to acquire a read lock that can optionally be upgraded
> // to a write lock.
> type Upgradable struct {
> readers sync.RWMutex
> writers sync.RWMutex
> }
>
> func (m *Upgradable) RLock() { m.readers.RLock() }
> func (m *Upgradable) TryRLock() bool { return m.readers.TryRLock() }
> func (m *Upgradable) RUnlock() { m.readers.RUnlock() }
> func (m *Upgradable) RLocker() sync.Locker { return m.readers.RLocker() }
>
> func (m *Upgradable) Lock() {
> m.writers.Lock()
> m.readers.Lock()
> }
>
> func (m *Upgradable) TryLock() bool {
> if m.writers.TryLock() {
> if m.readers.TryLock() {
> return true
> }
> m.writers.Unlock()
> }
> return false
> }
>
> func (m *Upgradable) Unlock() {
> m.readers.Unlock()
> m.writers.Unlock()
> }
>
> // UpgradableRLock returns a read lock that can optionally be
> // upgraded to a write lock.
> func (m *Upgradable) UpgradableRLock() *UpgradableRLock {
> m.readers.RLock()
> return {
> m:  m,
> unlockFunc: m.RUnlock,
> }
> }
>
> // UpgradableRLock is a read lock that can be upgraded to a write
> // lock. This is acquired by calling (*Upgradable).
> // UpgradableRLock().
> type UpgradableRLock struct {
> mu sync.Mutex
> m  *Upgradable
> unlockFunc func()
> }
>
> // TryUpgrade will attempt to upgrade the acquired read lock to
> // a write lock, and return whether it succeeded. If it didn't
> // succeed then it will block until the goroutine that succeeded
> // calls Unlock(). After unblocking, the read lock will still be
> // valid until calling Unblock().
> //
> // TryUpgrade panics if called more than once or if called after
> // Unlock.
> func (u *UpgradableRLock) TryUpgrade() (ok bool) {
> u.mu.Lock()
> defer u.mu.Unlock()
>
> if u.m == nil {
> panic("TryUpgrade can only be called once and not after Unlock")
> }
>
> if ok = u.m.writers.TryLock(); ok {
> u.m.readers.RUnlock()
> u.m.readers.Lock()
> u.unlockFunc = u.m.Unlock
>
> } else {
> u.m.readers.RUnlock()
> 

Re: [go-nuts] Clarification of memory model behavior within a single goroutine

2023-01-21 Thread burak serdar
On Sat, Jan 21, 2023 at 12:11 PM Peter Rabbitson (ribasushi) <
ribasu...@gmail.com> wrote:

> On Saturday, January 21, 2023 at 7:48:12 PM UTC+1 bse...@computer.org
> wrote:
> On Sat, Jan 21, 2023 at 10:36 AM Peter Rabbitson 
> wrote:
> Greetings,
>
> I am trying to understand the exact mechanics of memory write ordering
> from within the same goroutine. I wrote a self-contained runnable example
> with the question inlined here: https://go.dev/play/p/ZXMg_Qq3ygF and am
> copying its header here:
>
> // Below is a complete example, with the question starting on line 38:
> // how do I ensure that a *separate Linux OS process* observing `IPCfile`
> // (either via pread() or mmap()) can *NEVER* observe W2 before W1.
> // The only permissible states are:
> // 1. no changes visible
> // 2. only W1 is visible
> // 3. both W1 and W2 are visible
>
> This is based on my interpretation of the go memory model:
>
> Atomic memory operations are sequentially consistent, so here:
>
>  (*mmapBufAtomic.Load())[fSize-1] = 255 // W1
> (*mmapBufAtomic.Load())[0] = 42// W2
>
> The first atomic load happens before the second load. That also implies
> the first write (W1) happens before the second (W2). However, there is no
> guarantee that W2 will be observed by another goroutine.
>
> This is perfectly acceptable ( see point 2. above ). Also note that there
> is no other goroutine that is looking at this: the observers are separate (
> possibly not even go-based ) OS processes. I am strictly trying to get to a
> point where the writer process exemplified in the playground will issue the
> CPU write instructions in the order I expect.
>
>
> I think what is really needed here is an atomic store byte operation. If
> this is the only goroutine writing to this buffer, you can emulate that by
> atomic.LoadUint32, set the highest/lowest byte, then atomic.StoreUint32
>
> This would not be viable: the W1 write is a single byte for the sake of
> brevity. In practice it will be a multi-GiB write, with a multi-KiB  write
> following it, followed by a single-UInt write. All part of a lock-free
> "ratcheted" transactional implementation, allowing for incomplete writes,
> but no dirty reads - the "root pointer" is the last thing being updated, so
> an observer process sees "old state" or "new state" and nothing inbetween.
> This is why my quest to understand the precise behavior and guarantees of
> the resulting compiled program.
>


You realize, if W1 is a multi-GB write, another process will
observe partial writes for W1. But, I believe, if another process observes
W2, then it is guaranteed that all of W1 is written.

I think the Go memory model does not really apply here, because you are
talking about other processes reading shared memory. What you are really
relying on is that on x86, there will be a memory barrier associated with
atomic loads. I don't know how this works on arm. I am not sure how
portable this solution would be. The memory model is explicit about
observing the effects of an atomic write operation, and sequential
consistency of atomic memory operations. So it sounds like an unprotected
W1 followed by an atomic store of W2 would still work the same way.


> --
> 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.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/c23d512e-a307-4f4d-bf23-74398c5cf42bn%40googlegroups.com
> 
> .
>

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAMV2RqowLALwe8yHsOLROOi5OFFY8sn9y4hdFYDgLyN9GnssLA%40mail.gmail.com.


Re: [go-nuts] Clarification of memory model behavior within a single goroutine

2023-01-21 Thread burak serdar
On Sat, Jan 21, 2023 at 10:36 AM Peter Rabbitson 
wrote:

> Greetings,
>
> I am trying to understand the exact mechanics of memory write ordering
> from within the same goroutine. I wrote a self-contained runnable example
> with the question inlined here: https://go.dev/play/p/ZXMg_Qq3ygF and am
> copying its header here:
>
> // Below is a complete example, with the question starting on line 38:
> // how do I ensure that a *separate Linux OS process* observing `IPCfile`
> // (either via pread() or mmap()) can *NEVER* observe W2 before W1.
> // The only permissible states are:
> // 1. no changes visible
> // 2. only W1 is visible
> // 3. both W1 and W2 are visible
>

This is based on my interpretation of the go memory model:

Atomic memory operations are sequentially consistent, so here:

 (*mmapBufAtomic.Load())[fSize-1] = 255 // W1
(*mmapBufAtomic.Load())[0] = 42// W2

The first atomic load happens before the second load. That also implies the
first write (W1) happens before the second (W2). However, there is no
guarantee that W2 will be observed by another goroutine.

I think what is really needed here is an atomic store byte operation. If
this is the only goroutine writing to this buffer, you can emulate that by
atomic.LoadUint32, set the highest/lowest byte, then atomic.StoreUint32



>
> I did read through https://go.dev/ref/mem and
> https://github.com/golang/go/discussions/47141 + links, but could not
> find a definitive answer to my specific use-case.
>
> Would really appreciate any help getting to the bottom of this!
>
> --
> 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.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/CAMrvTSKXb5JQMR9PcCXwYhcT4rq8O_5hiTHrOChk6sUeOrbagw%40mail.gmail.com
> 
> .
>

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAMV2RqpAFDV9DJcydk3DD8%3DkdizJygBirq6Ub-VkKV2xK120Lw%40mail.gmail.com.


Re: [go-nuts] Simple Regexp fails but more complex one finds match

2023-01-19 Thread burak serdar
This:

(-)*

matches the empty string as well, and that's what it is returning. Try (-)+

On Thu, Jan 19, 2023 at 12:16 PM Pat Farrell  wrote:

> This has to be something simple, but I've been pulling my hair out for
> days.
> I have made two regexp.MustCompile where one is just a simple punctuation
> search and the other is a combination of an identifier plus the
> punctuation search.
> I am building the patterns with two strings that I concatinate as argument
> to the MustCompile.
>
> The complex Find works, but the simplier one returns nothing.
> This is the opposite of what I expected.
>
> Playground:
> https://go.dev/play/p/4gp43BvwRwo
>
> The code is near trivial,
> The output in the playground shows an empty slice when Find is
> called on the punctuation, yet
> returns the expected slice on the more complex pattern:
> output:
> ><
> Heart -
> Program exited.
>
> Source:
> package main
>
> import (
> "fmt"
> "regexp"
> )
>
> func main() {
> var fn = []byte("Heart - Crazy On You")
> const nameP = "(([0-9A-Za-z]*)\\s*)*"
> const divP = "-*"
> var regMulti = regexp.MustCompile(nameP + divP)
> var regPunch = regexp.MustCompile(divP)
>
> p := regPunch.Find(fn)
> fmt.Printf(">%s<\n", p)
>
> m := regMulti.Find(fn)
> fmt.Printf("%s\n", m)
> }
>
> Any enlightenment would be greatly appreciated.
>
> --
> 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.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/51915214-d52a-431d-aca4-bbdda2b380een%40googlegroups.com
> 
> .
>

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAMV2Rqo2PaAPZuW_b6aNLjXxEz3-HaM1vW-8Q3sx6xwhWej99g%40mail.gmail.com.


Re: [go-nuts] Go 1.19 comparison of variables of generic type

2023-01-18 Thread burak serdar
On Wed, Jan 18, 2023 at 5:52 PM Andrew Athan  wrote:

> (Possibly related to issues such as those discussed in
> https://groups.google.com/g/golang-nuts/c/pO2sclKEoQs/m/5JYjveKgCQAJ ?)
>
> If I do:
>
> ```
> func Foo[V any](v V)bool {
>   return v==v
> }
> ```
>
> golang 1.19 reports:
>
> ```
> invalid operation: v == v (incomparable types in type set)
> ```
>
> There are two issues with this in my mind: (1) It is ambiguous in that I
> cannot be sure, as a new user, whether what's being indicated is an
> incompatibility between the actual types on either side of the equality
> test or between the set of possible types that COULD be on either side of
> the equality test due to V's any type constraing in either the case where
> the left and right side are same or different types (2) In this case, the
> type V appears to be determinable at compile time and yet it is claimed
> this equality test is in some way problematic.
>
> I'm sure I'm misunderstanding something about golang generics.
>
> Can someone comment on this?
>
> Thanks in advance :)
>


The problem here is that a type constraint is different from a type, but
the same identifier is overloaded in the language so "any" as a type
constraint means something else from "any" as a type.

The error is there, because without that Foo([]string{}) would satisfy the
constraint but it is still a compile error. Foo[V comparable)(v V) bool is
the correct declaration.


>
> --
> 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.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/7134400e-ed5e-4c9f-bacd-4b739daf0e0bn%40googlegroups.com
> 
> .
>

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAMV2Rqo_nrhZfvJ_9qykTkg%3DTxbgdZMC7zFHx1rNnGcdgQk8cA%40mail.gmail.com.


Re: [go-nuts] Re: Why not tuples?

2022-12-03 Thread burak serdar
On Sat, Dec 3, 2022 at 8:47 PM Diogo Baeder  wrote:

> Hi there, sorry for weighting in so late in the game, but I just started
> again to learn Go and was thinking why the language still doesn't have a
> tuple type.
>
> Now, imagine this scenario: I have a web application which has to access a
> webservice that responds with JSON payloads; These payloads are a list of
> values, where each value is a smaller list like '[20220101, 1.234, "New
> York"]'. And these smaller lists follow the same type sequence: int64,
> float64, string. Suppose that I want to filter those values and send a
> response to the client, with the data structure unchanged (same format and
> types). Today, it doesn't seem to be possible to do that in Go, unless I do
> some dirty hack like decoding to '[]any' and then cast to the other types,
> and then hack again to put these values in the response to the client.
>

What you described above is a struct.


>
> I totally understand the reasoning for preferring the usage of structs for
> heterogeneous data (and I myself do prefer them, they're much more powerful
> in general), but there's real world data that's available like in the
> example above, and we just can't go on changing them at their sources. I
> might be mistaken (please let me know if it's the case), but it seems like
> Go is missing an opportunity to interoperate with what's a fundamental data
> structure in many other languages (Python, Rust etc). I'm having a lot of
> fun learning to use the language, and would be happy to see this feature
> being implemented at the core.
>

In general, you can implement most tuple functionality using []any.
However, when dealing with unpredictable data structures like an unknown
JSON document, third-party libraries might be better suited than a
map[string]any. When you have a tuple like that, you have to "discover" the
type of each variable and parse it to do any nontrivial processing. You
can't really unmarshal a string from a JSON document and expect to get a
date in the tuple. My current work is on the interoperability of
heterogeneous data, so for XML documents we use DOM libraries, for JSON
documents we wrote https://github.com/bserdar/jsonom, etc.


>
> (Maybe what I said above is total BS, I acknowledge that since I'm an
> almost complete ignorant in the language)
>
> Cheers!
>
> On Thursday, April 19, 2018 at 1:03:55 PM UTC-3 Louki Sumirniy wrote:
>
>> Multiple return values. They do kinda exist in a declarative form of
>> sorts, in the type signature, this sets the number and sequence and types
>> of return values. You could even make functions accept them as also input
>> values, I think, but I don't think it works exactly like this. I'm not a
>> fan of these things because of how you have to nominate variables or _ and
>> type inference will make these new variables, if you  := into whatever the
>> return was.
>>
>> I'm not sure what the correct word is for them. Untyped in the same way
>> that literals can be multiple types (especially integers) but singular in
>> their literal form.
>>
>>
>> On Thursday, 19 April 2018 16:06:42 UTC+3, Jan Mercl wrote:
>>>
>>> On Thu, Apr 19, 2018 at 2:51 PM Louki Sumirniy 
>>> wrote:
>>>
>>> > Sorry for the self-promotion but it was relevant in that I was working
>>> on how to tidy up the readability of my code and needed multiple returns
>>> and simple untyped tuples were really not nearly as convenient as using a
>>> type struct.
>>>
>>> I have no idea what you mean by 'untyped tuples' because Go does not
>>> have tuples, or at least not as a well defined thing. I can only guess if
>>> you're trying to implement tuples in Go with an array, slice or a struct,
>>> ...? To add to my confusion, Go functions can have as many return values as
>>> one wishes just fine, ie. I obviously do not even understand what problem
>>> you're trying to solve. Sorry.
>>>
>>>
>>> --
>>>
>>> -j
>>>
>> --
> 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.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/8e728e0f-341d-4340-a868-aac028dfc443n%40googlegroups.com
> 
> .
>

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAMV2Rqq%2BDmRDuqcxW-DF%2ByDqTrAu%3DNv51wLWZsx2ERiYEv%3DZ1w%40mail.gmail.com.


Re: [go-nuts] Performance for concurrent requests

2022-12-02 Thread burak serdar
On Fri, Dec 2, 2022 at 8:13 PM Diogo Baeder  wrote:

> Hi guys,
>
> I've been working on some experiments with different web application
> stacks to check their performances under a specific scenario: one in which
> I have to make several concurrent requests and then gather the results
> together (in order) and throw them out as JSON in the response body. (This
> project is only an experiment, but it's informing me for decisions that
> have to be made for a real-world project where we have a similar scenario.)
>
> However, probably due to my ignorance in Go, I cannot make it perform as
> well as I expected - actually the best I'm getting are results that are
> even slower than Python, which was a surprise to me. Here they are:
> https://github.com/yougov/concurrency-tests#edit-13-added-golang-with-gin
>
> So, looking at the code here:
> https://github.com/yougov/concurrency-tests/blob/master/stacks/goapp/main.go
> - does anybody see any problem in the implementation that could be hurting
> performance? I tried using a WaitGroup, tried sharing memory (nasty, I
> know, but just for the sake of experimentation), tried multiple JSON
> codecs, different web frameworks, and nothing worked so far. I have a
> feeling that I'm doing something fundamentally wrong and stupid, and that
> somehow I can make a small change to make the experiment much faster.
>

Have you measured how much time is spent on the http.Get calls? It is
likely that the 50 concurrent http.Get calls is the bottleneck.

Also note that you don't need a channel there. You can simply use a
waitgroup and set the results from inside the goroutine, because each
goroutine knows the index. But that is unlikely to change anything
measurable when compared to the Get calls.



>
> Thanks in advance, I'm sure this will help me learning more about the
> language! :-)
>
> Cheers!
>
> --
> 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.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/42d7d04f-f6d8-4d96-bcdf-bcf32b99a73cn%40googlegroups.com
> 
> .
>

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAMV2Rqp5RVqdBj_6oQgEuZo76eS-n4VQNk%2BBE4ed8%3D7Y2zavCQ%40mail.gmail.com.


Re: [go-nuts] Go Memory Model question

2022-12-02 Thread burak serdar
The way I read the memory model, this program can print 01, 00, and 11, but
not 10. This is because goroutine creation creates a synchronized before
relationship between x=1 and x=0, so even though there is a race, x=0
happens before x=1.

On Fri, Dec 2, 2022 at 6:56 AM のびしー  wrote:

> > I believe your example is basically equivalent to the ones in
> https://go.dev/ref/mem#badsync which also contains an explanation of how
> the memory model implies this
>
> @Wagner
> Thanks for your opinion, I think so too. I was not confident that my
> example is equivalent to https://go.dev/ref/mem#badsync, since my example
> reads from the same variable.
>
>
> > Programs that modify data being simultaneously accessed by multiple
> goroutines must serialize such access.
> @peterGo
>
> I know that my example has data races. But the Go Memory Model guarantees
> a limited number of outcomes for programs with races(unless runtime reports
> the race and terminates). My question is about the limited outcomes.
>
> 2022年12月2日(金) 22:02 Axel Wagner :
>
>> I believe your example is basically equivalent to the ones in
>> https://go.dev/ref/mem#badsync which also contains an explanation of how
>> the memory model implies this (or rather, how it does not imply the
>> opposite).
>>
>> On Fri, Dec 2, 2022, 13:11 のびしー  wrote:
>>
>>> Hello, I have another question regarding the Go Memory Model.
>>>
>>> (1) Can this program print "10", according to the Memory Model?
>>> (2) If that is forbidden, which part of the Go Memory Model excludes
>>> such behavior?
>>>
>>> https://go.dev/play/p/Fn5I0fjSiKj
>>>
>>> ```go
>>> package main
>>>
>>> var x int = 0
>>>
>>> func main() {
>>> go func() {
>>> x = 1
>>> }()
>>> print(x) // first read: 1
>>> print(x) // second read: 0
>>> }
>>> ```
>>>
>>> I draw a picture of the happens-before relation of this program here:
>>>
>>>
>>> https://gist.github.com/nobishino/8150346c30101e2ca409ed83c6c25add?permalink_comment_id=4388680#gistcomment-4388680
>>>
>>> I think the answer to (1) is yes.
>>> Both reads are concurrent with x = 1, so each read can observe both x =
>>> 0 and x = 1.
>>> And there is no constraint between the results of the first read and the
>>> second read.
>>> So the second read can observe x = 0 even if the first read observes x =
>>> 0.
>>>
>>> But I'm not very sure. Is this understanding correct?
>>>
>>> --
>>> 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.
>>> To view this discussion on the web visit
>>> https://groups.google.com/d/msgid/golang-nuts/CAGoET5HyPxEhBETGWNPuYpDgXbm0JM3jeaKFdoQdtc5eGUR0Uw%40mail.gmail.com
>>> 
>>> .
>>>
>> --
> 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.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/CAGoET5Fk6Wwd7JOJOY%3DJVix9NymsP3yJ_P%2BaDPgtPTorL-X_Wg%40mail.gmail.com
> 
> .
>

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAMV2Rqphhx8S0sZDv%3Dj1rskhPvCBstzLo%2BAscz5X7pMnNFzWNQ%40mail.gmail.com.


Re: [go-nuts] How to fix an awful marshal reflection hack

2022-12-01 Thread burak serdar
On Thu, Dec 1, 2022 at 6:39 AM 'Mark' via golang-nuts <
golang-nuts@googlegroups.com> wrote:

> The reason there's no nullable in the real code is that it isn't needed
> there: if the field is to a pointer variable (e.g., *string), then I call
> hack() and that adds the '?' to the string so no need for a nullable bool;
> otherwise for non-pointers it falls through to the normal processing. So
> the complete -- and working -- code is in the repo and go test works. But
> replacing the call to hack() with kind = field.Type().Elem().Kind() breaks
> the tests.
>


Your original code set the nullable to true in the if-block. Do you still
have that piece?


>
> On Thursday, December 1, 2022 at 1:09:50 PM UTC Marvin Renich wrote:
>
>> * 'Mark' via golang-nuts  [221201 05:17]:
>> > I tried that and it works in the playground, and I added more types and
>> it
>> > still works in the playground .
>> > But in my program it still doesn't work:-(
>> > The actual code is here tdb-go <
>> https://github.com/mark-summerfield/tdb-go>
>> > in the file marshal.go from line 133 function marshalTableMetaData().
>> > If you run: go test it all works; but if you replace the call to hack()
>> and
>> > use nullable as you did in the playground, some of the tests fail.
>>
>> You don't show the code that doesn't work (i.e. with nullable). Did you
>> make a typo like you did in your code below?
>>
>> > On Thursday, December 1, 2022 at 9:45:48 AM UTC kortschak wrote:
>> >
>> > > On Thu, 2022-12-01 at 00:33 -0800, 'Mark' via golang-nuts wrote:
>> > > > Thanks. I've now tried that as follows:
>> > > >
>> > > > fmt.Printf("@@: %T %v\n", field, field)
>> > > > kind = field.Type().Elem().Kind()
>> > > > fmt.Printf("##: %T %v\n", field, field)
>>
>> Note that in both Printf statements, you are using field rather than
>> kind. If the two Printf's gave different results, I would consider it a
>> compiler bug (a really egregious one!).
>>
>> > > > In every case the output for kind before and after was identical.
>> > > > (Naturally, I tried without the print statements too.) And, of
>> course
>> > > > the tests fail. So I'm _still_ using the awful hack!
>> > > >
>> > >
>> > > Doesn't this do what you want?
>> > >
>> > > https://go.dev/play/p/7jUw_iW8B_8
>>
>> ...Marvin
>>
>> --
> 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.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/e77369e7-7387-496e-ab02-0f47d5319fd6n%40googlegroups.com
> 
> .
>

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAMV2Rqo%3DoCP0aCzuCf4uso84g%2BKDqexdOyBy%2BPgCXKDin0bWsQ%40mail.gmail.com.


Re: [go-nuts] How to fix an awful marshal reflection hack

2022-11-30 Thread burak serdar
On Wed, Nov 30, 2022 at 10:17 AM 'Mark' via golang-nuts <
golang-nuts@googlegroups.com> wrote:

> Yes, I'd already tried that (that's what I started with) and unfortunately
> it doesn't work.
>

It fails if field.Elem() is nil. Try this:

  kind = field.Type().Elem().Kind()


>
> On Wednesday, November 30, 2022 at 3:37:47 PM UTC bse...@computer.org
> wrote:
>
>> On Wed, Nov 30, 2022 at 5:29 AM 'Mark' via golang-nuts <
>> golan...@googlegroups.com> wrote:
>>
>>> I have this code which works but has a horrible hack:
>>> ...
>>> nullable := false
>>> kind := field.Kind() // field's type is reflect.Value
>>> if kind == reflect.Ptr {
>>>
>>
>> This should work:
>>
>> kind = field.Elem().Kind()
>>
>>
>>
>>
>>> // FIXME How can I improve upon this truly awful hack?
>>> switch field.Type().String() {
>>> case "*int", "*int8", "*uint8", "*int16", "*uint16", "*int32",
>>> "*uint32", "*int64", "*uint64":
>>> kind = reflect.Int
>>> case "*float32", "*float64":
>>> kind = reflect.Float64
>>> }
>>> nullable = true
>>> }
>>> switch kind {
>>> case reflect.Bool:
>>> out.WriteString("bool")
>>> case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32,
>>> reflect.Int64, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32,
>>> reflect.Uint64:
>>> out.WriteString("int")
>>> case reflect.Float32, reflect.Float64:
>>> out.WriteString("real")
>>> ...
>>> if nullable {
>>> out.WriteByte('?')
>>> }
>>> What is the correct way to achieve what I'm aiming for?
>>>
>>> --
>>> 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...@googlegroups.com.
>>> To view this discussion on the web visit
>>> https://groups.google.com/d/msgid/golang-nuts/5ff4b6f6-405c-4ca5-9299-7c15e1d5c424n%40googlegroups.com
>>> 
>>> .
>>>
>> --
> 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.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/c2d154f2-b425-4cc9-a015-af30f4dc9de2n%40googlegroups.com
> 
> .
>

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAMV2RqpNMsPVzpEPM-WFJpcQiOmvruHhQ7h9Ls7B_BpSj219rw%40mail.gmail.com.


Re: [go-nuts] How to fix an awful marshal reflection hack

2022-11-30 Thread burak serdar
On Wed, Nov 30, 2022 at 5:29 AM 'Mark' via golang-nuts <
golang-nuts@googlegroups.com> wrote:

> I have this code which works but has a horrible hack:
> ...
> nullable := false
> kind := field.Kind() // field's type is reflect.Value
> if kind == reflect.Ptr {
>

This should work:

kind = field.Elem().Kind()




> // FIXME How can I improve upon this truly awful hack?
> switch field.Type().String() {
> case "*int", "*int8", "*uint8", "*int16", "*uint16", "*int32",
> "*uint32", "*int64", "*uint64":
> kind = reflect.Int
> case "*float32", "*float64":
> kind = reflect.Float64
> }
> nullable = true
> }
> switch kind {
> case reflect.Bool:
> out.WriteString("bool")
> case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32,
> reflect.Int64, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32,
> reflect.Uint64:
> out.WriteString("int")
> case reflect.Float32, reflect.Float64:
> out.WriteString("real")
> ...
> if nullable {
> out.WriteByte('?')
> }
> What is the correct way to achieve what I'm aiming for?
>
> --
> 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.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/5ff4b6f6-405c-4ca5-9299-7c15e1d5c424n%40googlegroups.com
> 
> .
>

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAMV2RqpQXU%2B3b-v5UwB45initW7Yk99CT8k%3DdK%3DkHW%3DGJC6-aA%40mail.gmail.com.


Re: [go-nuts] Understanding some gotchas with linking slices together via indexing

2022-11-02 Thread burak serdar
On Tue, Nov 1, 2022 at 10:49 PM Brian, son of Bob 
wrote:

> Can anyone explain these gotchas (demo )?
> I've tried reading articles on this [one
> , two
> ]
> but they don't go into enough detail.
>
>
> *Slight gotcha #1: arr[:N] only creates a linked slice when N < len(arr)
> and arr[N:] only creates a linked slice when N>0.*
> E.g. `y` is linked here:
> y := x[:len(x) - 1]
> and here:
> y := x[1:]
>
> But not here
> y := x[:len(x)]
> or here:
> y := x[0:]
>

There is no "linked" slice. A slice is simply three values: pointer to an
array, length, and capacity. If x is a slice, then

y:=x[j:k]

means

y.array = [j]
y.cap=x.cap-j
y.len=k-j

So x[0:] is simply equal to x, and x[1:] is a slice that doesn't have the
first element of x.



>
> Also AFAICT, it's impossible create a link to an empty/nil slice unless
> you use pointers.  And I'm not sure if it's possible to create a linked
> slice that looks at all of the elements in the original without using a
> pointer.
>
> I kind of understand where the Go designers were coming from since it is
> probably more efficient to avoid copying all the time.  Though by that
> logic, I'd still think x[0:] would create a linked slice.
>

This is not about efficiency. An array is a fixed-length data structure,
and if you pass arrays around, you'll get copies of it. A slice is a view
of an array.


>
>
> *Gotcha #2: Appending to a linked slice affects the original slice but not
> the other way around*
> E.g. if `y` is linked to `x` via `y :=  x[1:], then:
> - appending to `y` *might* affect x (see Gotcha #3!)
> - appending to `x` won't affect `y`
> If there is a link, why does it not work both ways?
>

Appending to a slice will append the element to the underlying array if the
slice has capacity. Otherwise, it will allocate a larger array, copy the
old one into the new array, and append to the new array. Because of this,
if you do:

x:=append(y,elem)

If y has enough capacity, then both x and y will point to the same array
that will contain elem. If not, a new array will be allocated, elem will be
appended to it, and x will point to that new array while y will continue to
point to the old array.



>
>
> *Gotcha #3: Using variadic args to append to a linked slice doesn't affect
> the other one*
> If `y` is linked to `x` via `y :=  x[:len(x) - 1], then
> - append(y, 1) affects x
> - append(y, 1, 2) doesn't affect x
> I really don't get this one.
>

This is same as the above case.


>
>
>
> Thanks for any insights!
>
> --
> 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.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/7e2b82cc-f5f4-4fe4-ba73-0ff4dead66f7n%40googlegroups.com
> 
> .
>

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAMV2Rqr8oJUnO7chga32VK83rP3XQduEfTJnm%3DjwZCno1nFdpw%40mail.gmail.com.


Re: [go-nuts] Atomic pointers to arrays and sequenced-before guarantees for array elements

2022-10-30 Thread burak serdar
Based on my reading of the Go memory model, this algorithm sketch is
memory-race free. However, there is a race condition. Here's the reason:

The writer issues a synchronized-write  to array pointer, and another
synchronized-write to the array len. A reader issues a synchronized read.
the corresponding synchronized-write is synchronized-before this read, so
you get the address of an array. Then the reader issues a synchronized-read
of the array len. The synchronized-write for the array len is synchronized
before this read. However, there is no guarantee that the array length you
read is the length corresponding to the array read at the first step. So
this is the race condition, and you can fix it by atomically writing a
struct that has both array pointer and len in it. You have to
synchronized-read the struct, and synchronized-read the array len after
that. There is no need for a synchronized-read of array pointer, provided
you set it in the writer before synchronized-write of the struct pointer.
That is:

var arr atomic.Value
arrPtr:={array:a, len:0}
arr.Store(arrPtr)

For the second part of your question: the go memory model guarantees that
non-synchronized stores before a synchronized write happen before
non-synchronized reads after the synchronized read corresponding to that
synchronized write. This is because:

"The happens before relation is defined as the transitive closure of the
union of the sequenced before and synchronized before relations."

So: if A is synchronized before B, A happens before B. If A is
sequenced-before B, a happens-before B. Thus, if A is sequenced-before B,
and B is synchronized-before C, and C is synchronized-before D, then A
happens before D.

Of course, I'd appreciate it if someone from the Go team could verify this.



On Sun, Oct 30, 2022 at 7:28 AM Konstantin Khomoutov 
wrote:

> Hi!
>
> I would like to receive clarifications, if possible, on Go memory model
> guarantees about non-atomic load and stores when intermixed with atomic
> load
> and stores.
>
> I'm reviewing a piece of code which, simplified, works as follows:
>
>  - There is a single "writer" goroutine which
>
> - Allocates a new array, then uses sync/atomic.StorePointer to save the
>   address of this array someplace.
>
> - Writes the array elements one by one.
>   After writing each element it - again atomically - updates some
> memory
>   location which contains the number of elements currently written in
> the
>   array.
>
> - When the array fills up, it repeats the routine.
>
>A point to note is that the writer writes each element only once,
>and after it's done with the array, it never touches this array again.
>
>  - There are multiple "reader" goroutines each of which consumes the data
>being updated by the "writer" in the following way:
>
> - Use sync/atomic.LoadPointer to obtain the address of the array
> currently
>   in use by the "writer" goroutine.
>
> - Atomically read the current number of elements written in the array
>   by the "writer" goroutine and then read that many elements
>   from the array.
>
> My problem is that I fail to properly apply the text of the Go memory model
> to this case to figure out if there is still a data race on the elements
> of these arrays between the writer and the readers.
>
> The chief problem I have with my reasoning is that I fail to understand
> whether the sequenced-before guarantees provided by atomics apply only to
> the
> atomic operations theirselves - and the memory locations they operate on -
> or
> to the whole sequences of statements executed by goroutines which perform
> the atomic operations.
>
> To simplify, and given the description of the algorithm above, I apply the
> following reasoning.
> A goroutine A performs multiple non-synchronized stores to memory
> locations X,
> Y and Z, and then performs atomic store into memory location M. Naturally,
> all
> store operations done on A up to and including the atomic store to M, are
> naturally sequenced - all the non-synchronized stores has happened before
> the
> atomic store.
> Now a goroutine B uses atomic load of memory location M and then
> performs multiple non-synchronized memory loads from memory locations X, Y
> and Z. These non-synchronized loads are naturally sequenced after the
> atomic
> load from M.
> ("Naturally sequenced" means it's just a regular program flow within a
> goroutine.)
> Given the above, is it guaranteed that A's stores to X, Y and Z are
> synchronized-before B's loads from X, Y and Z?
>
> My gut feeling is that no, Go does not provide this guarantee because of
> two
> reasons:
>
>  - The store performed by A to M does not depend on stores to X, Y and Z,
>and the compiler and/or the hardware are free to reorder them.
>
>  - An atomic store operation is not required to perform a full memory
> fence,
>so even if no reordering has happened on any layer, the goroutine B
>can still obtain stale data 

Re: [go-nuts] Detecting JSON changes

2022-10-10 Thread burak serdar
On Mon, Oct 10, 2022 at 8:50 AM Slawomir Pryczek 
wrote:

> Hi Guys,
> I have 2 json files, A, B. Now i want to detect changes on the root level.
>
> File A: {"a":{"b":1, "c":2}, "x":false,  ... }
> File B: {"a":{"b":1, "c":2}, "x":true,  ... }
>
> I want to be able to see that x is different between A and B and a stayed
> the same. What would be the easiest approach?
>

This is not easy in general. Try using an available package, like:
github.com/wI2L/jsondiff


>
> Thanks
>
> --
> 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.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/7e88ac99-b6ff-49af-95a9-c1c5d7cf9236n%40googlegroups.com
> 
> .
>

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAMV2RqohB%3DrtvNLWwtL0MOrNHf%3Deu0j%2BYm0NsQJi14nfc_W--A%40mail.gmail.com.


Re: [go-nuts] Structures / mutex question

2022-10-09 Thread burak serdar
On Sun, Oct 9, 2022 at 12:44 PM Slawomir Pryczek 
wrote:

> Thanks, very good point about including the structure by-value.
>
> As for using the structure via pointer
>
> > You don't need to rlock the global mutex. Even if another goroutine
> appends to
> > the slice and slice gets reallocated, this code will still be pointing
> to the correct element.
>
> I'd assume I'll still need the global RLock, as len will not be
> synchronized. And moreover if i shrink the array by 1 and then append one
> element, i'll be changing the pointer in-place which could result in some
> pseudo-random memory location being accessed.
>

If you create a goroutine and work with one of the elements of the slice of
pointers, you will not need to rlock the global mutex. If that goroutine
accesses the slice itself, then yes, you'll need it.


>
> niedziela, 9 października 2022 o 18:38:36 UTC+2 bse...@computer.org
> napisał(a):
>
>> On Sun, Oct 9, 2022 at 5:49 AM Slawomir Pryczek 
>> wrote:
>>
>>> Hi Guys,
>>> wanted to see if i making correct assumptions regarding mutexes and
>>> structures
>>>
>>> var globalMutex sync.Mutex{}
>>> type abc struct {
>>> a int
>>> b int
>>> mu sync.Mutex{}
>>> }
>>>
>>> 1. First is self explanatory, array of structures all needs to be
>>> protected by mutex
>>> x := []abc{}
>>> x = append(x, abc{})  // <- This needs to be done inside globalMutex.Lock
>>>
>>
>> There are some things to consider for this usage. You need the global
>> mutex to lock the slice when appending. If append needs to reallocate a new
>> slice, using a *sync.Mutex will work, but any goroutines working on the
>> elements of the slice will be working on stale copies of it. That is, if
>> one goroutine appends to the slice while another is modifying its elements,
>> the modification to the elements may be lost in the new copy of the slice.
>>
>> In short: you should not use struct abc as value if you're ever going to
>> append to the slice.
>>
>> If you are not going to append, then embed *sync.Mutex, otherwise you
>> will be copying the mutex.
>>
>>
>>> x[0].a = 10 // <- This needs to be done inside globalMutex.Lock, as the
>>> array/slice is holding the data (?)
>>>
>>
>> In general, you can lock x[0] for this without locking the global mutex,
>> so other goroutines can update other elements of the array. This, if only
>> you are not appending to the slice.
>>
>>
>>> - Reading x[0].a would require globalMutex.*RLock*
>>>
>>
>> It would require x[0].RLock(), if you are not appending to the slice.
>>
>>
>>>
>>> - Mu is not necessary
>>>
>>
>> You can do this with a global mutex, but that will prevent concurrency
>> for goroutines working on different slice elements.
>>
>>
>>>
>>> 2. Array of pointer to structures
>>> y := []*abc{}
>>> _tmp := {}
>>> y = append(y, _tmp)   <- This needs to be put inside globalMutex.Lock
>>> Mutex
>>>
>>
>> The above is correct.
>>
>>
>>>  y[0].b = 1  <- This can be put inside  globalMutex.RLock and we also
>>> need mu.Lock (as it's sufficient to read abc pointer and the pointer will
>>> never change after the element gets added to the list)
>>>
>>
>> You don't need to rlock the global mutex. Even if another goroutine
>> appends to the slice and slice gets reallocated, this code will still be
>> pointing to the correct element.
>>
>>
>>> - Reading y[0].b would require RLock on both globalMutex and mu
>>>
>>
>> It would require rlock on y[0] only.
>>
>>
>>>
>>> Or maybe it's better to just use generic read-write locks for everything
>>> and don't bother?
>>>
>>> Thanks
>>>
>>>
>>>
>>>
>>>
>>>
>>> --
>>> 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...@googlegroups.com.
>>> To view this discussion on the web visit
>>> https://groups.google.com/d/msgid/golang-nuts/ffc7c10e-ddb9-4bc5-a545-2a1ce7b22bfbn%40googlegroups.com
>>> 
>>> .
>>>
>> --
> 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.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/4c03668d-58b7-4629-8c27-001473005145n%40googlegroups.com
> 
> .
>

-- 
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.
To view this discussion on the web visit 

Re: [go-nuts] Structures / mutex question

2022-10-09 Thread burak serdar
On Sun, Oct 9, 2022 at 5:49 AM Slawomir Pryczek 
wrote:

> Hi Guys,
> wanted to see if i making correct assumptions regarding mutexes and
> structures
>
> var globalMutex sync.Mutex{}
> type abc struct {
> a int
> b int
> mu sync.Mutex{}
> }
>
> 1. First is self explanatory, array of structures all needs to be
> protected by mutex
> x := []abc{}
> x = append(x, abc{})  // <- This needs to be done inside globalMutex.Lock
>

There are some things to consider for this usage. You need the global mutex
to lock the slice when appending. If append needs to reallocate a new
slice, using a *sync.Mutex will work, but any goroutines working on the
elements of the slice will be working on stale copies of it. That is, if
one goroutine appends to the slice while another is modifying its elements,
the modification to the elements may be lost in the new copy of the slice.

In short: you should not use struct abc as value if you're ever going to
append to the slice.

If you are not going to append, then embed *sync.Mutex, otherwise you will
be copying the mutex.


> x[0].a = 10 // <- This needs to be done inside globalMutex.Lock, as the
> array/slice is holding the data (?)
>

In general, you can lock x[0] for this without locking the global mutex, so
other goroutines can update other elements of the array. This, if only you
are not appending to the slice.


> - Reading x[0].a would require globalMutex.*RLock*
>

It would require x[0].RLock(), if you are not appending to the slice.


>
> - Mu is not necessary
>

You can do this with a global mutex, but that will prevent concurrency for
goroutines working on different slice elements.


>
> 2. Array of pointer to structures
> y := []*abc{}
> _tmp := {}
> y = append(y, _tmp)   <- This needs to be put inside globalMutex.Lock Mutex
>

The above is correct.


>  y[0].b = 1  <- This can be put inside  globalMutex.RLock and we also need
> mu.Lock (as it's sufficient to read abc pointer and the pointer will never
> change after the element gets added to the list)
>

You don't need to rlock the global mutex. Even if another goroutine appends
to the slice and slice gets reallocated, this code will still be pointing
to the correct element.


> - Reading y[0].b would require RLock on both globalMutex and mu
>

It would require rlock on y[0] only.


>
> Or maybe it's better to just use generic read-write locks for everything
> and don't bother?
>
> Thanks
>
>
>
>
>
>
> --
> 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.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/ffc7c10e-ddb9-4bc5-a545-2a1ce7b22bfbn%40googlegroups.com
> 
> .
>

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAMV2RqpX7vS3MCWP0mUG%2Bi6UobH-frHnOY4uG8tnnL3C8pBdGg%40mail.gmail.com.


Re: [go-nuts] Shared Goruntime across different microservices written in GO

2022-09-28 Thread burak serdar
On Wed, Sep 28, 2022 at 11:02 PM Roland Müller  wrote:

> Microservices are located in containers and making these services to use a
> common binary would break the basic idea of microservices.
>

Not necessarily. A single binary containing multiple services gives the
flexibility to be run as a monolith, or as a set of microservices where
each instance is only running a subset of the services. It makes deployment
easier.


>
> Every service is a separate unit that shares only the absolute necessary
> things for collaboration with other services rather than its implementation.
>
> BR,
> Roland
>
> Am Mittwoch, 28. September 2022 schrieb Gladiators Squad <
> squadgladiators1...@gmail.com>:
> > Hi Everyone,
> > is there any way to separate go runtime from go binaries?. So that it
> can be shared across different micro services written in go. Instead of
> having separate go run time in each services.
>
>
> > Thanks.
> >
> > --
> > 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.
> > To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/736c26c4-643b-4f5c-836a-e8d9878a473bn%40googlegroups.com
> .
> >
>
> --
> 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.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/CA%2B8p0G1a5agnb2QPWRPZnoWr29MZUmE9R%3Djohikqe0%3DcJ9U73w%40mail.gmail.com
> 
> .
>

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAMV2RqosE_ezxbe4DGgXYNVPS6v4Xibc3H56dx4Mn-ZrARqMUQ%40mail.gmail.com.


Re: [go-nuts] understanding interface conversions

2022-09-22 Thread burak serdar
On Thu, Sep 22, 2022 at 7:01 PM Robert Engels  wrote:

> Exactly. The world figured out long ago that OO and it’s principles are a
> better way to go. The fact that Go is not OO doesn’t make it bad or not
> useful - but the proponents of that state doesn’t make it better.
>

I, for one, disagree with the assessment that OO principles are the better
way of doing things. If good OO is hard to do, which I agree with, then
most OO programs out there are wrong. I think OO with very limited
inheritance and a more pragmatic approach to encapsulation is much easier
to get right, which is, I believe, something Go got right.


>
> On Sep 22, 2022, at 7:58 PM, burak serdar  wrote:
>
> 
>
>
> On Thu, Sep 22, 2022 at 6:30 PM Robert Engels 
> wrote:
>
>> I would like to understand the reason to type assert but not cast? That
>> is an OO design flaw.
>>
>
> You can only type-assert an interface. With type-assertion, you are either
> checking if the underlying value of an interface is a specific type, or if
> the value underlying the interface also implements a different set of
> methods.
>
> And Go isn't OO.
>
>
>>
>> On Sep 22, 2022, at 7:24 PM, burak serdar  wrote:
>>
>> 
>>
>>
>> On Thu, Sep 22, 2022 at 6:08 PM Robert Engels 
>> wrote:
>>
>>> 100% true. The difficulty when examining a “large” system is that it
>>> becomes very difficult to understand the relationships. Documentation can
>>> help but it is not a great substitute for automated tools.
>>>
>>> In Java - actually all of OO - type casting is severely frowned upon -
>>> but it seems a lot of Go code does it liberally.
>>>
>>> If I designed a language today I would prohibit any type casts.  It is a
>>> huge problem and points to insufficient design skills.
>>
>>
>> Type-assertion is not exactly type-casting, though. And Go isn't exactly
>> OO.
>>
>>
>>>
>>>
>>> > On Sep 22, 2022, at 6:57 PM, Ian Davis  wrote:
>>> >
>>> > On Thu, 22 Sep 2022, at 11:27 PM, Rory Campbell-Lange wrote:
>>> >
>>> > I just wanted to respond to this part:
>>> >
>>> >> I suppose my question is (and forgive me if this is a terrifically
>>> >> naive), how can one negotiate the go landscape of commonly used
>>> modules
>>> >> to re-utilise, where possible, a more commonly named interface
>>> >> implementing "Speak()" or convertible to provide "Speak()"?
>>> >>
>>> >
>>> > Generally, when writing Go, the consumer of the object defines the
>>> interface it requires. So rather than you looking for interfaces that might
>>> exist in the wild, it's better to focus on your application and its needs.
>>> If you have a component that uses the Speak method on objects then define
>>> that as an interface that your component can accept. Any other user of your
>>> component can see that interface is needed and provide a suitable object
>>> that implements it or create a shim to adapt one.
>>> >
>>> >
>>> > --
>>> > 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.
>>> > To view this discussion on the web visit
>>> https://groups.google.com/d/msgid/golang-nuts/1fb8a3c4-b135-4ab1-b969-d6f4c239b7d9%40www.fastmail.com
>>> .
>>>
>>> --
>>> 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.
>>> To view this discussion on the web visit
>>> https://groups.google.com/d/msgid/golang-nuts/C0D7D21F-AC72-40E3-9DB9-A8678886CDF3%40ix.netcom.com
>>> .
>>>
>> --
>> 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.
>> To view this discussion on the web visit
>> https://groups.google.com/d/msgid/golang-nuts/CAMV2RqooGmOaXCGmriJ%2BDryYSSLNRmcrc9hfSTcWG-qPGAonxw%40mail.gmail.com
>> <https://groups.google.com/d/msgid/golang-nuts/CAMV2RqooGmOaXCGmriJ%2BDryYSSLNRmcrc9hfSTcWG-qPGAonxw%40mail.g

Re: [go-nuts] understanding interface conversions

2022-09-22 Thread burak serdar
On Thu, Sep 22, 2022 at 6:30 PM Robert Engels  wrote:

> I would like to understand the reason to type assert but not cast? That is
> an OO design flaw.
>

You can only type-assert an interface. With type-assertion, you are either
checking if the underlying value of an interface is a specific type, or if
the value underlying the interface also implements a different set of
methods.

And Go isn't OO.


>
> On Sep 22, 2022, at 7:24 PM, burak serdar  wrote:
>
> 
>
>
> On Thu, Sep 22, 2022 at 6:08 PM Robert Engels 
> wrote:
>
>> 100% true. The difficulty when examining a “large” system is that it
>> becomes very difficult to understand the relationships. Documentation can
>> help but it is not a great substitute for automated tools.
>>
>> In Java - actually all of OO - type casting is severely frowned upon -
>> but it seems a lot of Go code does it liberally.
>>
>> If I designed a language today I would prohibit any type casts.  It is a
>> huge problem and points to insufficient design skills.
>
>
> Type-assertion is not exactly type-casting, though. And Go isn't exactly
> OO.
>
>
>>
>>
>> > On Sep 22, 2022, at 6:57 PM, Ian Davis  wrote:
>> >
>> > On Thu, 22 Sep 2022, at 11:27 PM, Rory Campbell-Lange wrote:
>> >
>> > I just wanted to respond to this part:
>> >
>> >> I suppose my question is (and forgive me if this is a terrifically
>> >> naive), how can one negotiate the go landscape of commonly used
>> modules
>> >> to re-utilise, where possible, a more commonly named interface
>> >> implementing "Speak()" or convertible to provide "Speak()"?
>> >>
>> >
>> > Generally, when writing Go, the consumer of the object defines the
>> interface it requires. So rather than you looking for interfaces that might
>> exist in the wild, it's better to focus on your application and its needs.
>> If you have a component that uses the Speak method on objects then define
>> that as an interface that your component can accept. Any other user of your
>> component can see that interface is needed and provide a suitable object
>> that implements it or create a shim to adapt one.
>> >
>> >
>> > --
>> > 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.
>> > To view this discussion on the web visit
>> https://groups.google.com/d/msgid/golang-nuts/1fb8a3c4-b135-4ab1-b969-d6f4c239b7d9%40www.fastmail.com
>> .
>>
>> --
>> 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.
>> To view this discussion on the web visit
>> https://groups.google.com/d/msgid/golang-nuts/C0D7D21F-AC72-40E3-9DB9-A8678886CDF3%40ix.netcom.com
>> .
>>
> --
> 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.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/CAMV2RqooGmOaXCGmriJ%2BDryYSSLNRmcrc9hfSTcWG-qPGAonxw%40mail.gmail.com
> <https://groups.google.com/d/msgid/golang-nuts/CAMV2RqooGmOaXCGmriJ%2BDryYSSLNRmcrc9hfSTcWG-qPGAonxw%40mail.gmail.com?utm_medium=email_source=footer>
> .
>
>

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAMV2RqrouRZrUMPxwu16xCjS_L_0SQYgS8AaWJKEZ6JWwpFGUg%40mail.gmail.com.


Re: [go-nuts] understanding interface conversions

2022-09-22 Thread burak serdar
On Thu, Sep 22, 2022 at 6:08 PM Robert Engels  wrote:

> 100% true. The difficulty when examining a “large” system is that it
> becomes very difficult to understand the relationships. Documentation can
> help but it is not a great substitute for automated tools.
>
> In Java - actually all of OO - type casting is severely frowned upon - but
> it seems a lot of Go code does it liberally.
>
> If I designed a language today I would prohibit any type casts.  It is a
> huge problem and points to insufficient design skills.


Type-assertion is not exactly type-casting, though. And Go isn't exactly
OO.


>
>
> > On Sep 22, 2022, at 6:57 PM, Ian Davis  wrote:
> >
> > On Thu, 22 Sep 2022, at 11:27 PM, Rory Campbell-Lange wrote:
> >
> > I just wanted to respond to this part:
> >
> >> I suppose my question is (and forgive me if this is a terrifically
> >> naive), how can one negotiate the go landscape of commonly used modules
> >> to re-utilise, where possible, a more commonly named interface
> >> implementing "Speak()" or convertible to provide "Speak()"?
> >>
> >
> > Generally, when writing Go, the consumer of the object defines the
> interface it requires. So rather than you looking for interfaces that might
> exist in the wild, it's better to focus on your application and its needs.
> If you have a component that uses the Speak method on objects then define
> that as an interface that your component can accept. Any other user of your
> component can see that interface is needed and provide a suitable object
> that implements it or create a shim to adapt one.
> >
> >
> > --
> > 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.
> > To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/1fb8a3c4-b135-4ab1-b969-d6f4c239b7d9%40www.fastmail.com
> .
>
> --
> 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.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/C0D7D21F-AC72-40E3-9DB9-A8678886CDF3%40ix.netcom.com
> .
>

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAMV2RqooGmOaXCGmriJ%2BDryYSSLNRmcrc9hfSTcWG-qPGAonxw%40mail.gmail.com.


Re: [go-nuts] understanding interface conversions

2022-09-22 Thread burak serdar
On Thu, Sep 22, 2022 at 4:27 PM Rory Campbell-Lange 
wrote:

> This email follows my email yesterday "cannot convert fs.FS zip file to
> io.ReadSeeker (missing Seek)". Thanks very much to those who replied and
> provided solutions.
>
> Following that, I'm interested to learn how people negotiate interface
> interchangeability in their programmes as my query above showed a basic
> misunderstanding of how that operates and how to approach the topic in
> general.
>
> At a basic level my assumption that an fs.File would be "file like" and
> therefore act like a file was upended by the need for a PDF importer
> library to require an *io.ReadSeeker. This assumption broke for an fs.File
> from a zip archive since that doesn't support seeking. That is logical but
> was hard to find out. Although I can easily jump to methods and see related
> docs using vim-go, I still find interface interpolation (if that is a
> reasonable term) difficult to understand.
>
> At a more abstract level, the concept of interfaces was a key attraction
> to me of go, next to goroutines. They not only promise loose coupling of
> independently developed pieces, but also allow functionality to be easily
> re-used through types sharing method signatures, not to mention interface
> embedding. But, perhaps because of my background in python and SQL, I find
> this abstraction tricky to grasp. It's difficult to know, offhand, what
> interfaces are best to implement in a particular case. That difficulty is
> compounded when one interface can be interpolated (in some cases only,
> depending on the underlying concrete type) to another interface. The set of
> possible interface "contracts" offered to an fs.File, for example, could
> approach a very large number (ignoring interface{}) depending on the
> underlying concrete type.
>
> The https://jordanorelli.com/post/32665860244/how-to-use-interfaces-in-go
> article (pointed to by "Go by Example") by Jordan Orelli uses the example
> of "...the Animal type will be an interface, and we’ll define an Animal as
> being anything that can speak". He writes:
>

I think one of the problems in this particular example is that it is for
some reason easy for people to accept Animal type to be something that can
speak. I can see that it is simply an example to show the mechanics of
interfaces, but it also sets the expectation that the interface name means
more than what it actually is: in Go, an interface is simply a method set.
This is a difficult concept for people coming from other languages. So you
can have:

if speaker, yes:=someInterfaceValue.(interface{Speak() string}); yes {
spearer.Speak()
}

without having a named interface at all.

That is one of the properties of duck-typing I enjoy, especially after
working with Java for many years. In Java, an interface is a contract. In
Go, an interface is just a method set, which can be used as a contract.


> We start by defining our Animal interface:
>
> type Animal interface {
> Speak() string
> }
>
> I suppose my question is (and forgive me if this is a terrifically naive),
> how can one negotiate the go landscape of commonly used modules to
> re-utilise, where possible, a more commonly named interface implementing
> "Speak()" or convertible to provide "Speak()"?
>
> Finally I was surprised that I did not get a compile-time error when
> trying to convert an fs.File to a io.ReadSeeker for the (possible) case
> when an underlying concrete type did not support Seek.
>
> Many thanks,
> Rory
>
> --
> 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.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/YyzhV8S8WgH7mrJK%40campbell-lange.net
> .
>

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAMV2RqoyphWeq63YBx%2B%2BYr%2B7Jn1K3zUc5n3P3%2Ba742DX7D39jQ%40mail.gmail.com.


Re: [go-nuts] Re: Error-checking with errors.As() is brittle with regards to plain vs pointer types

2022-09-22 Thread burak serdar
That is not always true. I saw code that looks like this a few days ago:
what the author was trying to do was to handle a specific type of error
differently, and pass it along if the error is some other type:

type CustomError struct{}

func (e CustomError) Error() string { return "error" }

func g() error {...}

func f() (error, bool) {
  err, ok := g().(CustomError)
  if ok {
return err, true
   }
  return err, false
}

https://go.dev/play/p/YoIjKtoynuI



On Thu, Sep 22, 2022 at 11:38 AM Martin Schnabel  wrote:

> Sorry, to barge in but this specific thing is not really an issue as
> long as you use the error type as result type. because any value with an
> Error() string method does implement the error interface. and even an
> empty struct or a nil pointer to a applicable type will do just fine an
> matches err != nil
>
> have fun
>
> On 9/22/22 17:29, Tamás Gulácsi wrote:
> > plain struct error is brittle in other ways, too: you can shoot yourself
> > on foot with "err != nil" check.
> > So: error should be a pointer type.
> >
> > cpu...@gmail.com a következőt írta (2022. szeptember 21., szerda,
> > 21:26:31 UTC+2):
> >
> > Consider https://go.dev/play/p/jgPMwLRRsqe
> > :
> >
> > errors.As(err, ) will not match if error is of pointer
> > type. As a result, a library consumer needs to understand if a
> > library returns Error or *Error. However, that is not part of the
> > API spec as both returns would satisfy error if Error() is
> > implemented on the plain type.
> >
> > A potential workaround would be using Error.As(any) to match
> > plain/pointer type as part of the library. However, it seems
> > counterintuitive having to do so if errors.As() doesn't by default.
> >
> > Would it make sense (and I would like to propose) to expand
> > errors.As() to match plain receiver types even when err is a pointer
> > to the same underlying plain type.
> >
> > What do you think?
> >
> > Cheers,
> > Andi
> >
> > --
> > 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
> > .
> > To view this discussion on the web visit
> >
> https://groups.google.com/d/msgid/golang-nuts/b9d94e2f-860e-44eb-9f9e-efcd0a82b7d2n%40googlegroups.com
> > <
> https://groups.google.com/d/msgid/golang-nuts/b9d94e2f-860e-44eb-9f9e-efcd0a82b7d2n%40googlegroups.com?utm_medium=email_source=footer
> >.
>
> --
> 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.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/84507652-eabc-c149-bdfb-8032657536ed%40mb0.org
> .
>

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAMV2Rqp0wPvgMoH8ZnmbGEQf5PGzO2ySy1wG9pXkh3Jbkyii6w%40mail.gmail.com.


[go-nuts] Labeled property graphs and embedded openCypher library

2022-09-20 Thread burak serdar
I would like to announce two open-source Go libraries we have been working
on:

Labeled Property Graphs: https://github.com/cloudprivacylabs/lpg

This library supports openCypher (Neo4j) style of labeled property graphs
in memory. That is:
  * Nodes have a set of labels, and a set of key-values,
  * Edges are directed, each edge has a label and a set of key-values.
It also includes a JSON serialization for labeled property graphs.

The API is stable, and it performs well.

Embedded openCypher implementation:
https://github.com/cloudprivacylabs/opencypher

openCypher is a query language for labeled property graphs (
https://opencypher.org/). This library provides support for the openCypher
language. It allows running statements to create, modify, and query graphs
in memory.

This library is still being developed, but functional (with the exception
of multi-part queries and some other features that will be added in time).

Both libraries are part of a larger semantic interoperability framework,
the Layered Schema Architecture. They are being used in a federally funded
data harmonization project for health data:
https://github.com/cloudprivacylabs/leap-sh

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAMV2Rqr8zR6OD6wHDyCLpP3q_md7hD3dve1NSsobebQm9V4rpA%40mail.gmail.com.


Re: [go-nuts] Race detector question

2022-09-15 Thread burak serdar
On Thu, Sep 15, 2022 at 9:21 AM Thomas Bushnell BSG 
wrote:

> On Thu, Sep 15, 2022 at 11:19 AM burak serdar 
> wrote:
>
>> On Thu, Sep 15, 2022 at 9:11 AM Thomas Bushnell BSG 
>> wrote:
>>
>>> I cannot speak to "other accepted concurrency designs" here. Simply that
>>> Go does not guarantee the operation you want it to, the memory model does
>>> not actually imply that it does, and the last sentence of the memory model
>>> is the most important one here: don't be clever.
>>>
>>
>> I believe that's what we are discussing here. The way I read it, the
>> memory model does imply that a non-synchronized operation x sequenced
>> before an operation y  that happened before z implies that all operations
>> sequenced after z happens after x.
>>
>
> You may be misreading requirement one as implying that no reordering
> within a goroutine is ever permitted. It does not say that. What it says is
> that, within one goroutine, any reordering is permissible provided the
> actual value read and written by that goroutine are the correct ones.
>

I believe what the memory model implies is that no reordering is permitted
to cross a memory barrier. An atomic operation has a memory barrier.


>
> Thomas
>
>

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAMV2RqoZ2J8hHY6mD_rNdJu7W4p0osW0E%2BUxx8pYnh815%3DFmTw%40mail.gmail.com.


Re: [go-nuts] Race detector question

2022-09-15 Thread burak serdar
On Thu, Sep 15, 2022 at 9:19 AM Thomas Bushnell BSG 
wrote:

> On Thu, Sep 15, 2022 at 11:16 AM robert engels 
> wrote:
>
>> This is simply incorrect. The ‘issue’ about clarifying the memory has
>> been about “happens before” since the beginning. The model was clarified.
>> The race detector cannot cope with it.
>>
>> I don’t think you fully understand what “happens before” means. Please
>> read the article I referred to.
>>
>
> The article you referred to is a casual description of a different
> language, neither the official GCC documentation itself nor the C++
> standard. I'm not making representations about the semantics of C++ in any
> way.
>
> I understand the model, the race-detector is implementing the model, and
> the model is as explicit as it can be that atomics create a "happens
> before" relationship only when both variables concerned are atomic. I don't
> see any reason to continue this conversation, so I'll leave off here.
>

The memory model doesn't stop there though. In particular, this section:
https://go.dev/ref/mem#model

>
> Thomas
>
>

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAMV2RqocgnUmbOqw0t5pELju%3DCe7wva%2BGjbbgmnPvQwmuSvyXA%40mail.gmail.com.


Re: [go-nuts] Race detector question

2022-09-15 Thread burak serdar
On Thu, Sep 15, 2022 at 9:11 AM Thomas Bushnell BSG 
wrote:

> I cannot speak to "other accepted concurrency designs" here. Simply that
> Go does not guarantee the operation you want it to, the memory model does
> not actually imply that it does, and the last sentence of the memory model
> is the most important one here: don't be clever.
>

I believe that's what we are discussing here. The way I read it, the memory
model does imply that a non-synchronized operation x sequenced before an
operation y  that happened before z implies that all operations sequenced
after z happens after x.


>
> On Thu, Sep 15, 2022 at 11:08 AM robert engels 
> wrote:
>
>> This is not what “happens before” means - at least not in any other
>> accepted concurrency designs.
>>
>> See my second example as to why.
>>
>> On Sep 15, 2022, at 10:02 AM, Thomas Bushnell BSG 
>> wrote:
>>
>> Happens before works just fine with atomics. But in your example, x is
>> not an atomic.
>>
>> Thomas
>>
>> On Thu, Sep 15, 2022 at 10:51 AM robert engels 
>> wrote:
>>
>>> Yea, the race detector is broken… it fails on the following code:
>>>
>>> package main
>>>
>>> import (
>>>"sync"
>>>"sync/atomic"
>>> )
>>>
>>> func main() {
>>>
>>>var x int32
>>>var y int32
>>>
>>>w := sync.WaitGroup{}
>>>w.Add(2)
>>>
>>>go func() {
>>>   for {
>>>  x = 1
>>>  atomic.StoreInt32(, 1)
>>>   }
>>>   w.Done()
>>>}()
>>>go func() {
>>>   for {
>>>  if atomic.LoadInt32() == 1 {
>>> if x != 1 {
>>>panic("should not happen")
>>> }
>>>  }
>>>   }
>>>   w.Done()
>>>}()
>>>w.Wait()
>>>
>>> }
>>>
>>> The above code does not have a race, or Go doesn’t have “happens before”
>>> semantics with its atomics.
>>>
>>>
>>> On Sep 15, 2022, at 9:41 AM, Robert Engels 
>>> wrote:
>>>
>>> To clarify, if the atomic read of Y sees the updated Y then a subsequent
>>> non-atomic read of X must see the updated X. This is a happens before
>>> relationship.
>>>
>>> The question was if the race detector understands this - I know - why
>>> not try it out…
>>>
>>> On Sep 15, 2022, at 9:39 AM, Robert Engels 
>>> wrote:
>>>
>>> 
>>> I think it needs to see the updated X - which agrees with burak.
>>>
>>> Reading Z is race.
>>>
>>> On Sep 15, 2022, at 9:24 AM, burak serdar  wrote:
>>>
>>> 
>>>
>>> On Thu, Sep 15, 2022 at 8:03 AM 'Thomas Bushnell BSG' via golang-nuts <
>>> golang-nuts@googlegroups.com> wrote:
>>>
>>>> You cannot make that assumption. It's not about what the race detector
>>>> can detect.
>>>>
>>>> Goroutine one:
>>>>   Writes non-synchronized X
>>>>   Writes atomic Y
>>>>   Writes non-synchronized Z with the value of X+Y
>>>>
>>>> Goroutine two
>>>>   Reads atomic Y and sees the new value
>>>>
>>>
>>> The way I read the Go memory model, if Goroutine two sees the new value
>>> of Y, non-synchronizes writes to X by Goroutine 2 happened before Y, and
>>> thus, anything that happens after Y. This is based on:
>>>
>>> "If a synchronizing read-like memory operation r observes a
>>> synchronizing write-like memory operation w (that is, if W(r) = w), then w
>>> is synchronized before r."
>>>
>>> And:
>>>
>>> "The happens before relation is defined as the transitive closure of the
>>> union of the sequenced before and synchronized before relations."
>>>
>>> Because:
>>>   * The writes to non-synchronized X are sequenced before the atomic
>>> write to Y
>>>   * The atomic read Y happened after atomic write to Y if it sees the
>>> new value
>>>   * non-synchronized reads from X happen after that
>>>
>>> So that should not be a race.
>>>
>>> Am I reading this correctly?
>>>
>>>
>>>
>>>>
>>>> Can goroutine two now read non-synchronized X and assume it sees the
>>>> new value

Re: [go-nuts] Race detector question

2022-09-15 Thread burak serdar
On Thu, Sep 15, 2022 at 8:03 AM 'Thomas Bushnell BSG' via golang-nuts <
golang-nuts@googlegroups.com> wrote:

> You cannot make that assumption. It's not about what the race detector can
> detect.
>
> Goroutine one:
>   Writes non-synchronized X
>   Writes atomic Y
>   Writes non-synchronized Z with the value of X+Y
>
> Goroutine two
>   Reads atomic Y and sees the new value
>

The way I read the Go memory model, if Goroutine two sees the new value of
Y, non-synchronizes writes to X by Goroutine 2 happened before Y, and thus,
anything that happens after Y. This is based on:

"If a synchronizing read-like memory operation r observes a synchronizing
write-like memory operation w (that is, if W(r) = w), then w is
synchronized before r."

And:

"The happens before relation is defined as the transitive closure of the
union of the sequenced before and synchronized before relations."

Because:
  * The writes to non-synchronized X are sequenced before the atomic write
to Y
  * The atomic read Y happened after atomic write to Y if it sees the new
value
  * non-synchronized reads from X happen after that

So that should not be a race.

Am I reading this correctly?



>
> Can goroutine two now read non-synchronized X and assume it sees the new
> value written by one? No, it cannot. There is no "happens before" relation
> connecting the two writes performed by goroutine one. Requirement one does
> not establish such a relationship. It only establishes that Z will be
> written with the correct sum of X and Y. There must be *some *sequential
> order within the context of goroutine one that sees the correct value; the
> compiler is free to swap the order of the writes X and Y.
>
> If X were an atomic, then Requirement two would come into play. But
> because X and Z are not atomic, they play no role in Requirement two. Note
> that the description of atomic in the model says that writes to *atomic 
> *values
> have the property you want. And since there is no before relationship
> established by any of the following text, this synchronization cannot be
> relied on.
>
> Now you're asking whether the race detector ensures the synchronization
> property you're suggesting? The race detector doesn't ensure any
> synchronization properties; it detects bugs.
>
> I think it is capable of detecting this one.
>
> Thomas
>
>
>
>
> On Wed, Sep 14, 2022 at 11:01 PM robert engels 
> wrote:
>
>> Hi,
>>
>> I am working on a new project, and the race detector is reporting a race.
>>
>> Essentially, the code is
>>
>> var S []int
>>
>> several go routines write new S values using a mutex
>>
>> go routine Y reads S without grabbing a lock (it reads it initially under
>> lock)
>>
>> The semantics are such that Y can operate successfully with any valid
>> value of S (e.g. could be stale). (essentially S is used with copy on write
>> semantics)
>>
>> The race detector reports this as a race.
>>
>> I could change all reads of Y to use an atomic load, but I don’t think it
>> should be necessary.
>>
>> Is there any way to perform “lazy loads” in Go?
>>
>> And a follow-up:
>>
>> Is the race detector smart enough so that if a routines write to several
>> vars (v1…n)  and performs an atomic store to X, and another routine
>> atomically reads X it can also non atomically read v1…n and it will see the
>> stored values?
>>
>> This has been the long standing issue with the Go memory model and
>> “happens before”… but how does the race detector report this?
>>
>> (Some background, the library functions fine under heavy concurrent
>> stress tests - but the race detector says it is broken).
>>
>>
>>
>>
>> --
>> 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.
>> To view this discussion on the web visit
>> https://groups.google.com/d/msgid/golang-nuts/8EC74417-C4AD-4490-9231-6E869EE72D93%40ix.netcom.com
>> .
>>
> --
> 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.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/CA%2BYjuxtd%2BpaU_BNxXDrMAN9v71r-Qhm9LcXcN2fTtjD_6oWw-Q%40mail.gmail.com
> 
> .
>

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAMV2Rqr4vggPOWjiQg6qN0tJjhhXncKHLMCDwkqZTHBJJ7%3Dmug%40mail.gmail.com.


Re: [go-nuts] Assigning struct values

2022-09-07 Thread burak serdar
On Wed, Sep 7, 2022 at 12:28 PM Mustafa Durukan 
wrote:

>
>
> *fakeObject := tt.Object.(TypeOfStruct)object := Object.(TypeOfStruct)*


If you can include the definitions of tt, explain what you want to do, and
what you mean by "didn't  work", someone may be able to answer this
question. Without those, it is not clear what you are trying to achieve.


>
>
> *fakeObject.Field = object.FieldfakeObject.Field2 = object.Field2*
>
> I have case like that.
> I want to assign sme object values to tt.Object but when i try to assign
> it assings to fakeObject i mean copy of tt.Object so I cant assign
>
> I tried these assigns
>
> *tt.Object.(TypeOfStruct).Field =
> object.Fieldtt.Object.(TypeOfStruct).Field2 = object.Field2*
>
> or
>
>
>
> *tt.Object:= tt.Object.(TypeOfStruct)tt.Object.Field =
> object.Fieldtt.Object.Field2 = object.Field2*
>
> But both of them didnt work
> How should i achieve it?
> btw tt.Object and Object are interface{} of course
>
> --
> 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.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/d1539b71-8344-4199-bb7c-ef95b3cf2badn%40googlegroups.com
> 
> .
>

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAMV2RqqvuMR1ftKz1yE%2BdE9WJ5g-512gc5sVRew9gkX0K_ri%2Bg%40mail.gmail.com.


Re: [go-nuts] Struct with Interfaces fields as key in maps

2022-08-31 Thread burak serdar
On Wed, Aug 31, 2022 at 7:28 AM antonio.o...@gmail.com <
antonio.ojea.gar...@gmail.com> wrote:

> Hi,
>
> Based on the documentation:
>
> "The map key can be any type that is comparable."
> "Struct values are comparable if all their fields are comparable. Two
> struct values are equal if their corresponding non-blank fields are equal."
> "Interface values are comparable. Two interface values are equal if they
> have identical dynamic types and equal dynamic values or if both have value
> nil."
>
> My understanding is that I can use an structure like this as a key for a
> map
>
> type dialer interface {
> dial()
> }
>
> type key struct {
> id string
> number int
> dialer  dialer
> }
>
> It also seems to work fine https://go.dev/play/p/hKQfx-JH5WP
>

This works in general, but your example is flawed. In your example, you have

f1 := {}
f2 := {}

and then use f1 anf f2 as keys. These are pointers to structs, so the
comparison will be pointer comparison, not field-by-field comparison.

If you do:

f1 := fakedialer{}
f2 := fakedialer2{}

and replace the pointer receivers with value receivers, and then use these
as map keys, it will work. But this time, if you pass a struct that cannot
be used as a key, you'll receive a runtime panic instead of a compile error.


> But I'm wondering if I'm missing something or are there some corner cases
> I should take into account before doing this ...  or if this is not
> recommended at all
>
> Thanks,
>
> --
> 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.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/97b7368e-d276-40ab-afa3-f8a7868fd9ean%40googlegroups.com
> 
> .
>

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAMV2Rqq4qLv6eaBcRJ7r%3DOn3D%2B9YxLeaVSnfme-F187md%3DR7LA%40mail.gmail.com.


Re: [go-nuts] Pipelining with Go and Generics

2022-08-11 Thread burak serdar
On Thu, Aug 11, 2022 at 2:37 PM Robert Engels  wrote:

> I don’t think that is relevant. It is very difficult to do chaining with
> Go’s error model. You can pass a shared context to every node and store the
> error in the context and protect against concurrent access. It’s doable but
> not easy.
>
> Map/reduce and most functional patterns are easily represented using
> chains.
>
> But like I said, I would use panic/recover in the framework to make it
> easier.
>

I recently worked on a concurrent data pipeline to process a stream of data
packages. Error handling was done with an error channel. Each stage of the
pipeline had to prepare an error message capturing the current context,
cause of the error, etc., and then write to the error channel before
processing the next entry.


>
>
>
> On Aug 11, 2022, at 3:27 PM, Jan Mercl <0xj...@gmail.com> wrote:
>
> 
>
>
> On Thu, Aug 11, 2022, 21:36 Robert Engels  wrote:
>
>> I’d say it certainly highlights a problem with Go’s error model.
>> Exceptions would fit nicely here - instead it seems you needed to ignore
>> all error handling - because chaining is impossible with error returns.
>>
>
> It's okay if someone prefers the way Java does things, but the best thing
> about Go is IMHO that it is not Java. And I still hope it stays away from
> becoming Java as long as possible.
>
>
>> A streams api with panic/recover is needed.
>>
>> On Aug 11, 2022, at 12:55 PM, K. Alex Mills 
>> wrote:
>>
>> 
>> Hello Gophers,
>>
>> I recently had an opportunity to try out Go generics on a small
>> pipelines package
>> , along with
>> some of my coworkers.
>>
>> The overall goal of this package is to provide helpers for separating
>> concurrency from the core logic of the computation. The result was intended
>> for I/O bound computations, and so it's likely inappropriate for managing
>> short-lived goroutines. It takes a functional programming approach,
>> providing helpers with familiar names seen in other APIs like Map, FlatMap,
>> OptionMap, etc. One feature which I am particularly happy with is that
>> concurrency concerns like worker pool size and channel buffers are
>> configurable with minimal disruption to the rest of the code.
>>
>> Take a look at the library
>>  and its
>> accompanying blog post . I'm
>> open to any of your thoughts, suggestions, and issue reports.
>>
>> Sincerely,
>>
>> K. Alex Mills
>>
>> --
>> 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.
>> To view this discussion on the web visit
>> https://groups.google.com/d/msgid/golang-nuts/CALJzkY_zASs-YOukv6ciSO45b93jz39DmjAWA915kfBuwimkgQ%40mail.gmail.com
>> 
>> .
>>
>> --
>> 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.
>> To view this discussion on the web visit
>> https://groups.google.com/d/msgid/golang-nuts/6954C3FB-0E78-4922-8889-90FA58BA3F16%40ix.netcom.com
>> 
>> .
>>
> --
> 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.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/CAA40n-WfWSMbV8p79xXGbS2%2BQ0M8pQfUPupqGnzGAdbo%2BTx0JA%40mail.gmail.com
> 
> .
>
> --
> 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.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/04C53843-FD4F-4701-A546-33DBCB9C259B%40ix.netcom.com
> 
> .
>

-- 
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.
To view this discussion on the web visit 

Re: [go-nuts] Preemptive interfaces in Go

2022-08-09 Thread burak serdar
On Tue, Aug 9, 2022 at 1:52 PM Tim Peoples  wrote:

> Yeah, I'm with Burak on this one. The interface usage you're describing
> Henry is exactly the kind of thing I'm talking about.  While on the surface
> it may seem advantageous -- in fact, I also tried writing Go that way when
> I first started -- my *readability* reviewers at Google did well to
> enlighten me about the many problems this can cause with Go -- some of
> which rog was kind enough to enumerate.


I think "readability" is not the right metric to use here. "Code
comprehension" (comprehensibility?) should be the right metric. Readability
does not always imply it can be easily comprehended. Java is readable, but
not necessarily comprehensible. I argue that Go code is more comprehensible
than code written in most other languages, because you can understand all
the implications of the code using mostly "local knowledge", that is,
knowledge you can gain by reading pieces of code "close" to the point of
interest. Wherever you have interfaces, you need non-local knowledge to
understand what's going on.



>
> Also, since originally posting this yesterday, I've come to learn that my
> new shop is not only utilizing preemptive interface definitions but also a
> complete dependency injection framework and rather strict adherence to *Clean
> Architecture*™
> 
> -- (likely from the scripts in this repo
> ) which goes a long way
> towards explaining why so much of the code looks like Java written in Go
> syntax.
>
> On Tuesday, August 9, 2022 at 8:33:07 AM UTC-7 bse...@computer.org wrote:
>
>> On Mon, Aug 8, 2022 at 11:27 PM Henry  wrote:
>>
>>> I am sure that many of us have been on that journey. After using Go for
>>> some time, we discover some practices that are not necessarily in agreement
>>> with the existing "adages" but effectively solve our problems.
>>>
>>> For me, if the data type is mutable, I prefer returning interfaces. It
>>> would be something like this:
>>> ```
>>> type Student interface {
>>>//...
>>> }
>>>
>>> type studentImpl struct {
>>>//...
>>> }
>>>
>>> func NewStudent(id string) Student {
>>>return {
>>>   //...
>>>}
>>> }
>>> ```
>>> There is a bit of history why I use this approach. For a struct with a
>>> mutex, I wanted to ensure that the user did not accidentally copy the
>>> struct. Nowadays we have *go vet* to give us a warning, but this was
>>> before *go vet* had this functionality. So, I return a pointer to the
>>> struct and hide it behind an interface. That way, it hides the
>>> implementation details from the user and the user can pass the object
>>> around without knowing whether it has a mutex or not.
>>>
>>> And then I ended up with some *constructors* returning structs and some
>>> returning interfaces. To ensure consistency, my colleagues and I decided to
>>> return interfaces for all mutable objects. For immutable objects, we return
>>> structs.
>>>
>>> The nice thing about this approach is that it makes the syntax a lot
>>> cleaner as you have to deal with fewer pointers.
>>> ```
>>> //instead of this
>>> func Update(student *Student) {
>>>   //...
>>> }
>>> func UpdateMany(students []*Student){
>>>   //...
>>> }
>>>
>>> //now you have this
>>> func Update(student Student) {
>>>   //...
>>> }
>>> func UpdateMany(students []Student){
>>>   //...
>>> }
>>> ```
>>> Some members in the team came from higher level languages and they found
>>> working with pointers a bit awkward, so we made some accommodation for
>>> them.
>>>
>>
>>> There are times when I need to *upgrade* some of these mutable objects,
>>> and this approach has proven to be quite flexible. It also plays nicely
>>> with code generators.
>>>
>>> Some people may disagree with this approach, but I have been using it
>>> ever since: return interface for mutable objects, return structs for
>>> immutable objects.
>>>
>>
>> I am one of those who disagrees. I have not seen any benefit from having
>> interfaces for data objects other than making other developers happy. In my
>> opinion, this amounts to emulating another language in Go. There are cases
>> where this might make sense, but as a general principle, I think it should
>> be avoided. Data is data. There are no implementation details to hide.
>>
>>
>>
>>> On Tuesday, August 9, 2022 at 3:09:10 AM UTC+7 t...@timpeoples.com
>>> wrote:
>>>
 I can't speak to the *auto-generated swagger client* case but I
 believe gRPC is still doing things the right way -- in that the framework
 defines an interface I (the framework API consumer) then implements.  IOW:
 I don't see that as a "java style interface" (where the interface defines
 the API contract).

 I suspect you and I are saything the same thing.

 t.

 On Monday, August 8, 2022 at 12:51:29 PM UTC-7 bse...@computer.org
 wrote:

> On Mon, Aug 8, 2022 at 12:51 

Re: [go-nuts] Preemptive interfaces in Go

2022-08-09 Thread burak serdar
On Mon, Aug 8, 2022 at 11:27 PM Henry  wrote:

> I am sure that many of us have been on that journey. After using Go for
> some time, we discover some practices that are not necessarily in agreement
> with the existing "adages" but effectively solve our problems.
>
> For me, if the data type is mutable, I prefer returning interfaces. It
> would be something like this:
> ```
> type Student interface {
>//...
> }
>
> type studentImpl struct {
>//...
> }
>
> func NewStudent(id string) Student {
>return {
>   //...
>}
> }
> ```
> There is a bit of history why I use this approach. For a struct with a
> mutex, I wanted to ensure that the user did not accidentally copy the
> struct. Nowadays we have *go vet* to give us a warning, but this was
> before *go vet* had this functionality. So, I return a pointer to the
> struct and hide it behind an interface. That way, it hides the
> implementation details from the user and the user can pass the object
> around without knowing whether it has a mutex or not.
>
> And then I ended up with some *constructors* returning structs and some
> returning interfaces. To ensure consistency, my colleagues and I decided to
> return interfaces for all mutable objects. For immutable objects, we return
> structs.
>
> The nice thing about this approach is that it makes the syntax a lot
> cleaner as you have to deal with fewer pointers.
> ```
> //instead of this
> func Update(student *Student) {
>   //...
> }
> func UpdateMany(students []*Student){
>   //...
> }
>
> //now you have this
> func Update(student Student) {
>   //...
> }
> func UpdateMany(students []Student){
>   //...
> }
> ```
> Some members in the team came from higher level languages and they found
> working with pointers a bit awkward, so we made some accommodation for
> them.
>

> There are times when I need to *upgrade* some of these mutable objects,
> and this approach has proven to be quite flexible. It also plays nicely
> with code generators.
>
> Some people may disagree with this approach, but I have been using it ever
> since: return interface for mutable objects, return structs for immutable
> objects.
>

I am one of those who disagrees. I have not seen any benefit from having
interfaces for data objects other than making other developers happy. In my
opinion, this amounts to emulating another language in Go. There are cases
where this might make sense, but as a general principle, I think it should
be avoided. Data is data. There are no implementation details to hide.



> On Tuesday, August 9, 2022 at 3:09:10 AM UTC+7 t...@timpeoples.com wrote:
>
>> I can't speak to the *auto-generated swagger client* case but I believe
>> gRPC is still doing things the right way -- in that the framework defines
>> an interface I (the framework API consumer) then implements.  IOW: I don't
>> see that as a "java style interface" (where the interface defines the API
>> contract).
>>
>> I suspect you and I are saything the same thing.
>>
>> t.
>>
>> On Monday, August 8, 2022 at 12:51:29 PM UTC-7 bse...@computer.org wrote:
>>
>>> On Mon, Aug 8, 2022 at 12:51 PM Tim Peoples  wrote:
>>>
 I don't necessarily consider the "multiple implementations" case as
 being truly preemptive -- if there really are multiple implementations
 (e.g. the "hash" package from the standard library).

 I'm much more concerned about interfaces that are defined by an API
 producer -- for one and only one impl -- and then adding a bunch of extra
 (often autogenerated) code to deal with that.

>>>
>>> Like a gRPC client/server, or auto-generated swagger client/server?
>>>
>>> I've had many instances where such an auto-generated client had to be
>>> passed down components that have no knowledge of those services. Writing
>>> such components using interfaces declaring only parts of those service
>>> implementations have benefits. An example that I can think of is an
>>> audit-trail service that deals with recording transaction metadata, looking
>>> them up, etc. It makes sense to write components that use only the writer
>>> part of that service, instead of requiring the whole thing. It makes
>>> writing tests easier. It lets you decouple services better, add
>>> adapters/interceptors etc.
>>>
>>>

 t.

 On Monday, August 8, 2022 at 11:02:31 AM UTC-7 bse...@computer.org
 wrote:

> On Mon, Aug 8, 2022 at 11:17 AM Tim Peoples 
> wrote:
>
>>
>> For years I've read the old adage, "Accept interfaces, return
>> structs" and have spent years working to instill this understanding among
>> my colleagues. I gathered a great many skills while learning Go (and
>> acquiring readability)  back in the day -- and one of the strongest of
>> those is the idea that interfaces should be defined by their consumer
>> instead of an API producer -- but I've now been away from Google longer
>> than I was there and I'm beginning to suspect that the general consensus

Re: [go-nuts] Preemptive interfaces in Go

2022-08-08 Thread burak serdar
On Mon, Aug 8, 2022 at 12:51 PM Tim Peoples  wrote:

> I don't necessarily consider the "multiple implementations" case as being
> truly preemptive -- if there really are multiple implementations (e.g. the
> "hash" package from the standard library).
>
> I'm much more concerned about interfaces that are defined by an API
> producer -- for one and only one impl -- and then adding a bunch of extra
> (often autogenerated) code to deal with that.
>

Like a gRPC client/server, or auto-generated swagger client/server?

I've had many instances where such an auto-generated client had to be
passed down components that have no knowledge of those services. Writing
such components using interfaces declaring only parts of those service
implementations have benefits. An example that I can think of is an
audit-trail service that deals with recording transaction metadata, looking
them up, etc. It makes sense to write components that use only the writer
part of that service, instead of requiring the whole thing. It makes
writing tests easier. It lets you decouple services better, add
adapters/interceptors etc.


>
> t.
>
> On Monday, August 8, 2022 at 11:02:31 AM UTC-7 bse...@computer.org wrote:
>
>> On Mon, Aug 8, 2022 at 11:17 AM Tim Peoples  wrote:
>>
>>>
>>> For years I've read the old adage, "Accept interfaces, return structs"
>>> and have spent years working to instill this understanding among my
>>> colleagues. I gathered a great many skills while learning Go (and acquiring
>>> readability)  back in the day -- and one of the strongest of those is the
>>> idea that interfaces should be defined by their consumer instead of an API
>>> producer -- but I've now been away from Google longer than I was there and
>>> I'm beginning to suspect that the general consensus among the *Go
>>> Literati* may have shifted around some things -- like preemptive
>>> interfaces.
>>>
>>> My arguments against preemptive interfaces have recently run into more
>>> and more pushback  -- especially among the influx of developers coming from
>>> the Java and/or C# world who seem to continually reject any notion that Go
>>> should be any different from the way they've always done things.
>>>
>>> This has recently come to a head with a brand new job (I'm 3 weeks in)
>>> where virtually all of their services are built atop a dependency injection
>>> framework having a data model with dozens (if not hundreds) of preemptive
>>> interfaces and my initial, cursory review tells me the codebase is at least
>>> an order of magnitude more complex that it needs to be.  (Note, I was told
>>> that none SWEs at this company (other than myself) knew any Go before they
>>> started).
>>>
>>> So, my questions to the group are thus, "Should I even care about this
>>> at all?  Are preemptive interfaces now considered the norm with Go? Or,
>>> should I just shut up and crawl back into my hole?
>>>
>>
>> I believe both approaches have their uses. What you call preemptive
>> interfaces can be effectively used to hide implementation details where
>> multiple implementations can exist. This approach can coexist very well
>> with interfaces defined by the consumer. For example we have services that
>> are written to implement an interface, so it becomes a logical deployment
>> unit. Then we have consumers of that service that define parts of the
>> interface service implements, so the consumer is not dependent on the
>> complete service, and we can add any interceptors/filters.
>>
>> However, I agree with your assessment that especially newcomers tend to
>> choose the traditional "interface is a contract" approach. In addition to
>> the effect of other languages, people seem to like "clean architecture".
>> Nevertheless, even with people dedicated to clean architecture, the idea of
>> "interface parts" seems to resonate, especially when you show that you can
>> define an interface on the consumer side that combines parts of multiple
>> "contracts".
>>
>>
>>>
>>> TIA,
>>> Tim.
>>>
>>> --
>>> 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...@googlegroups.com.
>>> To view this discussion on the web visit
>>> https://groups.google.com/d/msgid/golang-nuts/f4777928-875d-4c0a-a4a7-9fb57bf9d51fn%40googlegroups.com
>>> 
>>> .
>>>
>> --
> 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.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/34469b98-c37e-4a1d-af13-729b639a71ben%40googlegroups.com
> 

Re: [go-nuts] Preemptive interfaces in Go

2022-08-08 Thread burak serdar
On Mon, Aug 8, 2022 at 11:17 AM Tim Peoples  wrote:

>
> For years I've read the old adage, "Accept interfaces, return structs" and
> have spent years working to instill this understanding among my colleagues.
> I gathered a great many skills while learning Go (and acquiring
> readability)  back in the day -- and one of the strongest of those is the
> idea that interfaces should be defined by their consumer instead of an API
> producer -- but I've now been away from Google longer than I was there and
> I'm beginning to suspect that the general consensus among the *Go
> Literati* may have shifted around some things -- like preemptive
> interfaces.
>
> My arguments against preemptive interfaces have recently run into more and
> more pushback  -- especially among the influx of developers coming from the
> Java and/or C# world who seem to continually reject any notion that Go
> should be any different from the way they've always done things.
>
> This has recently come to a head with a brand new job (I'm 3 weeks in)
> where virtually all of their services are built atop a dependency injection
> framework having a data model with dozens (if not hundreds) of preemptive
> interfaces and my initial, cursory review tells me the codebase is at least
> an order of magnitude more complex that it needs to be.  (Note, I was told
> that none SWEs at this company (other than myself) knew any Go before they
> started).
>
> So, my questions to the group are thus, "Should I even care about this at
> all?  Are preemptive interfaces now considered the norm with Go? Or, should
> I just shut up and crawl back into my hole?
>

I believe both approaches have their uses. What you call preemptive
interfaces can be effectively used to hide implementation details where
multiple implementations can exist. This approach can coexist very well
with interfaces defined by the consumer. For example we have services that
are written to implement an interface, so it becomes a logical deployment
unit. Then we have consumers of that service that define parts of the
interface service implements, so the consumer is not dependent on the
complete service, and we can add any interceptors/filters.

However, I agree with your assessment that especially newcomers tend to
choose the traditional "interface is a contract" approach. In addition to
the effect of other languages, people seem to like "clean architecture".
Nevertheless, even with people dedicated to clean architecture, the idea of
"interface parts" seems to resonate, especially when you show that you can
define an interface on the consumer side that combines parts of multiple
"contracts".


>
> TIA,
> Tim.
>
> --
> 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.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/f4777928-875d-4c0a-a4a7-9fb57bf9d51fn%40googlegroups.com
> 
> .
>

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAMV2RqpwRJSA8zNuz3F3u00uOpDon8c%2B3fQRYXiga5WeuUJ_mQ%40mail.gmail.com.


Re: [go-nuts] A pedantic question about updating a map during iteration

2022-08-02 Thread burak serdar
None of the conditions specified in that clause applies for updating key
in-place. The way I read it, a new entry is not added, so the iteration
should visit every entry only once. Thus, the program always prints "1 1".

On Tue, Aug 2, 2022 at 9:20 PM Kevin Chowski  wrote:

> Hello Go gurus,
>
> I think there is some ambiguity in the language spec about what happens
> when a map entry is updated during iteration. Quoting the spec (
> https://go.dev/ref/spec#For_range):
>
> 3. The iteration order over maps is not specified and is not guaranteed to
> be the same from one iteration to the next. If a map entry that has not yet
> been reached is removed during iteration, the corresponding iteration value
> will not be produced. If a map entry is created during iteration, that
> entry may be produced during the iteration or may be skipped. The choice
> may vary for each entry created and from one iteration to the next. If the
> map is nil, the number of iterations is 0.
>
> As per my read of the spec, there is no guarantee about what happens when
> you update a map key in-place.
>
> For example, is this program guaranteed to print "1 1"?
> https://go.dev/play/p/PeBEXKp1deH
>
> Apologies if I just missed some other part of the spec that ensures this.
>
> Thanks in advance for your time,
> Kevin
>
> --
> 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.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/c4f1d37c-84bb-49c9-a935-7b1f560688e4n%40googlegroups.com
> 
> .
>

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAMV2RqqBL1rxQ9PQitVn3KnkWtoM6SYLCpVn8FPatU4-FiL21Q%40mail.gmail.com.


Re: [go-nuts] concurrent read/write different keys in map

2022-08-02 Thread burak serdar
What exactly do you mean by "read/write 5 different keys"?

If you have a map[int]*SomeStruct, for instance, and if you initialize this
map with some entries, and then if you have multiple goroutines all
performing lookups of distinct keys and modifying the contents of
*SomeStruct, it would be safe.

If you have multiple goroutines adding/removing keys from the map, that
would not be safe.

It would be interesting to know if rewriting existing distinct keys from
multiple goroutines would be safe or not.



On Tue, Aug 2, 2022 at 7:31 PM ag9920  wrote:

> Hi! If I have several 5 goroutines read/write 5 different keys in map
> independently without a Mutex/RWMutex. Each goroutine just read/write their
> own corresponding key. No intersection.
>
> In such a case, no goroutines will operate on the same key, does that mean
> it's safe?
>
> Or maybe each goroutine just write to its corresponding key once, with no
> read, will that be safe?
>
> --
> 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.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/76788485-6809-4397-bf94-536a0d0bf0b3n%40googlegroups.com
> 
> .
>

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAMV2Rqq50NX8WGGkPK%2BhRSz91QpUHzWWhMmz1c8RNKpa9dncZg%40mail.gmail.com.


Re: [go-nuts] Re: testing examples printing to stdout not working for global var

2022-05-02 Thread burak serdar
On Mon, May 2, 2022 at 2:57 PM 'simon place' via golang-nuts <
golang-nuts@googlegroups.com> wrote:

> i see, thanks
>
> the implementation of 'go test' (which the playground runs
> auto-magically.) replaces os.Stdout with a new reference behind the scenes
> before running the func, but after making global vars, so the code as
> written isn't strictly 'go' anymore.
>

The assertion that "the code as written isn't strictly go" is not correct.
You just hit an edge case in the testing framework. Most testing frameworks
that control the environment for the code under test will have edge cases.

Use of globals almost always complicates things wrt testing.



>
> https://go.dev/play/p/3FBjOmzYIiz?v=goprev
>
> shame it couldn't have been done at a lower level, say mangling the OS
> pointer and preserving the go pointer.
>
> i guess a comment explaining what is up with the surprising code i'm going
> to have to add, is the best i can do.
>
>
> On Monday, 2 May 2022 at 16:14:30 UTC+1 bse...@computer.org wrote:
>
>> On Mon, May 2, 2022 at 9:00 AM psi@gmail.com 
>> wrote:
>>
>>> #1 the two functions need to behave identically according to the syntax
>>> of the language.
>>>
>>> #2 this is how working code operates, so testing needs to be able to
>>> handle it.
>>>
>>> at a guess; 'testing' would appear to have some non-compliant reflection
>>> going on, in this edge-case.
>>>
>>
>> This is not related to reflection, but an edge case with the testing
>> framework. Testing sets os.Stdout to something else before it starts
>> running so that it can accumulate the output. For #1, you save the stdout
>> before testing framework reassigns it, so it is printed to the output, and
>> testing framework cannot see it. For #2, you are using the reassigned
>> stdout, so testing can catch what you wrote to it.
>>
>>
>>>
>>> but anyway; your reply has no relevance i can decern, and replying like
>>> this can put off useful comments. please don't get huffy i don't have the
>>> time/interest, just don't comment anymore.
>>>
>>> On Monday, 2 May 2022 at 03:32:46 UTC+1 peterGo wrote:
>>>
 It looks like you have a bug in your code.

 "In tests, standard output is accumulated during execution and dumped
 to standard output when done."

 "Example functions may include a concluding line comment that begins
 with "Output:" and is compared with the standard output of the function
 when the tests are run."

 In ExampleMain(), you improperly used the os.Stdout variable value as
 of the testing package initialization.

 In ExampleMain2(), you properly used the os.Stdout variable value as of
 when the function was run.

 testing package
 https://pkg.go.dev/testing@latest

 Peter

 On Sunday, May 1, 2022 at 8:03:29 PM UTC-4 psi@gmail.com wrote:

> this caught me out, is it a bug?
>
> https://go.dev/play/p/atJb8dZHoqi
>
 --
>>> 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...@googlegroups.com.
>>> To view this discussion on the web visit
>>> https://groups.google.com/d/msgid/golang-nuts/d8654a21-e060-4bee-842f-e6eb41d21878n%40googlegroups.com
>>> 
>>> .
>>>
>> --
> 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.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/994e20cc-c1c5-4e8c-a022-16a2e83a85a4n%40googlegroups.com
> 
> .
>

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAMV2Rqo%3DnRLY707rGYG9FL0vawhvC0VnpcRzGZHGv6Z_QN6QoQ%40mail.gmail.com.


Re: [go-nuts] Re: testing examples printing to stdout not working for global var

2022-05-02 Thread burak serdar
On Mon, May 2, 2022 at 9:00 AM psi@gmail.com  wrote:

> #1 the two functions need to behave identically according to the syntax of
> the language.
>
> #2 this is how working code operates, so testing needs to be able to
> handle it.
>
> at a guess; 'testing' would appear to have some non-compliant reflection
> going on, in this edge-case.
>

This is not related to reflection, but an edge case with the testing
framework. Testing sets os.Stdout to something else before it starts
running so that it can accumulate the output. For #1, you save the stdout
before testing framework reassigns it, so it is printed to the output, and
testing framework cannot see it. For #2, you are using the reassigned
stdout, so testing can catch what you wrote to it.


>
> but anyway; your reply has no relevance i can decern, and replying like
> this can put off useful comments. please don't get huffy i don't have the
> time/interest, just don't comment anymore.
>
> On Monday, 2 May 2022 at 03:32:46 UTC+1 peterGo wrote:
>
>> It looks like you have a bug in your code.
>>
>> "In tests, standard output is accumulated during execution and dumped to
>> standard output when done."
>>
>> "Example functions may include a concluding line comment that begins with
>> "Output:" and is compared with the standard output of the function when the
>> tests are run."
>>
>> In ExampleMain(), you improperly used the os.Stdout variable value as of
>> the testing package initialization.
>>
>> In ExampleMain2(), you properly used the os.Stdout variable value as of
>> when the function was run.
>>
>> testing package
>> https://pkg.go.dev/testing@latest
>>
>> Peter
>>
>> On Sunday, May 1, 2022 at 8:03:29 PM UTC-4 psi@gmail.com wrote:
>>
>>> this caught me out, is it a bug?
>>>
>>> https://go.dev/play/p/atJb8dZHoqi
>>>
>> --
> 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.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/d8654a21-e060-4bee-842f-e6eb41d21878n%40googlegroups.com
> 
> .
>

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAMV2RqrfEbvPnSxoVUoTBxag8v3%3D7B_D9LwAEPZtLkzkJrkuoA%40mail.gmail.com.


Re: [go-nuts] Question regarding Golang Interfaces and composite struct

2022-04-28 Thread burak serdar
On Thu, Apr 28, 2022 at 9:49 AM Glen D souza  wrote:

> Consider the following piece of code
>
> type Dog struct {
> }
>
> type Walker interface {
> Walks()
> }
>
> func (d *Dog) Walks() {
>
> }
>
> func CheckWalker(w Walker) {
>
> }
>
> func main() {
> dog := Dog{}
> CheckWalker(dog) -> cannot use dog (variable of type Dog) as Walker
> value in argument to CheckWalker: Dog does not implement Walker (method
> Walks has pointer receiver)compilerInvalidIfaceAssign
> 
> }
>
> When I run this code I get the error as show in the red above
>
> Now consider this piece of code
>
> type Dog struct {
> }
>
> func (d *Dog) Walks() {
>
> }
>
> type Bird struct {
> }
>
> func (b *Bird) Flys() {
>
> }
>
> type Flyer interface {
> Flys()
> }
>
> type Walker interface {
> Walks()
> }
>
> type Combined interface {
> Walker
> Flyer
> }
>
> type Animal struct {
> Dog
> Bird
> }
>

Look at the Animal struct. The Walks and Flys methods are defined for
*Animal, not for Animal. The type Animal has no methods. Because of that,
*Animal implements the combined interface, and not Animal.

In your main(), you declare animal={}, thus the variable `animal`
can be used where Combined is required.



>
> func CheckCombined(c Combined) {
>
> }
>
> func Check(w Walker) {
>
> }
> func main() {
> animal := {}
> CheckCombined(animal)
> }
>
> This code runs without any error!
> Since Animal struct is compose of Dog and Bird (not pointer to them), why
> this code is working where as only pointer to Dog and Bird implement the
> necessary methods to satisfy the interface Combined ?
>
> --
> 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.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/80a3498b-b1e9-4a30-a55c-ef93a53e89e4n%40googlegroups.com
> 
> .
>

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAMV2RqqWFrd-SZAVgh%2BbbTzY63ZEpmWU6%2B%2B0bkO-rWvhiaDpSQ%40mail.gmail.com.


Re: [go-nuts] Hesitating on using cached / un-cached channels

2022-04-11 Thread burak serdar
An unbuffered channel is a synchronization mechanism. A send on an
unbuffered channel will block until there is a concurrent receive from
another goroutine.

Your program has only one goroutine. A send to an unbuffered channel will
always deadlock, so will a receive from it. So the problem you are
describing is not a problem related to the way unbuffered channels work,
but it is due to the way the program is organized: it is written to
deadlock. With a buffered channel, it can run. This program does not need a
buffer more than 1. Once the send runs, the channel will be full, and the
second case will be activated. The first case cannot run until the second
case is done, which will terminate the loop.

On Mon, Apr 11, 2022 at 10:08 PM robert engels 
wrote:

> There are numerous ways to create a “dead lock” in any program (this may
> actually be a “live lock” but I didn’t fully understand your statement -
> this is just one of them.
>
>
> On Apr 11, 2022, at 9:29 PM, Zhaoxun Yan  wrote:
>
> Hi guys, I have a great demonstration on why an un-cached channel might
> malfunction while receiving:
>
> package main
> import(
> "fmt"
> "time"
> )
>
> func main(){
> t := time.NewTicker(time.Second * 3)
> stopnow := make(chan bool)
> //stopnow := make(chan bool, 1) //cached channel instead
> var n int
>
> for{
> select{
> case <-t.C:
> n++
> fmt.Printf("%d\n", n)
>
> if n==3{
> stopnow <- true //The Only Sending!!!
> t.Stop()
> }
>
> case a:=<-stopnow: //The Only Receiving!!!
> if a{
> goto END
> }
> }
> }
> END:
> fmt.Println("out of select")
> }
>
> In the code above, you will never see the printout "out of select" ,
> because the for-select receiver is not working while the code is run inside
> timer receiver in the line " stopnow <- true".
>
> So an un-cached channel like " stopnow := make(chan bool)" will
> occasionally but inevitably miss receiving while the code is busy
> processing a competing receiving.
>
> That is why I use cached channel instead, like " stopnow := make(chan
> bool, 1)", which un-received message(s) will be cached until gotten
> received.
>
> However there comes another vulnerability - How large should the cache be?
>
> In a simple scenario like this, I am very confident there will be 1
> message to receive only. But on a complex server, it is very common that a
> goroutine will receive unexpected many messages from other goroutine or
> functions. And it is not safe for the programmer to just guess a ceiling
> for the number of unprocessed messages on any time - just as to guess the
> maximum on how many cars can line up after a red light. If you guess wrong,
> only one additional message will breach the cache and cause a crash:
>
> package main
>
> var c = make(chan int, 1)
>
> func main() {
>
> c <- 1
> c <- 2 //fatal error: all goroutines are asleep - deadlock!
> c <- 3
>
> }
>
> The code above crashes at the point that the cache of channel c is full,
> but the sender still puts another message into it.
>
> What is your thought on this?
> Regards,
> Zhaoxun
>
> --
> 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.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/fefc350d-3423-4fb6-b844-703ce03c7e5fn%40googlegroups.com
> 
> .
>
>
> --
> 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.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/FD201AFD-CD9D-48A8-AD3D-3B1813F3A479%40ix.netcom.com
> 
> .
>

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAMV2RqpqNZKYC5a1JOzue1PkW9RhB3aL6n6z3Gsm-ifoCTQ%3DFQ%40mail.gmail.com.


Re: [go-nuts] RFC: function or interface?

2022-03-31 Thread burak serdar
On Thu, Mar 31, 2022 at 1:14 PM Adam Pritchard 
wrote:

> I’m working on a library to help get the “real” client IP from HTTP
> requests:
> https://github.com/realclientip/realclientip-go
> https://pkg.go.dev/github.com/realclientip/realclientip-go
>
> Right now the “strategies” are like:
>
> type Strategy func(headers http.Header, remoteAddr string) string
> ...
> clientIPStrategy, err := 
> realclientip.RightmostTrustedCountStrategy("X-Forwarded-For", 1)
> ...
> clientIP := clientIPStrategy(req.Header, req.RemoteAddr)
>
> So, functions matching a signature are created that process the input.
>
> But I keep wondering: Should I be returning types (structs) adhering to an
> interface instead?
>
> I’m starting to think I should, but I can’t think of what difference it
> would make.
>

One option is to return interfaces, but at the same time define a function
type that implements that interface:

type Strategy interface {
   GetIP(headers http.Header, remoteAddr string) string
}

type StrategyFunc func(headers http.Header, remoteAddr string) string

func (s StrategyFunc) GetIP(headers http.Header, remoteAddr string) string
{return s(headers,remoteAddr)}

This way, you can use functions of type StrategyFunc as well as interfaces
of type Strategy when you create such strategies. The users of the library
would always see the interface.

This is similar to how the handlers are done in the http library.


> Any feedback would be appreciated.
>
> Adam Pritchard
>
> --
> 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.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/20a8eac9-98b2-4af5-87f3-e811d5a97e3cn%40googlegroups.com
> 
> .
>

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAMV2Rqo1Mjh3eL7VjV3mHT6owgEnO5iF6%3D36a1WGMEbKpPayWA%40mail.gmail.com.


Re: [go-nuts] Data Structure for String Interning?

2022-01-09 Thread burak serdar
I think the question is "why do you want to intern strings". The solution
can be different for different use cases.

I work with large Json files where keys are repeated, and the keys are long
strings (URLs) so using a map[string]string to intern the keys makes a lot
of sense. For serialization, the same idea is used to compress large data
using string tables: a []string holds all unique strings, and references to
those strings are represented using uint32 indexes. For the example where
you intern words, you might even consider a single []byte containing all
the words concatenated, with a custom string representation containing
uint32 offset and length. This may or may not be faster than the map
implementation, but it will occupy less space, but with a single large
object in memory.

On Sun, Jan 9, 2022 at 5:35 PM Bakul Shah  wrote:

> The string header will be 16 bytes on 64bit word size machines.
> If most of the words are much shorter, interning won’t buy you
> much. For applications where you *know* all the words are short,
> and the total string space won’t exceed 4GB, you can try other
> alternatives. For instance if the max length of any word is 16 bytes,
> create 16 string tables. Then the ‘interned string’ type is a 4 byte
> index, with the bottom 4 bits indicating the length as well as which
> table to index! A table for N byte words stores one copy of each
> unique word and in consecutive slots on N bytes. Given that on modern
> machines even though memory can be plentiful, memory access is slow
> & computing is fast, this can win. You will also need a possibly unsafe
> String func. that doesn’t allocate string data space. You can even allow
> an overflow table if longer words are not common. And you can allow
> many more unique words by extending the interned string type to 8
> bytes.
>
> On Jan 9, 2022, at 3:07 PM, burak serdar  wrote:
>
> 
> Note that a with a map[string]string, the code:
>
> m[s]=s
>
> The contents of the string s are not duplicated, only the string header s
> is.
>
> On Sun, Jan 9, 2022 at 3:52 PM jlfo...@berkeley.edu <
> jlforr...@berkeley.edu> wrote:
>
>> I'm aware of Artem Krylysov's idea for string interning published on
>> https://artem.krylysov.com/blog/2018/12/12/string-interning-in-go/
>>
>> If I understand it correctly, each string is stored twice in a map, once
>> as
>> a key and once as a value. That means that words that only appear once in
>> his example of string interning the words in the novel 1984 are 100%
>> inefficient
>> in terms of storage. Words that appear twice are neutral. The advantage
>> of his
>> approach only appears for words that appear three or more times.
>>
>> I'm wondering if there's a map-like data structure that would store a
>> string
>> as the key, and the address of the key as the value. I'm aware that a
>> standard
>> Go map can't be used for this because its components might be moved around
>> while a program is running so taking the address of the key would be
>> dangerous,
>> which is why it isn't allowed.
>>
>> This came up because I profiled a run of an app I'm working on that
>> processed 12518 strings, of which 9810 appeared 2 or fewer times.
>> Krylysov's
>> approach would only be marginally useful for this app.
>>
>> The data structure I'm looking for would always be at least neutral, and
>> would start
>> showing a benefit when a word appears twice.
>>
>> Does anybody know of such a data structure?
>>
>> Cordially,
>> Jon Forrest
>>
>> --
>> 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.
>> To view this discussion on the web visit
>> https://groups.google.com/d/msgid/golang-nuts/36684584-11eb-4bc0-a436-4906d523c8ban%40googlegroups.com
>> <https://groups.google.com/d/msgid/golang-nuts/36684584-11eb-4bc0-a436-4906d523c8ban%40googlegroups.com?utm_medium=email_source=footer>
>> .
>>
> --
> 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.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/CAMV2RqodPp7kye6%3D5PH0NHha%2BwQC4mqfotipoutm4aeL1EK0Fw%40mail.gmail.com
> <https://groups.google.com/d/msgid/golang-nuts/CAMV2RqodPp7kye6%3D5PH0NHha%2BwQC4mqfotipoutm4aeL1EK0Fw%40mail.gmail.com?utm_medium=email_source=footer>
> .
>
>

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAMV2RqqWOkvCv-bqjpCvJqQjrOUqHdRtTQwGJVnpH%3DUXvpC_zQ%40mail.gmail.com.


Re: [go-nuts] Data Structure for String Interning?

2022-01-09 Thread burak serdar
On Sun, Jan 9, 2022 at 4:30 PM jlfo...@berkeley.edu 
wrote:

>
>
> On Sunday, January 9, 2022 at 3:07:18 PM UTC-8 bse...@computer.org wrote:
>
>> Note that a with a map[string]string, the code:
>>
>> m[s]=s
>>
>> The contents of the string s are not duplicated, only the string header s
>> is.
>>
>
> I didn't know this. That's very good to know.
>
> What about this:
>
> package main
>
> type word struct {
>   s string
>   refcnt int
> }
>
> var w1 = word {"moby", 1}
>
> func main() {
> m := make(map[string]word)
> m["moby"] = w1
> }
>
> This is a little closer to what I'd like to do.
> How many times would the string "moby" be stored?
>

If you write it as follows, the string "moby" will have only one copy:

m[w1.s]=w1

This will only duplicate the string header `s`, not the contents of 's'.


>
> Thanks,
> Jon
>
> --
> 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.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/6f06bbe8-8d50-46f6-8b28-f4e680ecae43n%40googlegroups.com
> 
> .
>

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAMV2RqocHbKrYz8-a9p_W86qoQK7wGTc9%3DWKHOUEKHVSo18CwA%40mail.gmail.com.


Re: [go-nuts] Data Structure for String Interning?

2022-01-09 Thread burak serdar
Note that a with a map[string]string, the code:

m[s]=s

The contents of the string s are not duplicated, only the string header s
is.

On Sun, Jan 9, 2022 at 3:52 PM jlfo...@berkeley.edu 
wrote:

> I'm aware of Artem Krylysov's idea for string interning published on
> https://artem.krylysov.com/blog/2018/12/12/string-interning-in-go/
>
> If I understand it correctly, each string is stored twice in a map, once as
> a key and once as a value. That means that words that only appear once in
> his example of string interning the words in the novel 1984 are 100%
> inefficient
> in terms of storage. Words that appear twice are neutral. The advantage of
> his
> approach only appears for words that appear three or more times.
>
> I'm wondering if there's a map-like data structure that would store a
> string
> as the key, and the address of the key as the value. I'm aware that a
> standard
> Go map can't be used for this because its components might be moved around
> while a program is running so taking the address of the key would be
> dangerous,
> which is why it isn't allowed.
>
> This came up because I profiled a run of an app I'm working on that
> processed 12518 strings, of which 9810 appeared 2 or fewer times.
> Krylysov's
> approach would only be marginally useful for this app.
>
> The data structure I'm looking for would always be at least neutral, and
> would start
> showing a benefit when a word appears twice.
>
> Does anybody know of such a data structure?
>
> Cordially,
> Jon Forrest
>
> --
> 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.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/36684584-11eb-4bc0-a436-4906d523c8ban%40googlegroups.com
> 
> .
>

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAMV2RqodPp7kye6%3D5PH0NHha%2BwQC4mqfotipoutm4aeL1EK0Fw%40mail.gmail.com.


Re: [go-nuts] Amateur question: when you should use runes?

2021-11-15 Thread burak serdar
On Mon, Nov 15, 2021 at 11:00 AM Kamil Ziemian 
wrote:

> Hello,
>
> I read quite a few blog posts, articles, listen to nice number to talks
> about strings, runes and encoding in Go. I now reading Go Language Spec and
> I just stuck in the section about runes. I mean, it isn't hard as itself,
> but it raises to much questions to me. I decided that I need to learn more
> about Unicode and UTF-8, so from today I'm reading Unicode Technical Site
> (?), currently the Glossary (https://www.unicode.org/glossary/). But I
> can't understand one thing: when in practice you should use runes?
>
> My understanding at this moment is like that. Unicode assign every symbol
> a number (at this moment I disregard normalization and any other more
> advance stuff), rune is alias for int32 that stores integer representation
> of this number. UTF-8 is variable size encoding using one or more bytes to
> encode symbol and shouldn't and DOESN'T represent integer value of symbols
> Unicode number. Virtues of UTF-8 are clear as how it allows to save a space
> is clear to me, but I can't find a reason why I should transform my text to
> runes? In Go stdlib there is a RuneReader interface (?) so this reason must
> exists, but I just can't find anything. Maybe it have something to do with
> sending information using internet? I don't know, this is totally outside
> my humble knowledge.
>

In general, you should work with runes whenever you are working with text
that is entered by humans, or text that will be read by humans.

When you work with a string as a stream of bytes, then you either assume
the string does not contain any bytes over 127, or you have to decode the
UTF-8 string yourself. Working with runes eliminates both problems.




>
> You can say, that since I don't see a reason to use runes, I probably
> shouldn't care about it. This is a valid point, but I want to know Go
> reasonable well and constantly find code with runes which reason of
> existence I don't understand (e.g. functions in stdlib that operates on
> runes) is quite demoralising to me.
>
> Best
> Kamil
>
> --
> 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.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/f3dad0e1-cd25-4e33-a7f2-34e0118bf68an%40googlegroups.com
> 
> .
>

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAMV2Rqovfg9k9ALawv%2BC36_AxT0sbOb%2BEpcpKNO9r2kmg_T1nQ%40mail.gmail.com.


Re: [go-nuts] Why Doesn't "len()" Work With Structs?

2021-10-25 Thread 'burak serdar' via golang-nuts
On Sun, Oct 24, 2021 at 12:12 PM jlfo...@berkeley.edu <
jlforr...@berkeley.edu> wrote:

> I noticed that the len() function doesn't take a struct as an argument
> (see below).
> This is a big surprise. Can someone shed some light on why this
> restriction exists?
>

len() gives the number of elements in an object, not the size of the
object. Maybe unsafe.Sizeof is what you are looking for:

x:=[]int{1,2}
fmt.Println(len(x),unsafe.Sizeof(x))

Output: 2 24



> Cordially,
> Jon Forrest
>
> --
> package main
>
> import "fmt"
>
> var s struct {
> i1  int
> i2  int
> }
>
> func main() {
>fmt.Printf("len(s) = %d\n", len(s)) // -- invalid argument s (type
> struct { i1 int; i2 int }) for len
> }
>
> --
> 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.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/281160cc-0d99-4bd9-8f3d-703cda288051n%40googlegroups.com
> 
> .
>

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAMV2RqpG1oses4u%3D3WHayBR79JVAMBXa%2BFBgAcQoMY1kCaMZ7A%40mail.gmail.com.


Re: [go-nuts] Re: Why Doesn't "len()" Work With Structs?

2021-10-25 Thread 'burak serdar' via golang-nuts
On Sun, Oct 24, 2021 at 6:54 PM jlfo...@berkeley.edu 
wrote:

> I'm now aware that that I could use
>
> len(([unsafe.Sizeof(T{})][0]byte{}))
>
> But this seems overly complicated. Plus, I don't see why
> this is unsafe. Please advise.
>

Sizeof is unsafe because it returns the number of bytes of the underlying
object, including the overhead such as padding or headers. For slices, it
returns the size of the header, not the size of the underlying array.
Sizeof also means you are probably bypassing the Go type system.


>
> Jon
>
>
> On Sunday, October 24, 2021 at 5:14:44 PM UTC-7 kortschak wrote:
>
>> You can use len to determine the sizeof a struct.
>>
>> https://play.golang.org/p/f0x8p_04lP1 ;)
>>
>>
>> On Sun, 2021-10-24 at 16:44 -0700, jlfo...@berkeley.edu wrote:
>> > Thanks for the replies.
>> >
>> > I had been trying to translate the trick from C into Go where you can
>> > find how many structures are in an initialized array of structures
>> > by dividing the size of the array by the size of one structure. As
>> > I've learned, not only isn't this possible, because you can't get
>> > the size of one structure, but also because it isn't necessary.
>> > Instead, using a slice of structures rather than an array, I can just
>> > do "len(structslice)".
>> > That gives me what I need.
>> >
>> > But, I still have some questions about the responses. First, I think
>> > the expected value of len(struct) should be its size, in bytes,
>> > like with a string. Are there any examples of problems this would
>> > cause? I don't understand why this has to be
>> > unsafe. (It could even be done at compile time). I also don't
>> > understand the comment about recursive calls. Since it's possible
>> > to assign one structure to another I would think that the structure
>> > length is known. Since I'm new to Go I'm probably
>> > not aware of the finer points that would make this not so.
>> >
>> > Cordially,
>> > Jon Forrest
>> >
>> > On Sunday, October 24, 2021 at 11:29:58 AM UTC-7
>> > filipdimi...@gmail.com wrote:
>> > > len() works on indexed types - arrays, slices, maps, strings. It
>> > > also works on buffered channels but we can consider that a
>> > > sequence. I don't consider a struct a sequence. It's non-obvious
>> > > what the behaviour would be. Both of these sound reasonable: len()
>> > > should be the memory size of the struct like sizeof in C/C++ *or*
>> > > it should be the sum of the lengths of its (sequence) members.
>> > >
>> > > The first case is way too low-level for Go, because it belongs to
>> > > an unsafe operation so that's an easy no, ... and it already exists
>> > > as unsafe.Sizeof().
>> > >
>> > > The second case (len being the sum of its members' lengths) would
>> > > require recursive calls, and almost surely infinite cycles as we
>> > > eventually get to pointers.
>> > >
>> > > On Sunday, October 24, 2021 at 8:11:37 PM UTC+2
>> > > jlfo...@berkeley.edu wrote:
>> > > > I noticed that the len() function doesn't take a struct as an
>> > > > argument (see below).
>> > > > This is a big surprise. Can someone shed some light on why this
>> > > > restriction exists?
>> > > >
>> > > > Cordially,
>> > > > Jon Forrest
>> > > >
>> > > > --
>> > > > package main
>> > > >
>> > > > import "fmt"
>> > > >
>> > > > var s struct {
>> > > > i1 int
>> > > > i2 int
>> > > > }
>> > > >
>> > > > func main() {
>> > > > fmt.Printf("len(s) = %d\n", len(s)) // -- invalid argument
>> > > > s (type struct { i1 int; i2 int }) for len
>> > > > }
>>
>>
>> --
> 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.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/fa5a2544-314b-41e4-8686-2d55ac1ecf69n%40googlegroups.com
> 
> .
>

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAMV2RqpMjq5F0RR1gs%3DFO0dNpQRq5DqFG65jQ0BNZ652jD10Cg%40mail.gmail.com.


Re: [go-nuts] Loading Certificate and Key from string not file for HTTPs server

2021-09-13 Thread burak serdar
On Mon, Sep 13, 2021 at 3:03 PM Sam Caldwell  wrote:

> Does anyone have any ideas of an easy path to load certificate and key
> files from a string rather than a file?
>
> *Use Case:*
> 1. traditionally we all put a cleartext file on disk with our private key
> and public certificate.  If the server is breached, we just regenerate all
> the things and move on.
> 2. I would like to store my certificates and keys in a more secure
> location (AWS SSM Param store, Hashicorp Vault, etc.).
> 3. The certificate is only read from file at startup as best I can tell,
> and relocating certificates and keys to an encrypted store would (a) allow
> better auditing when the content is accessed, (b) restrict access to only
> authorized processes and (c)  make rotating keys and certificates a much
> easier process.
>
> *Analysis:*
> *Current Functionality:*
> - We setup a server using ListenAndServeTLS() and pass in a filename for
> the certificate and key.
> - In go1.17.1/src/net/http/server.go at 3066, tls.LoadX509KeyPair() loads
> is called.
> - LoadX509KeyPair() exists at 230 in src/crypto/tls/tls.go and
>- It calls os.ReadFile() at 231 and 235.
> *Possible Solution:*
> - We cannot break existing things, and within the limitations of golang,
> it is probably the least-disruptive solution to add a new
> ListenAndServeTLSFromVar() which would functionally do everything
> ListenAndServeTLS() does, but instead of reading a file, it would instead
> accept the input string as the certificate/key content.
> - Alternatively ListenAndServeTLSFromVar() would accept a boolean
> parameter which would determine if certificate and key parameters are
> filenames or content strings.  in this case, ListenAndServeTLSFromVar()
> would support both filenames and content string use cases and provide a
> path to unifying the approach if the community begins to adopt the use case
> identified above in large numbers.
>

You can already do this by creating an http.Server{} with a tls.Config
initialized from the certificates you have. You have to decode and parse
the certificates from strings to create the tls.Config.



>
> *Conclusion:*
> I'm willing to do the work and contribute the code to implement the above,
> but I wanted to solicit opinions first.  Ideally the functionality exists
> already and I am reinventing a wheel.  In that case, please point me in the
> right direction so I can focus my efforts on my current project.
>
> --
> 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.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/6e283ce3-7802-4765-9fd3-156d01c65bbbn%40googlegroups.com
> 
> .
>

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAMV2RqoUG4XoXs%2BCfDdDeNqdtv9QXAX5mZ2En-P2jKL6zbSFpw%40mail.gmail.com.


Re: [go-nuts] Right way to fan out work loads

2021-09-08 Thread burak serdar
On Wed, Sep 8, 2021 at 10:02 AM David Belle-Isle 
wrote:

>
> Hi,
>
> I've been facing this question for a while and never managed to find the
> "right" answer. Hopefully this forum will be able to enlighten me a little
> bit.
>
> Given a very simple pattern: Consume some data, transform it, store it
> (ETL). The storing part is slow(er) and needs to be fanned out.
>
> The question: What's the best (correct? idiomatic?) way to implement that
> in Go?
>
> A) From "main", buffer the incoming data and launch a goroutine and pass
> it the data to store. Similar to how you could implement a web server
> handling an incoming connection in Go.
>
> OR
>
> B) From "main", create N channels and spin up N goroutines to send down
> data to workers. Round-robin writes to the N channels.
>

How about creating N goroutines, with one channel. All goroutines listen to
the channel. Main goroutine writes to the channel as it receives data, so
any available goroutine picks it up.



> B1) Do you buffer the data in "main" or after the channel, in the
> goroutine?
>
> I understand that (A) can spin out of control and launch too many
> goroutines and (B) can run into a bottle neck. Each of these problems can
> be easily addressed. I'm more interested in hearing what you think is the
> "right" way to solve this problem?
>
> Thanks
>
> David
>
> --
> 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.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/6ba8cf62-8711-4c39-bf6c-f255727385ffn%40googlegroups.com
> 
> .
>

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAMV2Rqp1bfvkCBWvXHbO1yVTvbJm3jT_0i8RrrGCHgwP3ffVdA%40mail.gmail.com.


Re: [go-nuts] HTTP request matching different endpoint - gorilla mux

2021-09-02 Thread burak serdar
Your paths are ambiguous.  "/nfdm-fdm/v2/shared-data" matches
"/nfdm-fdm/v2/{id}" where id=shared_data. You can use a regex for the path
with {id} to exclude the "shared_data" match.

On Thu, Sep 2, 2021 at 10:13 AM Van Fury  wrote:

> Hi All,
>
> I have the following to handler functions, DataSetsGet and
> RetrieveSharedData.
> When make request with the URL
> https://127.0.0.1:2/nfdm-fdm/v2/shared-data, I get response from
> DataSetsGet handler instead of RetrieveSharedData handler function. When I
> take the bracket from {id} to id, I get the right response from
> RetrieveSharedData handler. Any help to solve this issue, my code below
> with omitted codes.
>
> ```
> func DataSetsGet(response http.ResponseWriter, request *http.Request) {
>
> // Data set response codes
> }
>
> func RetrieveSharedData(response http.ResponseWriter, request
> *http.Request) {
> // Retrieve shared data response codes
> }
>
>
>
> type Route struct {
> Namestring
> Method  string
> Pattern string
> HandlerFunc http.HandlerFunc
> }
>
> var Router = NewRouter()
>
> type Routes []Route
>
> func NewRouter() *mux.Router {
> router := mux.NewRouter().StrictSlash(true)
> for _, route := range routes {
> var handler http.Handler
> handler = route.HandlerFunc
>
> router.
> Methods(route.Method).
> Path(route.Pattern).
> Name(route.Name).
> Handler(handler)
> }
>
> return router
> }
>
>
> var routes = Routes{
> Route{
> "DataSetsGet",
> strings.ToUpper("Get"),
> "/nfdm-fdm/v2/{id}",
> DataSetsGet,
> },
>
> Route{
> "RetrieveSharedData",
> strings.ToUpper("Get"),
> "/nfdm-fdm/v2/shared-data",
> RetrieveSharedData,
> },
>
> }
>
>
> func main{
>
> addr := "127.0.0.1:6060"
>
> server := NewServer(addr)
>
> go func() {
> err := server.ListenAndServe()
> if err != nil && err != http.ErrServerClosed {
> logger.Log.Errorf("Could not listen on %s: %v\n", addr, err)
> }
> }()
> }
>
>
>
> // Create a new server
> func NewServer(ListAddr string) *http.Server {
>
> return {
> Addr: ListAddr,
> Handler:  Router,
> ReadTimeout:  5 * time.Second,
> WriteTimeout: 10 * time.Second,
> IdleTimeout:  15 * time.Second,
> }
> }
> ```
>
> BR
> Fury
>
> --
> 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.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/faf2c214-3638-4b3e-b460-1a789e351defn%40googlegroups.com
> 
> .
>

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAMV2RqqU3bTZ3midOUr1Dn8Aax0wdgSABmrPrOOfSv%2B252YqRg%40mail.gmail.com.


[go-nuts] gofmt error formatting suggestion

2021-08-10 Thread burak serdar
Here is an idea to make reading code a bit easier: If gofmt can format this:

f, err:=os.Open(file)
if err!=nil {
   return err
}

as:

f, err:=os.Open(file); if err!=nil { return err }

it would make reading code easier by pushing the error passing code to the
right. This formatting would only be used for passing errors without any
handling.

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAMV2RqrX6ZF85JDV7oNZDM-NwaL%3DAAYXg-oXwS_DSTZwaYd%3DZg%40mail.gmail.com.


Re: [go-nuts] The behavior of the function variable which points to the struct method

2021-08-10 Thread burak serdar
On Tue, Aug 10, 2021 at 3:50 PM E Z  wrote:

> It works when I changed the code as your suggested. That's great, thanks.
>
> And I'm still a little confused here, you know when we use the struct
> method directly, it is only when the function is called that the type of
> receiver determines whether the passed struct is a pointer or a copied
> value. But when using a function pointer, why does it decide whether to
> bind a pointer or a copied value at the time of assignment, but not at the
> time of function called?
>
> It seems that these two behaviors are not consistent. Is there any benefit
> to doing so? I didn't find much information on this topic on Google. Is
> there any extended reading on this topic?
>

It is consistent. The pointer to function assignment captures the current
receiver.

func (z Zoo) Display()
func (z *Zoo) DisplayPtr()

fptr:=gz.Display  --> Captures gz, since Display gets gz by value, captures
gz by value

fptr2:= gz.DisplayPtr -> Captures gz, since DisplayPtr gets gz by
reference, captures *gz

That is:

gz:={}
fptr2:=gz.DisplayPtr
gz={}
fptr2() -> This will call the DisplayPtr with the first value of gz, not
the second



>
> On Tuesday, August 10, 2021 at 12:07:26 PM UTC-7 bse...@computer.org
> wrote:
>
>> On Tue, Aug 10, 2021 at 12:01 PM E Z  wrote:
>>
>>> I feel confused when I use the function pointer which point to the
>>> struct method. Here is the test code:
>>>
>>> /***
>>> package main
>>>
>>> type Zoo struct {
>>> Animal string
>>> }
>>>
>>> func (z Zoo) Display(){
>>> fmt.Printf("Current animal is:%s\n", z.Animal)
>>> }
>>>
>>
>> This method has a value receiver. When pf is assigned to gz.Display, it
>> is assigned with its receiver, which is a copy of gz.
>>
>> Change the method to func (z *Zoo) Display(), and it will work as you
>> expect.
>>
>>
>>>
>>> func main(){
>>> gz := {
>>> Animal: "Monkey",
>>> }
>>>
>>> pf := gz.Display
>>> pf()   //display "Current animal
>>> is Monkey"
>>> gz.Animal="Tiger"
>>> pf()//display "Current
>>> animal is Monkey"
>>> gz.Display() //display "Current animal is
>>> Tiger"
>>> }
>>> ***/
>>> As the code is shown above,  even though I changed the value of the
>>> member field of the Zoo instance gz,  the function pointer call that
>>> followed still prints the unmodified value.
>>>
>>> Can someone help explain why? In my opinion, The function pointer pf
>>> should bind to the instance gz and its method(note that gz here is a
>>> pointer variable),  if so anytime I change the value of the variable gz,
>>> pf should reflect the changes.
>>>
>>> Thanks,
>>> Ethan
>>>
>>> --
>>> 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...@googlegroups.com.
>>> To view this discussion on the web visit
>>> https://groups.google.com/d/msgid/golang-nuts/60c6523c-dbce-4530-aa51-06f2c1223ca8n%40googlegroups.com
>>> 
>>> .
>>>
>> --
> 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.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/651e712a-9f81-4b90-a56c-1fc4b4e8b174n%40googlegroups.com
> 
> .
>

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAMV2RqrifLCDEHyRqNH6vzYVV0hmH9VGfpf55pJQSJy9QdGsPg%40mail.gmail.com.


Re: [go-nuts] The behavior of the function variable which points to the struct method

2021-08-10 Thread burak serdar
On Tue, Aug 10, 2021 at 12:01 PM E Z  wrote:

> I feel confused when I use the function pointer which point to the struct
> method. Here is the test code:
>
> /***
> package main
>
> type Zoo struct {
> Animal string
> }
>
> func (z Zoo) Display(){
> fmt.Printf("Current animal is:%s\n", z.Animal)
> }
>

This method has a value receiver. When pf is assigned to gz.Display, it is
assigned with its receiver, which is a copy of gz.

Change the method to func (z *Zoo) Display(), and it will work as you
expect.


>
> func main(){
> gz := {
> Animal: "Monkey",
> }
>
> pf := gz.Display
> pf()   //display "Current animal
> is Monkey"
> gz.Animal="Tiger"
> pf()//display "Current animal
> is Monkey"
> gz.Display() //display "Current animal is
> Tiger"
> }
> ***/
> As the code is shown above,  even though I changed the value of the member
> field of the Zoo instance gz,  the function pointer call that followed
> still prints the unmodified value.
>
> Can someone help explain why? In my opinion, The function pointer pf
> should bind to the instance gz and its method(note that gz here is a
> pointer variable),  if so anytime I change the value of the variable gz,
> pf should reflect the changes.
>
> Thanks,
> Ethan
>
> --
> 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.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/60c6523c-dbce-4530-aa51-06f2c1223ca8n%40googlegroups.com
> 
> .
>

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAMV2RqoFhtb0Zs%3DOVBX-7X1CzXp4yf%2BpeCeR9N_efPQGo67u%3Dg%40mail.gmail.com.


Re: [go-nuts] Behavior to copy the value of pointer inside another pointer

2021-08-04 Thread burak serdar
On Wed, Aug 4, 2021 at 9:18 AM Olivier Szika 
wrote:

> Hi all,
>
> I am surprised by the behavior of "&(*var)".
>

According to the language spec, pointer indirection is addressable:

https://golang.org/ref/spec#Address_operators

Thus, taking the address of an indirection yields the original pointer, not
a pointer to a copy of its contents.


>
> https://play.golang.org/p/CK522lRkddd
>
> It is expected?
>
> --
> 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.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/5f265699-ed67-4798-92d0-88832a7444d1n%40googlegroups.com
> 
> .
>

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAMV2Rqpi9WBCX1%3D4H2DGVbXCf%3DyQgWPGkUZn%3DiqH52TsfTas-g%40mail.gmail.com.


Re: [go-nuts] How can I check error types of gRPC calls?

2021-05-19 Thread burak serdar
Here is something I did to pass custom error information:

Based on the grpc code, if an error type has GRPCStatus()
*status.Status function, then grpc gets the status information using
that method. For the error types that can go through grpc, I have this
method below:

func (e MyError) GRPCStatus() *status.Status {
var code codes.Code
switch e.HTTPStatus {
  case http.StatusBadRequest:
code = codes.InvalidArgument
  case http.StatusUnauthorized:
 code = codes.Unauthenticated
  default:
 code = codes.Unknown
 }
 x, _ := json.Marshal(e)
 return status.New(code, string(x))
}


In this example, the error type includes an HTTP status code, and the
grpc status is decided based on that. The grpc error contains a JSON
marshaled error information.

On the receiving end, I have this function:

func FromGRPCError(err error) (MyError, bool) {
  if x, ok := status.FromError(err); ok {
var e MyError
if json.Unmarshal([]byte(x.Message()), ) == nil {
return e, true
   }
  }
  return MyError{}, false
}

This decodes the error information from the incoming error.

This scheme can be extended to deal with multiple error types.

On Tue, May 18, 2021 at 8:45 AM 'Axel Wagner' via golang-nuts
 wrote:
>
> You cant to use status.Code(err), which gives you the gRPC status code.
>
>
> On Tue, May 18, 2021 at 3:08 PM cpu...@gmail.com  wrote:
>>
>>
>> Thank you for the pointer. After looking at the API, I'm still confused how 
>> to use it. I can status.Convert(err) to get a status object but couldn't 
>> really figure how how to use that to extract the actual underlying base 
>> error?
>> On Saturday, May 15, 2021 at 2:12:28 PM UTC+2 kortschak wrote:
>>>
>>> On Sat, 2021-05-15 at 04:47 -0700, cpu...@gmail.com wrote:
>>> > In my local code, I'm using things like
>>> >
>>> > if errors.Is(err, api.ErrMustRetry) { ... }
>>> >
>>> > How would I achieve the same on errors returned by the gRCP
>>> > interface? I've noticed these are wrapped:
>>> >
>>> > rpc error: code = Unknown desc = must retry rpc error: code = Unknown
>>> > desc = must retry
>>> >
>>> > I assume the errors package won't work here as type information is
>>> > not carried across gRPC: What is the best practice here: unwrap the
>>> > root error from the RPC result (how) and perform string comparison?
>>> >
>>>
>>> There is the status package which provides tools for examining the gRPC
>>> errors, https://pkg.go.dev/google.golang.org/grpc/status.
>>>
>>>
>> --
>> 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.
>> To view this discussion on the web visit 
>> https://groups.google.com/d/msgid/golang-nuts/8ecd4024-a846-4657-8e61-15c16289ccd2n%40googlegroups.com.
>
> --
> 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.
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/golang-nuts/CAEkBMfERsv28%2BJV-EVYqhZraHbyYmPftQV6V0i55zVaK1R13HQ%40mail.gmail.com.

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAMV2RqrL%3DkqGH2_RSpKuF8ppT-JCfGL9XSFkE63WRX8Eraw3OQ%40mail.gmail.com.


Re: [go-nuts] Idiomatic Go code

2021-03-04 Thread burak serdar
On Thu, Mar 4, 2021 at 6:19 AM Christian von Kietzell
 wrote:
>
> Hello Gophers,
>
> since I obviously don't have enough Twitter followers to get more than
> one answer to my Go question I'm posting it here ;-)
>
> Would you consider this idiomatic Go code?
>
> https://play.golang.org/p/ymPt_9tKQ9p
>
> I'm talking specifically about returning a cleanup function. My
> reasoning for it goes kinda like this:
>
> - doSomething doesn't care whether the output is a file or a buffer or
> os.Stdout, so it should just get an io.Writer.
> - The cleanup work for using os.Stdout (or a buffer in tests) is
> different than for *os.File.
> - Who's responsible for doing that work? If I return *os.File directly
> from getFile(), there's an implicit assumption that the file needs to be
> closed by the caller. But what if it's os.Stdout?
> - The alternative of putting all that in run() is kinda ugly because
> run() potentially has to do a lot more.
>
> A potential problem I see? The error from os.File.Close() is never
> checked, neither is the error from bufio.Writer.Flush(). In this small
> example that wouldn't bother me because it means the program ends
> anyway. But in other cases it might become more of a problem.

The problems you noted aside, this is similar to context.WithCancel()
that returns a cancel() func. It is a pattern I've seen and used in
the field. In my opinion, it is idiomatic Go code.

>
> What do you think?
>
> Kind regards,
> Chris
>
> --
> 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.
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/golang-nuts/7baf0ec35696fc5501dfbe6ce8f161f8%40vonkietzell.de.

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAMV2RqrruFwSb8EVdtMO%3D9wy2oUu_FekhDyy%3DOkAg%2Bcc%3DK03PQ%40mail.gmail.com.


Re: [go-nuts] Interface arguments to generic functions

2021-01-19 Thread burak serdar
On Tue, Jan 19, 2021 at 10:37 PM Ian Lance Taylor  wrote:
>
> On Tue, Jan 19, 2021 at 8:02 PM burak serdar  wrote:
> >
> > On Tue, Jan 19, 2021 at 8:38 PM Ian Lance Taylor  wrote:
> > >
> > > On Tue, Jan 19, 2021 at 7:06 PM burak serdar  wrote:
> > > >
> > > > In the following program, it is valid to pass an interface to function 
> > > > P:
> > > >
> > > > func P[T fmt.Stringer](x T) {
> > > >  fmt.Println(x)
> > > > }
> > > >
> > > > func main() {
> > > >   var v fmt.Stringer
> > > >   P(v)
> > > > }
> > > >
> > > > However, there is no way for P to check if x is nil. This does not 
> > > > compile:
> > > >
> > > > func P[T fmt.Stringer](x T) {
> > > >  if x!=nil {
> > > > fmt.Println(x)
> > > > }
> > > > }
> > > >
> > > > Is it possible to write a generic function that can test if its
> > > > argument with a constraint is nil?
> > >
> > > For an interface type the value "nil" is the zero value of the type,
> > > so this is the general zero value issue mentioned at
> > > https://go.googlesource.com/proposal/+/refs/heads/master/design/go2draft-type-parameters.md#the-zero-value
> > >
> > > You can write
> > >
> > > func P[T fmt.Stringer](x T) {
> > >  var zero T
> > >  if x!=zero {
> > > fmt.Println(x)
> > > }
> > > }
> > >
> >
> > But that breaks the generic function for non-interface types.
> >
> > type Str string
> >
> > func (s Str) String() string {return string(s)}
> >
> > func main() {
> >P(Str(""))
> > }
> >
> > Now the passed parameter is the zero value, but not nil.
>
>
> OK, but what are you really trying to check?  Why do you want to check
> that an interface is not the zero value while at the same time you
> don't care whether a string is the zero value?

As a generic-function writer, I do not know if the argument will be an
interface or a concrete type. I don't want to check if it is
zero-value, I want to check if it is nil, because I don't want it to
panic.

If I was to convert the following non-generic function to a generic one:

func f(x SomeIntf) {
  if x!=nil {
x.Something()
  }
 ...
}

the obvious way to do this is:

func f[T SomeIntf](x T) {
  ...
}

but I can no longer check if x is nil.

Treating nil-checks as a special case might work maybe?

>
> Ian

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAMV2RqqGVm%3DbiiAeKGHe5G%2By3WgZBSJGtbpA0ugZKngcW0Mgpw%40mail.gmail.com.


Re: [go-nuts] Interface arguments to generic functions

2021-01-19 Thread burak serdar
On Tue, Jan 19, 2021 at 8:38 PM Ian Lance Taylor  wrote:
>
> On Tue, Jan 19, 2021 at 7:06 PM burak serdar  wrote:
> >
> > In the following program, it is valid to pass an interface to function P:
> >
> > func P[T fmt.Stringer](x T) {
> >  fmt.Println(x)
> > }
> >
> > func main() {
> >   var v fmt.Stringer
> >   P(v)
> > }
> >
> > However, there is no way for P to check if x is nil. This does not compile:
> >
> > func P[T fmt.Stringer](x T) {
> >  if x!=nil {
> > fmt.Println(x)
> > }
> > }
> >
> > Is it possible to write a generic function that can test if its
> > argument with a constraint is nil?
>
> For an interface type the value "nil" is the zero value of the type,
> so this is the general zero value issue mentioned at
> https://go.googlesource.com/proposal/+/refs/heads/master/design/go2draft-type-parameters.md#the-zero-value
>
> You can write
>
> func P[T fmt.Stringer](x T) {
>  var zero T
>  if x!=zero {
> fmt.Println(x)
> }
> }
>

But that breaks the generic function for non-interface types.

type Str string

func (s Str) String() string {return string(s)}

func main() {
   P(Str(""))
}

Now the passed parameter is the zero value, but not nil.


> Ian

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAMV2Rqo61NNVSf_y54rq9-iCDcY%3DjDZk%2Bd3tzy4%3DMX3XL-VZug%40mail.gmail.com.


[go-nuts] Interface arguments to generic functions

2021-01-19 Thread burak serdar
In the following program, it is valid to pass an interface to function P:

func P[T fmt.Stringer](x T) {
 fmt.Println(x)
}

func main() {
  var v fmt.Stringer
  P(v)
}

However, there is no way for P to check if x is nil. This does not compile:

func P[T fmt.Stringer](x T) {
 if x!=nil {
fmt.Println(x)
}
}

Is it possible to write a generic function that can test if its
argument with a constraint is nil?

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAMV2Rqp3OV%2BOHTYJL3zkBbssktOSaRQDqz7fzSoeLU002YTZ1Q%40mail.gmail.com.


Re: [go-nuts] A new solution of type list in generic.

2020-12-28 Thread burak serdar
On Mon, Dec 28, 2020 at 7:10 PM redsto...@gmail.com
 wrote:
>
> But interface-only contracts do work here, as I suggest, only need to 
> introduce implicit type conversion.  Type list is not so good as you say. 
> When defining the generic funcition max, I am not expecting number and 
> string, and I am not expecting operator>,  I am expecting method BiggerThan. 
> Using methods keeps consistency of the language, and it is much more clear 
> than type list and operators. Type list is strange in the interface with 
> methods, and causes a lot of other problems. This solution only adds 
> complexity in generic libraries. But the type list invades in the language 
> core.  So far as I can see, the implicit type conversion is better, at least 
> it can be considered. If there is  technical difficulty on the implicit type 
> conversion, we can discuss it.

If all you need is a method BiggerThan, then what you need is an
interface, not generics.


>
> On Tuesday, December 29, 2020 at 12:19:49 AM UTC+8 bbse...@gmail.com wrote:
>>
>> On Mon, Dec 28, 2020 at 4:30 AM redsto...@gmail.com
>>  wrote:
>> >
>> > If generic is inevitable, make it better. The type list in the current 
>> > draft is so special that it is added only for operators. I think it will 
>> > bring complexity and inconsistens in go. So I get an idea to replace it.
>>
>> There have been similar proposals before. Interface-only contracts do
>> not work for primitive types, as you realized, so there were
>> suggestions to work around that limitation, as you already did.
>>
>> I believe the question you should ask is that in a language with no
>> operator overloading, what is the purpose of defining a constraint
>> that allows operator >? That simply means numeric types and string. I
>> think it is much more concise and explicit to say "the function
>> expects a numeric or string" than to say "the function expects a type
>> on which > can be used".
>>
>> >
>> > type bigger[T bigger] interface{
>> > BiggerThan(T) bool
>> > }
>> >
>> > func max[T bigger[T]](a, b T) T{
>> > if a.BiggerThan(b) {
>> > return a
>> > } else {
>> > return b
>> > }
>> > }
>> >
>> > type BiggerInt int
>> >
>> > func (a BiggerInt) BiggerThan(b BiggerInt)bool{
>> > return a > b
>> > }
>> >
>> > type BiggerFloat float32
>> >
>> > func (a BiggerFloat) BiggerThan(b BiggerFloat)bool{
>> > return a > b
>> > }
>> >
>> >
>> > max(1,2)
>> >
>> > instead of operators we use method. the generic call site remain the same.
>> > If we allow the implicity type conversion between BiggerInt and int, this 
>> > will work.
>> >
>> > This solution will write more code when we define BiggerThan in each type. 
>> > But we remove type list in interface. How do you think it?
>> >
>> > --
>> > 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...@googlegroups.com.
>> > To view this discussion on the web visit 
>> > https://groups.google.com/d/msgid/golang-nuts/debe7749-fe96-4587-814b-a76ee7f48528n%40googlegroups.com.
>
> --
> 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.
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/golang-nuts/3aa54c64-b76e-4ccf-bbf2-b42c3c12d24fn%40googlegroups.com.

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAMV2Rqo%2BkTQaDAWFc39dEcD6a%2B%2B%2BUizT62S02Uu14bDtApXo%3DQ%40mail.gmail.com.


Re: [go-nuts] json.NewDecoder()/Decode() versus Unmarshal() for single large JSON objects

2020-12-28 Thread burak serdar
On Mon, Dec 28, 2020 at 5:22 PM Amit Saha  wrote:
>
> Hi all, let's say I am a single large JSON object that I want to
> process in my HTTP server backend.
>
> I am trying to get my head around if there is any performance
> advantage - memory or CPU to use the json.NewDecoder()/Decode()
> mechanism versus the Unmarshal() function?

Unmarshal uses the decoder for unmarshaling. Unless you are planning
to process the JSON object piece by piece using a decoder, the two are
identical in terms of performance.

>
> Thanks,
> Amit
>
> --
> 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.
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/golang-nuts/CANODV3%3DU2KRRkvAAEfYqRtCVtYnh2dmGreqePF8QXLo1PriSPw%40mail.gmail.com.

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAMV2RqoBk_9SnEP5M8%3DnzC63qsECFyNpRU%3DU8YAMR2byXjWuqw%40mail.gmail.com.


Re: [go-nuts] A new solution of type list in generic.

2020-12-28 Thread burak serdar
On Mon, Dec 28, 2020 at 4:30 AM redsto...@gmail.com
 wrote:
>
> If generic is inevitable, make it better.  The type list in the current draft 
> is so special that  it is added only for operators. I think it will bring 
> complexity and inconsistens in go. So I get an idea to replace it.

There have been similar proposals before. Interface-only contracts do
not work for primitive types, as you realized, so there were
suggestions to work around that limitation, as you already did.

I believe the question you should ask is that in a language with no
operator overloading, what is the purpose of defining a constraint
that allows operator >? That simply means numeric types and string. I
think it is much more concise and explicit to say "the function
expects a numeric or string" than to say "the function expects a type
on which > can be used".

>
> type bigger[T bigger] interface{
> BiggerThan(T) bool
> }
>
> func max[T bigger[T]](a, b T) T{
> if a.BiggerThan(b) {
> return a
> } else {
> return b
> }
> }
>
> type BiggerInt int
>
> func (a BiggerInt) BiggerThan(b BiggerInt)bool{
> return a > b
> }
>
> type BiggerFloat float32
>
> func (a BiggerFloat) BiggerThan(b BiggerFloat)bool{
> return a > b
> }
>
>
> max(1,2)
>
> instead of operators we use  method. the generic call site remain the same.
> If we allow the implicity type conversion between BiggerInt and int, this 
> will work.
>
> This solution will write more code when we define BiggerThan in each type. 
> But we remove type list in interface. How do you think it?
>
> --
> 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.
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/golang-nuts/debe7749-fe96-4587-814b-a76ee7f48528n%40googlegroups.com.

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAMV2Rqpa9vnPcLuxyHUdNME0Cw9%2BK1wSDhYp4Qqp_S6bZ4_Ong%40mail.gmail.com.


Re: [go-nuts] Re: Generics, please go away!

2020-12-22 Thread burak serdar
On Tue, Dec 22, 2020 at 12:09 PM Anthony Martin  wrote:
>
> 'Axel Wagner' via golang-nuts  once said:
> > What isn't welcome is your attempt of alienating people with a different
> > viewpoint from yours and make them feel unwelcome. And if you continue to
> > insist on doing that, the community *will* ask you to leave.
>
> Please don't minimize or silence the lived experience
> of people disproportionately affected by generics.
>
> We should protect non-generic function bodies.

I also developed some horrendous code using generics in Java. I can
relate to the resistance many are having against generics. However,
there are some differences in the Go generics implementation that
makes me hopeful, so I suggest those who are opposed to it to give it
a chance and try it. This is not Java generics that were forced into
the language without changing the underlying JVM. Nor is it C++ (yet)
that you can't really do anything useful without writing lots of
cryptic code just to keep the libraries happy. A balanced approach in
the library that doesn't impose generics on developers at every
possible opportunity may go a long way.

>
> Concrete code matters.
>
>   Anthony
>
> --
> 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.
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/golang-nuts/X%2BJD0mE0ZzY7AyM2%40alice.

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAMV2Rqo1KgAp2F4BQRSsm9Zx4kviUEW4GRx6KnktBzmWp0LQRg%40mail.gmail.com.


Re: [go-nuts] embedding

2020-09-28 Thread burak serdar
On Mon, Sep 28, 2020 at 10:55 AM Michał Pawełek  wrote:
>
> https://play.golang.org/p/CBuzITRmTiP
>
> Why isn't T1 allowed to pass to f ?

func f requires an argument of type T. You cannot pass a value of type
T1. However, T1 has T embedded in it, so you can pass:

f(t1.T)


>
> --
> 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.
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/golang-nuts/76a2daf6-8b37-4b55-bfc0-c6621551e464n%40googlegroups.com.

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAMV2Rqpbphxh2Ev%2B%2BhAHWkQz5e4Uhaq0h2s3gkJDEc5t1pQs7g%40mail.gmail.com.


Re: [go-nuts] global goroutine data / thread local storage?

2020-09-23 Thread burak serdar
On Wed, Sep 23, 2020 at 6:17 PM Alex Mills  wrote:
>
> Since by default all http requests coming to a go http server are on their 
> own goroutine, I am wondering if there is a way to have some sort of "global" 
> variable that is local to a goroutine if that makes sense, something like 
> this, where "gork" is the namespace for variables available anywhere within a 
> goroutine:
>
>
> func PrintLoggedInUser(){
> log.Println(gork.loggedInUser)
> }
>
> go func(){
>  var loggedInUser = "abc"
>  PrintLoggedInUser()
> }()
>
> go func(){
>  var loggedInUser = "def"
>  PrintLoggedInUser()
> }()
>
>
> why? i am looking to log the current logged in user id, without having to 
> manually pass that id to every log call.

Usually, this kind of information is placed in the http request
context, so all the function down the call chain can have access to
the variables in the context. You have to pass that context to the
call chain.

>
>
> log.Warn("foo")  // will log:  "foo", "logged in user id:", abc
> log.Error("bar")  // will log:  "bar", "logged in user id:", abc
>
> but for now, I have to pass the id manually:
>
> log.Warn(id, "foo")  // will log:  "foo", "logged in user id:", abc
> log.Error(id, "bar")  // will log:  "bar", "logged in user id:", abc
>
>
>
> --
> 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.
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/golang-nuts/07fb2e73-14a2-4559-a7d6-2010acbc7c51n%40googlegroups.com.

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAMV2RqqcLRazZXs%3DQCMPkffAi41yKkA%2BL5_TzBmrWMi9LBjo4Q%40mail.gmail.com.


  1   2   3   4   5   >