Re: [go-nuts] Re: How to end producer from the consumer side

2019-01-22 Thread Josh Humphries
On Tue, Jan 22, 2019 at 8:33 AM  wrote:

> Hi, we have the same problem of OP.
> But, in the Chris's playground there could be an error, indeed if the
> consumer
> runs slower of the producer the program ends in a deadlock.
>
> To force this behavior just add a time.Sleep() after the foor loop in main.
> --> https://play.golang.org/p/A3i6TEyGQm_L
>
> Am I wrong?
>

This is wrong because it's not using the select expression in the producer
correctly. Instead of a default case with unconditional channel write, you
need the channel write to be one of the cases. Like so:
https://play.golang.org/p/piR5pyXeV_Y



>
> Thanks for the help.
>
>
> Il giorno martedì 21 febbraio 2012 01:51:55 UTC+1, Jan ha scritto:
>>
>> hi all, quick question, I have a scenario where the producer should
>> generate numbers indefinitely, until it is told to stop.
>>
>> Most of the channel producer/consumer examples assume that the producer
>> closes the channels and dies cleanly (on its goroutine).
>>
>> When I close the channel on the reader instead, i get a panic. Any simple
>> ways around it ?
>>
>> Pseudo-code:
>>
>> func producer() chan int {
>>   c := make(chan int)
>>   for {
>> // produce number
>> c <- some_number
>>   }
>> }
>>
>> func main() {
>>   c := producer()
>>   for some_condition {
>> consume(<-c)
>>   }
>>   close(c)
>>   ...
>> }
>>
>> Since I'm going to call this producer zillions of times, I want to make
>> sure whatever memory/resources it uses is reclaimed and cleanly exited when
>> c is closed.
>>
>> Ideas ?
>>
>> many thanks in advance :)
>> Jan
>>
>> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [go-nuts] How to append nil using reflect

2019-01-11 Thread Josh Humphries
On Fri, Jan 11, 2019 at 5:59 PM Xinhu Liu  wrote:

> Hi Ian,
>
> thanks for your reply.
>
> After reading and experimenting a lot I think I understand the slight
> differences between nil and interface{} with nil value.
>
> The only thing I find confusing is that interface{}(nil) == nil returns
> true.
>

In that context, they are the same thing -- the nil interface. In fact
SomeInterface(nil)
== interface{}(nil) is also true -- the values are both the nil interface.
(The nil identifier is quite overloaded in Go since it can also indicate a
nil pointer, a nil map, a nil slice, a nil function, or a nil channel,
depending on context).

The issue at hand is that reflect.ValueOf(nil) does *not* give you an
instance with type interface{} and value nil -- it gives you a zero-value
(e.g. invalid) instance. This is because reflect.ValueOf returns the
*concrete* type and value of the input value, but nil interface has no
concrete type or value. So, in order to get a reflect.Value of type
interface{} and nil value, you have to go through some hoops.


>
> (The reason why I use reflect on interface is that I want to operate slice
> with different element types, like []interface{}, []int and so on.)
>
> Best regards,
> Xinhu
>
> Am Fr., 11. Jan. 2019 um 01:39 Uhr schrieb Ian Lance Taylor <
> i...@golang.org>:
>
>> On Thu, Jan 10, 2019 at 3:40 PM  wrote:
>> >
>> > I want to append a nil value using reflect.Append(), but I got a panic:
>> reflect: call of reflect.Value.Set on zero Value.
>> >
>> > This is my code.
>> >
>> > s := make([]interface{}, 10)
>> > v := reflect.ValueOf(nil)
>> > reflect.Append(reflect.ValueOf(s), v)
>> >
>> > So is there a way i can append nil? Currently I do this as workaround:
>> >
>> > s := make([]interface{}, 10)
>> > s0 := make([]interface{}, 1)
>> > r := reflect.AppendSlice(reflect.ValueOf(s), reflect.ValueOf(s0))
>> >
>> > It works but I think there must be a better way.
>>
>> First you have to clearly distinguish between nil, an uninitialized
>> value with no type, and the value interface{}(nil), which is an
>> uninitialized value of type interface{}.  You want the latter.  Then,
>> it's always a bit awkward to work with interface types with the
>> reflect package, because the reflect package naturally tries to look
>> for the value stored in the interface type, whereas you actually want
>> the interface type.
>>
>> Here is one way to do it:
>>
>> https://play.golang.org/p/Qt5-AmYa9Mk
>>
>> 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.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [go-nuts] getting a reflect.Type for a type

2018-12-05 Thread Josh Humphries
On Wed, Dec 5, 2018 at 12:16 PM Burak Serdar  wrote:

> On Wed, Dec 5, 2018 at 10:12 AM Mark Volkmann 
> wrote:
> >
> > I can get a reflect.Type for a variable with the following: myType :=
> reflect.TypeOf(myVariable)
> >
> > How can I get a reflect.Type for a type I have defined?
> > For example: type MyThing struct { …bunch of fields… }
> > I need to get a reflect.Type that describes the MyThing type.
> >
> > The best I can find is this: myThingType :=
> reflect.TypeOf(new(MyThing)).Elem()
>
>
> myThingType:=reflect.TypeOf(MyThing{})
>

This works for concrete types, but not for interfaces or named channel and
function types.

For interfaces, you can use a nil pointer:

myThingType := reflect.TypeOf((*MyThing)(nil)).Elem()

For channels and functions, you don't need a pointer or the Elem() call:

myThingType := reflect.TypeOf(MyThing(nil))

The use of nil above is also good for named map type: the other suggestion
above will allocate an unused empty map (though the compiler may optimize
that away).


>
> >
> > I seems odd that I have to create one with new, getting a pointer to it,
> and then ask for the type of the thing in points to (with Elem) in order to
> get what I need.
> >
> > --
> > R. Mark Volkmann
> > Object Computing, Inc.
> >
> > --
> > You received this message because you are subscribed to the Google
> Groups "golang-nuts" group.
> > To unsubscribe from this group and stop receiving emails from it, send
> an email to golang-nuts+unsubscr...@googlegroups.com.
> > For more options, visit https://groups.google.com/d/optout.
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [go-nuts] Rethink possibility to make circular imports

2018-11-30 Thread Josh Humphries
On Fri, Nov 30, 2018 at 8:50 AM Michel Levieux 
wrote:

> Hi guys,
>
> I've been trying to find examples of cases where it is complicated to
> structure the project because circular imports are forbidden, but I can't
> find something simple that I can show you. The thing is when I've been
> confronted to such cases, it was with large projects, and I have no simple
> way of reducing it to anything that can stand in a mail.
>

How about find a *single* dependency cycle in a large project (if there are
many, find the shortest), and then briefly describe it and justify the
cycle? If you don't want to reveal internal details of a closed source
project, you can just rename the components, as long as their new name is
at least abstractly indicative of the component's purpose.

You may even get good replies about good ways to re-organize the example to
break the cycle -- perhaps in a clean way that you haven't yet considered.



>
> Maybe it would help if you gave an example of some code that you think
>> requires circular imports and we can see if it can be restructured without?
>>
>
> I know that most projects can be restructured without circular imports,
> but my point is that sometimes, even if it *can* be restructured without
> them, it *should not*. I don't really know how to convey clearly what's
> in my mind, maybe I'm wrong in my  conclusions, but I've thought a lot
> about this and it makes me uncomfortable. From my own perspective, if the
> logical resolution of a problem leads to a structure with loops in its
> semantics and construction, the language should not require rethinking such
> solution so that there are no more loops in its architecture.
>
> I'm gonna keep trying to find a really simple and clear use case, and I'll
> get back to you guys when I find one.
>
> Le jeu. 29 nov. 2018 à 23:30, Rob Pike  a écrit :
>
>> And to reduce build time, especially for incremental builds.
>>
>> -rob
>>
>>
>> On Fri, Nov 30, 2018 at 8:17 AM Ian Lance Taylor  wrote:
>>
>>> On Thu, Nov 29, 2018 at 5:22 AM Michel Levieux 
>>> wrote:
>>> >
>>> > The last few days I've been thinking a lot about the fact that Go does
>>> not allow circular imports.
>>> > I'm not really sure of why it currently works that way, but from what
>>> I've understood the way the compiler works - which is also the reason why
>>> compilation of Go programs is much faster than other languages - makes it
>>> quite difficult to authorize circular imports.
>>>
>>> That's not the real reason.  The real reason is to make program
>>> initialization as clear and unambiguous as possible.
>>>
>>> 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.
>>> For more options, visit https://groups.google.com/d/optout.
>>>
>> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [go-nuts] protoc question

2018-11-18 Thread Josh Humphries
Support for Go is not built into protoc. Instead, Go code gen relies on a
protoc plugin. A serious omission from the help output for protoc is how to
use plugins:

--_out  Generate source code by invoking plugin program named
protoc-gen-.

So, to use the --go_out flag, you need to install the Go plugin, which is
named protoc-gen-go
<https://github.com/golang/protobuf/tree/master/protoc-gen-go>. To install
that plugin, you can use the Go tool:

go get github.com/golang/protobuf/protoc-gen-go

When protoc tries to invoke protoc-gen-go, it will expect to find it in
your PATH environment. But you can also use a --plugin flag to protoc to
tell it exactly where the plugin binary lives.


*Josh Humphries*
jh...@bluegosling.com


On Sun, Nov 18, 2018 at 4:57 PM Tharaneedharan Vilwanathan <
vdhar...@gmail.com> wrote:

> Hi All,
>
> I have a minor question. When I run "protoc --help", I do not see "go_out"
> option but I see others:
>
>   --cpp_out=OUT_DIR   Generate C++ header and source.
>   --csharp_out=OUT_DIRGenerate C# source file.
>   --java_out=OUT_DIR  Generate Java source file.
>   --js_out=OUT_DIRGenerate JavaScript source.
>   --objc_out=OUT_DIR  Generate Objective C header and source.
>   --php_out=OUT_DIR   Generate PHP source file.
>   --python_out=OUT_DIRGenerate Python source file.
>   --ruby_out=OUT_DIR  Generate Ruby source file.
>
> Is it a minor bug or am I missing something?
>
> Thanks
> dharani
>
>
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [go-nuts] go-grpc question

2018-10-17 Thread Josh Humphries
On Wed, Oct 17, 2018 at 5:04 PM  wrote:

> Hi Josh,
>
> Thanks for getting back ! Wouldn't having a single TCP connection be a
> bottleneck (assuming no layer-4 load balancer) especially if there is a
> slow reader, tcp flow control would limit other streams on that connection.
> In that case wouldn't having more connections help ?
>

A *grpc.ClientConn is not a single TCP connection to a *server*: it is a
"logical" connection to a *service*. It can manage a very large number of
actual sockets. It supports pluggable name resolution as well as load
balancing, for routing requests in the presence of multiple physical
connections.

But, as I mentioned, you may have an issue if using the default DNS
resolver and a hostname that resolves to just a single IP address: that
will cause the grpc.ClientConn to maintain only a single connection. (By
default, the DNS resolver will try to maintain one connection to every IP
address returned -- unless something has changed recently.)

In that case, yes, there could be a bandwidth bottleneck, especially if the
network link is not reliable (e.g. over internet/WAN, vs. between machines
in the same datacenter/region). For machines in the same datacenter, (at
least in my experience) the poor load balancing has been a bigger concern.

IIRC, I don't think it's that hard to create a custom resolver that
resolves a single IP address but instructs the client to use multiple
connections. (I haven't worked in those particular nooks and crannies of
the project in a while, though.)



>
> Thanks,
> Nakul
>
> On Wednesday, October 17, 2018 at 6:26:00 AM UTC-7, Joshua Humphries wrote:
>>
>> *+grp...@googlegroups.com*
>>
>> *moving golan...@googlegroups.com to BCC*
>>
>> In general, connections are not cheap, but stubs are. Actual
>> implementations for some languages differ, but Go complies with this.
>>
>> What that means is that, generally speaking, you should not try creating
>> the *grpc.ClientConn for each request. Instead create it once and cache
>> it. You *can* create the stub just once and cache it (they are safe to
>> use concurrently form multiple goroutines). But that is not necessary; you
>> could also create the stub for each request, using the cached connection.
>>
>> In practice, creating a new connection for each request will have
>> overhead in terms of allocations, creating and tearing down goroutines, and
>> also in terms of latency, to establish a new network connection every time.
>> So it is advisable to cache and re-use them. However, if you are not using
>> TLS, it *may be* acceptable to create a new connection per request
>> (since the network connection latency is often low, at least if the client
>> and server are in the same region/cloud provider). If you are using TLS,
>> however, creating a connection per request is a bit of an atrocity: you are
>> not only adding the extra latency of a TLS handshake to every request
>> (typically 10s of milliseconds IIRC), but you are also inducing a
>> potentially huge amount of load on the server, by making it perform many
>> more digital signatures (one of the handshake steps) than if the clients
>> cached and re-used connections.
>>
>> Historically, the only reason it might be useful to create a new
>> connection per request in Go was if you were using a layer-4(TCP) load
>> balancer. In that case, the standard DNS resolver would resolve to a single
>> IP address (that of the load balancer) and then only maintain a single
>> connection. This would result in very poor load balancing since 100% of
>> that client's requests would all route to the same backend. This would also
>> happen when using standard Kubernetes services (when using gRPC for
>> server-to-serve communication), as kubedns resolves a service name into a
>> single virtual IP. I'm not sure if the current state of the world regarding
>> TCP load balancers and the grpc-go project, but if it's still an issue and
>> you run services in Kubernetes, you can use a 3rd party resolver:
>> https://github.com/sercand/kuberesolver.
>>
>> 
>> *Josh Humphries*
>> jh...@bluegosling.com
>>
>>
>> On Wed, Oct 17, 2018 at 2:13 AM  wrote:
>>
>>> Hello,
>>>
>>> I intend to use grpc between two fixed endpoints (client and server)
>>> where the client receives multiple requests (the client serves as a proxy)
>>> which in turn sends a grpc request to the server. I wanted to know of the
>>> following would be considered good practice:
>>>
>>> a) For every request that comes in at the client, do the following in
>>> the http handler:
>>>a) c

Re: [go-nuts] go-grpc question

2018-10-17 Thread Josh Humphries
*+grpc...@googlegroups.com *

*moving golang-nuts@googlegroups.com  to BCC*

In general, connections are not cheap, but stubs are. Actual
implementations for some languages differ, but Go complies with this.

What that means is that, generally speaking, you should not try creating
the *grpc.ClientConn for each request. Instead create it once and cache it.
You *can* create the stub just once and cache it (they are safe to use
concurrently form multiple goroutines). But that is not necessary; you
could also create the stub for each request, using the cached connection.

In practice, creating a new connection for each request will have overhead
in terms of allocations, creating and tearing down goroutines, and also in
terms of latency, to establish a new network connection every time. So it
is advisable to cache and re-use them. However, if you are not using TLS,
it *may be* acceptable to create a new connection per request (since the
network connection latency is often low, at least if the client and server
are in the same region/cloud provider). If you are using TLS, however,
creating a connection per request is a bit of an atrocity: you are not only
adding the extra latency of a TLS handshake to every request (typically 10s
of milliseconds IIRC), but you are also inducing a potentially huge amount
of load on the server, by making it perform many more digital signatures
(one of the handshake steps) than if the clients cached and re-used
connections.

Historically, the only reason it might be useful to create a new connection
per request in Go was if you were using a layer-4(TCP) load balancer. In
that case, the standard DNS resolver would resolve to a single IP address
(that of the load balancer) and then only maintain a single connection.
This would result in very poor load balancing since 100% of that client's
requests would all route to the same backend. This would also happen when
using standard Kubernetes services (when using gRPC for server-to-serve
communication), as kubedns resolves a service name into a single virtual
IP. I'm not sure if the current state of the world regarding TCP load
balancers and the grpc-go project, but if it's still an issue and you run
services in Kubernetes, you can use a 3rd party resolver:
https://github.com/sercand/kuberesolver.


*Josh Humphries*
jh...@bluegosling.com


On Wed, Oct 17, 2018 at 2:13 AM  wrote:

> Hello,
>
> I intend to use grpc between two fixed endpoints (client and server) where
> the client receives multiple requests (the client serves as a proxy) which
> in turn sends a grpc request to the server. I wanted to know of the
> following would be considered good practice:
>
> a) For every request that comes in at the client, do the following in the
> http handler:
>a) conn := grpc.Dial(...)// establish a grpc connection
>b) client := NewClient(conn)// instantiate a new client
>c) client.Something(..) // invoke the grpc method on
> the client
>
> i.e Establish a new connection and client in handling every request
>
> b) Establish a single grpc connection between client and server at init()
> time and then inside the handler, instantiate a new client and invoke the
> grpc method
>a) client := NewClient(conn)// instantiate a new client
>b) client.Something(..) // invoke the grpc method on
> the client
>
> c) Establish a connection and instantiate a client at init() and then in
> every handler, just invoke the grpc method.
>a) client.Something(..)
>
> The emphasis here is on performance as I expect the the client to process
> a large volume of requests coming in. I do know that grpc underneath
> creates streams but at the end of the day a single
> logical grpc connection runs on a single TCP connection (multiplexing the
> streams) on it and having just one connection for all clients might not cut
> it. Thoughts and ideas appreciated !
>
> Thanks,
> Nakul
>
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [go-nuts] golang gRPC question

2018-09-12 Thread Josh Humphries
On Wed, Sep 12, 2018 at 9:05 AM robert engels  wrote:

> Hi, I am adding a remote component to my github.com/robaho/keydb project
> and decided to use gRPC.
>
> I’ve reviewed the docs, and it appears to want to be stateless - which
> given the nature of Google makes sense.
>
> But for something like a database connection, where there could be
> substantial connection setup costs that you wouldn’t want to pay on every
> request, what is the best way to accomplish this with gRPC?
>
> There are issues like https://github.com/grpc/grpc-go/issues/297 that are
> closed with no resolution ???
>
> There doesn’t seem to be a way to access the connection state on the
> server - to know the associated user, register a close handler, etc.
>
> The only solutions I see is are
>
> 1) that the client must send heartbeat message, if the server doesn’t
> receive a heartbeat in X, clean-up the connection, AND the client must send
> a connectionID along with every request (but even this seems problematic
> for security reasons).
>
> 2) use the bidirectional streaming mode, and so the connection is treated
> as one long stream of messages in and out, and when the rpc finishes the
> connection is cleaned up
>

I think you want this mechanism -- the stream. Since gRPC clients assume
statelessness, approach #1 will not only need some keep-alive mechanism,
but it also requires "smart" routing/affinity, so that all requests for the
same "connection ID" get routed on the same socket. Otherwise, you will not
be able to do any sort load balancing, since different requests can be
scattered to different backends. With a single stream, all messages sent on
the stream will be destined for the same backend. For an example of a bidi
streaming RPC call that sends/receives sequential request-response pairs on
its stream, checkout service reflection

.

On a separate note: I've actually started toying around with a library for
"tunneling" with gRPC. This library would provide helpers to wrap a
protoc-generated stream interface in a more user-friendly API, if you
choose to define a streaming endpoint similar to reflection. But it also
provides the ability to create a "tunnel" from client to server that acts
like a normal gRPC connection but guarantees that all requests are always
routed to the same server (basically, gRPC-over-gRPC). It will even support
"reverse tunnels", where a gRPC server can act as a client to invoke
services exposed by the gRPC client. If any of that is interesting to you,
let me know, and I can share some in-progress code with you.


>
> Is there an example of this type of usage someone can point me to?
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [go-nuts] tests for variadic functions

2018-05-23 Thread Josh Humphries
The syntax you are looking for is:

   max(test.vals...)

The ellipsis indicates that the var args are the *contents* of the slice,
as opposed to trying to pass the slice as if it were just a single element
of the var args.


*Josh Humphries*
jh...@bluegosling.com

On Wed, May 23, 2018 at 7:09 PM, Alex Dvoretskiy <advoretski...@gmail.com>
wrote:

> How do you write test for variadic functions?
>
> For example I have function:
>
> func max(vals ...int) int {
> m := 0
> for _, v := range vals {
> if v > m {
> m = v
> }
> return m
> }
>
>
> and how to write a few tests for it? I can't put vals ...int
> in struct
>
>
> package main
>
> import (
> "testing"
> )
>
> func TestMax(t *testing.T) {
> var tests = []struct {
> vals ...int
> want int
> }{
> {[]int{1,2,3}, 3},
> {[]int{-1,0}, -1},
> {[]int{0}, 0},
> }
>
> for _, test := range tests {
> if got := max(test.vals); got !=test.want {
> t.Errorf("max(%d) = %d", test.vals, got)
> }
> }
>
> }
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [go-nuts] Appreciating Go

2018-02-22 Thread Josh Humphries
On Thu, Feb 22, 2018 at 4:56 AM, Steven Hartland 
wrote:

> On 22/02/2018 09:46, andrewchambe...@gmail.com wrote:
>
> Just a list of things I like about Go, thanks everyone for the hard work:
>
> snip...
>
> Minor things that could be improved in order of importance:
>
> - Ways to express immutability ... as a concurrent language it can still
> be easy to make mistakes and share a buffer or slice by accident.
> - More advanced static analysis tools that can prove properties of your
> code (perhaps linked with the above).
>
> Have you seen: https://github.com/alecthomas/gometalinter
>
> - Generics.
> - Some sort of slightly more sophisticated pattern matching .
>
> Not sure what you mean here but have you seen:
> https://golang.org/pkg/regexp/
>

I'm pretty sure Andrew was referring to pattern matching like in Scala and
Rust. It's a very slick feature. Related: Rust's enum types are slick --
they are like a combination of enums (such as in Java, and Scala) and
Scala's sealed classes.
https://docs.scala-lang.org/tour/pattern-matching.html
https://doc.rust-lang.org/1.6.0/book/match.html


>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [go-nuts] “Design Patterns: Elements of Reusable Object-Oriented Software” in Go

2018-02-08 Thread Josh Humphries
On Thu, Feb 8, 2018 at 12:17 AM, Rob Pike <r...@golang.org> wrote:

> Isn't the visitor pattern just a way to implement type switch in languages
> that don't implement type switch?
>
> That's certainly how I saw it when using C++. Go has a type switch, and so
> has no need for the visitor pattern, a perfect example of the principle
> that a design pattern is just a way to work around shortcomings in the
> language.
>

That is likely the origin of the visitor pattern, but that is not its only
use. JVM languages can switch on type, yet visitors are still prevalent in
several libraries there. The value above-and-beyond a type switch only
applies to OO languages (i.e. class-based inheritance):
re-using/specializing code by sub-classing a visitor implementation and
only overriding/decorating subset of methods.

Also, visitor patterns are sometimes used to abstract away the mechanics of
the tree traversal, too (such as in the "go/ast" package's Walk function).

And they can provide API symmetry for code that both consumes and produces
a data structure. So you implement the visitor to consume; you accept a
visitor and invoke its methods to produce. (For example, the ASM
<http://download.forge.objectweb.org/asm/asm4-guide.pdf> library for Java.)


>
> -rob
>
>
> On Thu, Feb 8, 2018 at 2:14 PM, Josh Humphries <jh...@bluegosling.com>
> wrote:
>
>> FWIW, it looks like someone else has gone through this exercise:
>> https://github.com/tmrts/go-patterns
>>
>> 
>> *Josh Humphries*
>> jh...@bluegosling.com
>>
>> On Fri, Feb 2, 2018 at 12:03 PM, <matthewju...@gmail.com> wrote:
>>
>>> I’m looking at patterns summarized on Wikipedia from “Design Patterns:
>>> Elements of Reusable Object-Oriented Software” and writing out a few as the
>>> equivalent in Go.
>>>
>>> Visitor: https://play.golang.org/p/A5tNzxMmetH
>>>
>>> Abstract Factory: https://play.golang.org/p/SWwuX49eysd
>>>
>>> Factory Method: https://play.golang.org/p/FRgDBx2CLFf
>>>
>>> Facade: https://play.golang.org/p/forPdwy9VCi
>>>
>>> Proxy: https://play.golang.org/p/DFWuDPTOzEP
>>>
>>> I’m curious how more experienced people rank these and the other
>>> patterns.
>>>
>>> Matt
>>>
>>> --
>>> You received this message because you are subscribed to the Google
>>> Groups "golang-nuts" group.
>>> To unsubscribe from this group and stop receiving emails from it, send
>>> an email to golang-nuts+unsubscr...@googlegroups.com.
>>> For more options, visit https://groups.google.com/d/optout.
>>>
>>
>> --
>> You received this message because you are subscribed to the Google Groups
>> "golang-nuts" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to golang-nuts+unsubscr...@googlegroups.com.
>> For more options, visit https://groups.google.com/d/optout.
>>
>
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [go-nuts] Re: “Design Patterns: Elements of Reusable Object-Oriented Software” in Go

2018-02-08 Thread Josh Humphries
On Wed, Feb 7, 2018 at 5:45 PM, roger peppe  wrote:

> As someone totally unfamiliar with the GoF patterns, hre's my take.
> I looked at the wikipedia articles and tried to work out what
> problem I thought the pattern was trying to address and then
> wrote some Go code to do that. I'm generally in agreement
> with those who say that these patterns are there largely to avoid
> the pitfalls of languages with class-based inheritance.
>

Some are targeted specifically at C++/Java -- not due to class-based
inheritance but to language/syntax limitations. For example the builder
pattern is meant to make construction of objects more readable than
overloaded constructors/factories with telescoping argument lists. Go has
less need for this because of its struct literal syntax. And, for structs
that need stronger encapsulation (private fields, enforce invariants at
construction time), Go has its own pattern: the functional option pattern
.

They certainly aren't all there to avoid pitfalls of class-based
inheritance. Many are intuitive solutions to certain classes of problems:
one could easily write code that adheres to one of these patterns without
even realizing it (adapters, facades, decorators, interceptors, commands,
strategies, flyweights, iterators, observers, DSLs). Admittedly, some are
less powerful/expressive without class-based inheritance, so less
applicable to Go. But, as alluded to in the previous paragraph, Go has some
of its own patterns.


> abstract factory https://play.golang.org/p/syHr7QJ9e2q
> - anything in Go that returns an interface rather than a concrete type
> could be considered an abstract factory.
>

This isn't quite right. Your example is just a parameterized factory
method. This pattern is about the factory itself being abstract. Here's a
re-worked example: https://play.golang.org/p/joSYzhMeS0n
This pattern is a specialization of the strategy
 pattern.


>
> facade https://play.golang.org/p/U6DSg5pDC0w
> - any type that has another type as a member and not much
> significant logic in its own methods could be considered a facade.
>

And if that facade implements a particular interface then it is also an
example of the adapter 
pattern. More adapter examples: bytes.NewReader() and strings.NewReader().
They adapt []byte or string to the io.Reader interface.


>
> proxy https://golang.org/pkg/bufio/#NewReader
> - any Go function that takes an interface and returns a
> value that implements the same interface could be considered
> a proxy.
>

This describes the decorator pattern more than the proxy pattern. Usually,
a proxy isn't just a wrapper (like a decorator is) -- the proxy object is
some form of stand-in for some other resource, typically remote. RPC is a
much better example of the proxy pattern (like the "net/rpc" package, but
also things like gRPC). Sometimes proxies also add functionality (like the
decorator pattern), translate protocols (a la the adapter pattern), or
perform routing/multiplexing/demultiplexing.

Another related pattern is the interceptor pattern (aka
chain-of-responsibility
).


>
> factory method: https://play.golang.org/p/AmQ7lQHAPDy
> - any function or method that creates and returns an object could
> be considered a factory. Go doesn't have constructors so this
> is just normal.
>
>
This statement describes "factory method", but is not at all what the
factory method pattern is about. This pattern is specific to class-based
inheritance. The idea is to create a virtual/abstract factory method that
sub-classes override to return different sub-types/implementations.

Since Go does not have class-based inheritance, the closest I could
envision is "override" behavior via a function field. Here's a take on it
based on the example in the wikipedia page
:
https://play.golang.org/p/EnZ4sRFdmyT



> visitor: https://play.golang.org/p/w74EhhuAhT5
> - I'm not sure that this is a great pattern. Doing a callback for every
> object in a hierarchy seems fine, but requiring a different method
> to be implemented for each kind of object seems unnecessary - if
> you add another kind of object, then all the code using the visitor
> will break (but that could also be considered an advantage, I guess,
> as it means your clients are forced to consider all possible kinds).
>

This one also is more suited to class-based inheritance as there is usually
a base class implementation that has a no-op implementation for all
callbacks. That way, the code implementing the visitor is not broken
whenever a new method is added to the visitor. (In Go, you could embed a
no-op visitor, so that you only need to implement the subset of applicable
methods.) For what it's worth, adding other kinds of 

Re: [go-nuts] “Design Patterns: Elements of Reusable Object-Oriented Software” in Go

2018-02-07 Thread Josh Humphries
FWIW, it looks like someone else has gone through this exercise:
https://github.com/tmrts/go-patterns


*Josh Humphries*
jh...@bluegosling.com

On Fri, Feb 2, 2018 at 12:03 PM, <matthewju...@gmail.com> wrote:

> I’m looking at patterns summarized on Wikipedia from “Design Patterns:
> Elements of Reusable Object-Oriented Software” and writing out a few as the
> equivalent in Go.
>
> Visitor: https://play.golang.org/p/A5tNzxMmetH
>
> Abstract Factory: https://play.golang.org/p/SWwuX49eysd
>
> Factory Method: https://play.golang.org/p/FRgDBx2CLFf
>
> Facade: https://play.golang.org/p/forPdwy9VCi
>
> Proxy: https://play.golang.org/p/DFWuDPTOzEP
>
> I’m curious how more experienced people rank these and the other patterns.
>
> Matt
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [go-nuts] “Design Patterns: Elements of Reusable Object-Oriented Software” in Go

2018-02-02 Thread Josh Humphries
I didn't get a chance to look at all of them, but your Proxy pattern
example is incorrect.

The idea of a proxy is that the proxy object exposes the same interface as
the underlying object, so they are substitutable.

In your example, Car is concrete (meaning that callers cannot substitute
any other type in its place). Also, the signature of the operation on Car
differs from the one on the Proxy that is meant to wrap it. Here's a fixed
version: https://play.golang.org/p/gq6Koi8f6XC

I'll also pointed out that the example code -- which I see is
transliterated from the code snippets in Wikipedia -- likes more like its a
related pattern: the decorator (sometimes known as the interceptor pattern).


*Josh Humphries*
jh...@bluegosling.com

On Fri, Feb 2, 2018 at 12:03 PM, <matthewju...@gmail.com> wrote:

> I’m looking at patterns summarized on Wikipedia from “Design Patterns:
> Elements of Reusable Object-Oriented Software” and writing out a few as the
> equivalent in Go.
>
> Visitor: https://play.golang.org/p/A5tNzxMmetH
>
> Abstract Factory: https://play.golang.org/p/SWwuX49eysd
>
> Factory Method: https://play.golang.org/p/FRgDBx2CLFf
>
> Facade: https://play.golang.org/p/forPdwy9VCi
>
> Proxy: https://play.golang.org/p/DFWuDPTOzEP
>
> I’m curious how more experienced people rank these and the other patterns.
>
> Matt
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [go-nuts] Deploying protobuf code on AppEngine standard

2018-02-01 Thread Josh Humphries
If the external packages can be located via your GOPATH, then `gcloud app
deploy` should also be able to find the code and compile+deploy the app.
You could also vendor the external packages (so they appear under a
"vendor" folder in the same directory as your app's entry point and the
rest of your code).

----
*Josh Humphries*
jh...@bluegosling.com

On Thu, Feb 1, 2018 at 6:31 AM, s2gatev <m...@s2gatev.com> wrote:

> Hey there!
>
> I'm trying to convert an AppEngine flexible setup to standard environment.
> I hit a problem with a piece of code that depends on some protobuf
> definitions.
> The problem is that the protobuf definitions import some external packages:
>
> import google_protobuf "github.com/golang/protobuf/ptypes/timestamp"
> import google_protobuf1 "github.com/golang/protobuf/ptypes/any"
>
> I'm not sure how to package my code (and if its possible at all) in order
> to deploy it on the standard environment.
> If anybody has experience with such deployments and is willing to provide
> an advice I'd greatly appreciate it!
>
> Best,
> Stanislav
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [go-nuts] Re: JSON and Embedded Types (Aliases)

2018-01-23 Thread Josh Humphries
Roger,
I don't believe that patch will change behavior. See my last message: the
fields appear to be unexported according to reflection.

That patch has the encoding/json package checking StructField.PkgPath,
which should be blank for exported fields. For these fields, it is
"go.builtin", which appears to be a pseudo-package name for builtins
(interestingly, it's not just "builtin" which is what Go doc would lead one
to expect). That means it will behave the same and skip the three fields in
question.

 This is non-intuitive based on the language spec, since the field names
are upper-cased. I think this is either a bug in reflect -- which should
set StructField.PkgPath to "" since the field name is exported -- OR a bug
in the compiler which should complain that there are three fields whose
resolved name appears to be the unexported identifier "int".




Josh Humphries

FullStory <https://www.fullstory.com/>  |  Atlanta, GA

Software Engineer

j...@fullstory.com

On Tue, Jan 23, 2018 at 3:44 AM, roger peppe <rogpe...@gmail.com> wrote:

> This is a bug that has been fixed on Go tip by
> https://go-review.googlesource.com/c/go/+/65550.
>
>
> On 23 January 2018 at 00:45, Josh Humphries <jh...@bluegosling.com> wrote:
> > I think have misspoken. Even though the field's name appears exported via
> > reflection (it has a name that starts with a capital letter), attempting
> to
> > use the reflect.Value's SetInt method panics, indicating that the field
> was
> > obtained using an unexported field. So the encoding/json package is thus
> > consistent with that in that it ignores unexported fields.
> >
> > It is still not obvious from the spec what should be happening. I would
> > expect it to be exported due to the resolved field name. But if it is
> > unexported because the compiler resolves the alias first, then I would
> > expect a compiler error because the four fields all resolve to the same
> > name. The spec states this is not allowed:
> >
> > The following declaration is illegal because field names must be unique
> in a
> > struct type:
> >
> > struct {
> >   T // conflicts with embedded field *T and *P.T
> >   *T// conflicts with embedded field T and *P.T
> >   *P.T  // conflicts with embedded field T and *T
> > }
> >
> > So it is possible that this is not a bug in the encoding/json package
> but in
> > the compiler.
> >
> > 
> > Josh Humphries
> > jh...@bluegosling.com
> >
> > On Mon, Jan 22, 2018 at 7:28 PM, Josh Humphries <jh...@bluegosling.com>
> > wrote:
> >>
> >> I think that is expected, and it is the JSON marshaling that is
> surprising
> >> (and erroneous).
> >>
> >> If it were expected that the embed field names resolved to the alias
> >> target type name, it would instead be a compiler error since the
> compiler
> >> does not allow embedded types that would result in name collisions.
> Using
> >> reflection, one can see the fields are named just as in your example,
> after
> >> the type aliases, not its underlying type name. The bug is that JSON
> >> marshaling is not looking at the field name and instead looking
> directly at
> >> the field type name (which, in this case, has been resolved to int).
> >>
> >> 
> >> Josh Humphries
> >> jh...@bluegosling.com
> >>
> >> On Mon, Jan 22, 2018 at 5:58 PM, Dan Kortschak
> >> <dan.kortsc...@adelaide.edu.au> wrote:
> >>>
> >>> This is sort of surprising though: https://play.golang.org/p/
> mjfkzIqAo_b
> >>>
> >>> On Mon, 2018-01-22 at 10:20 -0800, C Banning wrote:
> >>> > From the Language Specification -
> >>> >
> >>> > A field declared with a type but no explicit field name is called an
> >>> > *embedded
> >>> > field*. An embedded field must be specified as a type name T or as a
> >>> > pointer to a non-interface type name *T, and T itself may not be a
> >>> > pointer
> >>> > type. The unqualified type name acts as the field name.
> >>> >
> >>> > // A struct with four embedded fields of types T1, *T2, P.T3 and
> >>> > *P.T4
> >>> > struct {
> >>> > T1// field name is T1
> >>> > *T2   // field name is T2
> >>> > P.T3  // field name is T3
> >>> > *P.T4 // field name is T4
> >>> > x, y int  // field names are x and 

Re: [go-nuts] Re: JSON and Embedded Types (Aliases)

2018-01-22 Thread Josh Humphries
I think have misspoken. Even though the field's name appears exported via
reflection (it has a name that starts with a capital letter), attempting to
use the reflect.Value's SetInt method panics, indicating that the field was
obtained using an unexported field. So the encoding/json package is thus
consistent with that in that it ignores unexported fields.

It is still not obvious from the spec what should be happening. I would
expect it to be exported due to the resolved field name. But if it is
unexported because the compiler resolves the alias first, then I would
expect a compiler error because the four fields all resolve to the same
name. The spec <https://golang.org/ref/spec#Struct_types> states this is
not allowed:

The following declaration is illegal because field names must be unique in
a struct type:

struct {
T // conflicts with embedded field *T and *P.T
*T// conflicts with embedded field T and *P.T
*P.T  // conflicts with embedded field T and *T
}

So it is possible that this is not a bug in the encoding/json package but
in the compiler.


*Josh Humphries*
jh...@bluegosling.com

On Mon, Jan 22, 2018 at 7:28 PM, Josh Humphries <jh...@bluegosling.com>
wrote:

> I think that is expected, and it is the JSON marshaling that is surprising
> (and erroneous).
>
> If it were expected that the embed field names resolved to the alias *target
> type* name, it would instead be a compiler error since the compiler does
> not allow embedded types that would result in name collisions. Using
> reflection, one can see the fields are named just as in your example, after
> the type aliases, not its underlying type name. The bug is that JSON
> marshaling is not looking at the field name and instead looking directly at
> the field type name (which, in this case, has been resolved to int).
>
> 
> *Josh Humphries*
> jh...@bluegosling.com
>
> On Mon, Jan 22, 2018 at 5:58 PM, Dan Kortschak <
> dan.kortsc...@adelaide.edu.au> wrote:
>
>> This is sort of surprising though: https://play.golang.org/p/mjfkzIqAo_b
>>
>> On Mon, 2018-01-22 at 10:20 -0800, C Banning wrote:
>> > From the Language Specification -
>> >
>> > A field declared with a type but no explicit field name is called an
>> > *embedded
>> > field*. An embedded field must be specified as a type name T or as a
>> > pointer to a non-interface type name *T, and T itself may not be a
>> > pointer
>> > type. The unqualified type name acts as the field name.
>> >
>> > // A struct with four embedded fields of types T1, *T2, P.T3 and
>> > *P.T4
>> > struct {
>> > T1// field name is T1
>> > *T2   // field name is T2
>> > P.T3  // field name is T3
>> > *P.T4 // field name is T4
>> > x, y int  // field names are x and y
>> > }
>> >
>> >
>> > From the encoding/json#Marshal documentation -
>> >
>> > Struct values encode as JSON objects. Each exported struct field
>> > becomes a
>> > member of the object, using the field name as the object key, unless
>> > the
>> > field is omitted for one of the reasons given below.
>> >
>>
>> --
>> You received this message because you are subscribed to the Google Groups
>> "golang-nuts" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to golang-nuts+unsubscr...@googlegroups.com.
>> For more options, visit https://groups.google.com/d/optout.
>>
>
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [go-nuts] Re: JSON and Embedded Types (Aliases)

2018-01-22 Thread Josh Humphries
I think that is expected, and it is the JSON marshaling that is surprising
(and erroneous).

If it were expected that the embed field names resolved to the alias *target
type* name, it would instead be a compiler error since the compiler does
not allow embedded types that would result in name collisions. Using
reflection, one can see the fields are named just as in your example, after
the type aliases, not its underlying type name. The bug is that JSON
marshaling is not looking at the field name and instead looking directly at
the field type name (which, in this case, has been resolved to int).


*Josh Humphries*
jh...@bluegosling.com

On Mon, Jan 22, 2018 at 5:58 PM, Dan Kortschak <
dan.kortsc...@adelaide.edu.au> wrote:

> This is sort of surprising though: https://play.golang.org/p/mjfkzIqAo_b
>
> On Mon, 2018-01-22 at 10:20 -0800, C Banning wrote:
> > From the Language Specification -
> >
> > A field declared with a type but no explicit field name is called an
> > *embedded
> > field*. An embedded field must be specified as a type name T or as a
> > pointer to a non-interface type name *T, and T itself may not be a
> > pointer
> > type. The unqualified type name acts as the field name.
> >
> > // A struct with four embedded fields of types T1, *T2, P.T3 and
> > *P.T4
> > struct {
> > T1// field name is T1
> > *T2   // field name is T2
> > P.T3  // field name is T3
> > *P.T4 // field name is T4
> > x, y int  // field names are x and y
> > }
> >
> >
> > From the encoding/json#Marshal documentation -
> >
> > Struct values encode as JSON objects. Each exported struct field
> > becomes a
> > member of the object, using the field name as the object key, unless
> > the
> > field is omitted for one of the reasons given below.
> >
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [go-nuts] Re: JSON and Embedded Types (Aliases)

2018-01-22 Thread Josh Humphries
I'm not trying to suggest that the example code makes sense or is something
that one *should* do.

But it is surprising behavior that is not expected, even after reading
relevant parts of the language spec and the reflect and json package docs.

It looks like this is a bug in the json package. When it encounters an
anonymous field, it looks directly at the name of the field's type, instead
of the name of the field itself, to decide whether the field is exported or
not:
https://golang.org/src/encoding/json/encode.go?s=6456:6499#L1097
In this case, the StructField's indicate exported names (based on the type
alias names), but the field's type is simply int (which is not exported due
to starting with lower-case letter).




*Josh Humphries*
jh...@bluegosling.com

On Mon, Jan 22, 2018 at 3:12 AM, 'Axel Wagner' via golang-nuts <
golang-nuts@googlegroups.com> wrote:

> On Mon, Jan 22, 2018 at 8:50 AM, dc0d <kaveh.shahbaz...@gmail.com> wrote:
>
>> Then the main question would be why is it possible to embed type aliases?
>>
>
> Because it is possible to embed types and an alias is simply another name
> for a type.
>
> For example, embedding an x/image/draw.Image
> <https://godoc.org/golang.org/x/image/draw#Image> makes 100% complete
> sense: It allows your type to be used as an Image itself, while adding or
> overwriting some methods. And the alias makes x/image/draw a drop-in
> replacement for image/draw, so you can use your embedding type also in
> functions that expect an image/draw. Also note, that even with unexported
> embedded types, you are *still* promoting fields and methods
> <https://play.golang.org/p/k-223vmcfNJ>.
>
> In the end, the issue here boils down to: Aliases are a purely
> compile-time feature. type Foo = Bar will *by definition* not introduce a
> new actual type, but just an identifier to refer to the same type - that's
> the point. Given that encoding/json works with reflection, so uses runtime
> type information, it can't possibly know about your alias and will have to
> assume you are embedding an int instead. And note, that embedding an int was
> always possible <https://play.golang.org/p/70jzEBzq5Ov> - but always
> sorta pointless. But why explicitly disallow it? If it ain't broke don't
> fix it.
>
> Why are you even using aliases in your example? It would seem that those
> things either shouldn't have a name at all (and instead be field names) or
> they should be actual types. Probably the former.
>
>
>>
>>
>> On Sunday, January 21, 2018 at 10:42:28 PM UTC+3:30, Kevin Malachowski
>> wrote:
>>>
>>> Given the last playground post, I'd guess that the aliased type (i.e.
>>> 'int' here) is being used for visibility rather than the alias's new name.
>>>
>>> It's also a little weird to use embedded types that dont need to be
>>> (there's no method promotion here because 'int' has no methods), or seeing
>>> aliases to primitive types. Do you need to do both of those things?
>>>
>> --
>> You received this message because you are subscribed to the Google Groups
>> "golang-nuts" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to golang-nuts+unsubscr...@googlegroups.com.
>> For more options, visit https://groups.google.com/d/optout.
>>
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [go-nuts] Mixed type array in Go

2018-01-04 Thread Josh Humphries
You would typically define the array type as an array of some interface
that is implemented by both purchase and coupon. You can then use a
type-switch or type-assertion to determine/assert the actual type at
runtime, on a per element basis.

If the two types do not share some interface (e.g. common methods), you
could define the array as []interface{}. But this also allows code to
accidentally add *any* kind of value to the array (not just a purchase or a
coupon). So it may be better to create a marker interface -- an unexported
interface with a no-op unexported marker method -- and make purchase and
coupon both implement that interface.


For example:

type checkoutObject interface {
  checkoutObject()
}

type Purchase struct {
// yadda yadda
}

func (p *Purchase) checkoutObject() {
// no-op marker method
}


type Coupon struct {
// yadda yadda
}

func (c *Coupon) checkoutObject() {
// no-op marker method
}

// assert that Purchase and Coupon implement checkoutObject
var _ checkObject = (*Purchase)(nil)
var _ checkObject = (*Coupon)(nil)


*// Now you can define your array like so:*
*var checkoutItems []checkoutObject*
*// The compiler will only let you add *Purchase and *Coupon*
*// values to the array.*

*// You can use the values at runtime like so:*
*for e := range checkoutItems {*
*switch e := e.(type) {*
*case *Purchase:*
*// handle purchase*
*case *Coupon:*
*// handle coupon*
*default:*
*panic(fmt.Sprintf("unsupported type: %T", e))*
*}*
*}*


----
*Josh Humphries*
jh...@bluegosling.com

On Thu, Jan 4, 2018 at 10:24 AM, Tong Sun <suntong...@gmail.com> wrote:

> I need a data struct / solution that I can store mixed data-types into an
> array. How to architect that?
>
>
> Details -- Consider the checkout point at the cashier, the checkout
> process receives the following string of instructions
>
>1. purchase
>2. coupon
>3. purchase
>4. purchase
>
> I want to store all the above request data into an array, so I don't lost
> the sequence how they arrive, which in turn requests the array element to
> be either purchase or coupon.
>
>
> How to make it happen? 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.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [go-nuts] How to get explicit receiver of a method through reflect?

2017-11-23 Thread Josh Humphries
If you knew the representation of the function, and how captured variables
were stored in this representation, you could use unsafe to reinterpret the
function value as a usable form (pointer, tuple, whatever) and de-reference
this data to read captured variable addresses. In the case you describe,
the receiver would be the only captured variable.

But this is a very bad idea for a couple of reasons:

   1. The Go language spec does not define the representation for a
   function. So if you discovered the representation, the code would not be
   portable to other Go compilers or even across versions of Go.
   2. It is not safe. You have to know apriori the number and types of
   closed variables for this to work. You would not be able to distinguish
   between functions that have the same signature, but with different sets of
   closed variables. So it could be possible you receive a function that does
   not capture a method receiver, and then your interpretation of whatever you
   read using unsafe will likely cause memory corruption and/or a program
   crash.




*Josh Humphries*
jh...@bluegosling.com

On Wed, Nov 22, 2017 at 8:46 PM, Hoping White <baihaop...@gmail.com> wrote:

> Thanks Josh. Yes, a single-method interface can do the job. I just want to
> know the unsafe way for curiosity. could you please explain more?
>
> 2017-11-22 22:12 GMT+08:00 Josh Humphries <jh...@bluegosling.com>:
>
>> The reflection package provides no way to do this. Even if it were
>> possible to do with unsafe (not even sure it is, but maybe?), it would be
>> brittle and tied to an undocumented representation of a function and its
>> captured variables.
>>
>> Instead, use a single-method interface. It's easy to create a factory
>> method that takes a function and adapts it to the interface. And then the
>> value can be used both to invoke the logic (by calling the one method of
>> the interface) and for inspecting its concrete type and value.
>>
>>
>> 
>> *Josh Humphries*
>> jh...@bluegosling.com
>>
>> On Wed, Nov 22, 2017 at 8:26 AM, Hoping White <baihaop...@gmail.com>
>> wrote:
>>
>>> Hi, all
>>>
>>> I known that method of a struct can be a function with explicit
>>> receiver, like this
>>>
>>> type Param struct {
>>> v int
>>> }
>>>
>>> func (this *Param) Call() {
>>> println(this.v)
>>> }
>>>
>>> p := {v:10}
>>> t := p.Call
>>> t()
>>>
>>> I wonder how can I get the receiver p from function t through
>>> reflect. Thanks all.
>>>
>>> --
>>> You received this message because you are subscribed to the Google
>>> Groups "golang-nuts" group.
>>> To unsubscribe from this group and stop receiving emails from it, send
>>> an email to golang-nuts+unsubscr...@googlegroups.com.
>>> For more options, visit https://groups.google.com/d/optout.
>>>
>>
>>
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [go-nuts] How to get explicit receiver of a method through reflect?

2017-11-22 Thread Josh Humphries
The reflection package provides no way to do this. Even if it were possible
to do with unsafe (not even sure it is, but maybe?), it would be brittle
and tied to an undocumented representation of a function and its captured
variables.

Instead, use a single-method interface. It's easy to create a factory
method that takes a function and adapts it to the interface. And then the
value can be used both to invoke the logic (by calling the one method of
the interface) and for inspecting its concrete type and value.



*Josh Humphries*
jh...@bluegosling.com

On Wed, Nov 22, 2017 at 8:26 AM, Hoping White <baihaop...@gmail.com> wrote:

> Hi, all
>
> I known that method of a struct can be a function with explicit receiver,
> like this
>
> type Param struct {
> v int
> }
>
> func (this *Param) Call() {
> println(this.v)
> }
>
> p := {v:10}
> t := p.Call
> t()
>
> I wonder how can I get the receiver p from function t through
> reflect. Thanks all.
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [go-nuts] Union types mindset

2017-11-20 Thread Josh Humphries
Hi, Paulo,
I think you're on the right track. The main thing to note is that the
IsInstruction method isn't that useful. A concrete implementation of
AsmEntry is an instruction if it implements the Instruction interface, so
you shouldn't need a separate method.

So the example you provided looks like you plan to do something like this
when visiting entries:

if entry.IsInstruction() {
ins := entry.(Instruction)
// do stuff with ins
}


But instead, use the dual-return form of type conversion:

if ins, ok := entry.(Instruction); ok {
  // do stuff with ins
}


So the interfaces are just for holding the shared methods that all concrete
types must implement. You don't need to add discriminator methods.

However, if you do want discriminator methods (useful for when a concrete
type *happens to *implement an interface, like if it has methods with
commonly overloaded/used signatures), you simply move the implementation
down to concrete types.

So instead of this, which you noted will note compile:

func (i Interface) IsInstruction() bool {
return true
}


You would have this in various places:

func (i *SomeConcreteInstruction) IsInstruction() bool {
return true
}

func (i *AnotherConcreteInstruction) IsInstruction() bool {
return true
}

// etc


I hope that makes sense. ASTs for languages typically use this same
pattern, so they are often reasonable examples to look at.

Here's the AST for the Go language: https://godoc.org/go/ast
It has interfaces for Node, Decl, and Expression, each implemented by the
various kinds of concrete AST nodes.

And here's another:
https://github.com/jhump/protoreflect/blob/50b1762cd8f6881d9e0e2f806b1275022695ceb9/desc/protoparse/ast.go#L29
It's an AST for protocol buffers, implemented in Go. It has interfaces for
node, terminalNode, and various kinds of declarations. It also uses type
assertions for unnamed package variables
<https://github.com/jhump/protoreflect/blob/50b1762cd8f6881d9e0e2f806b1275022695ceb9/desc/protoparse/ast.go#L75>
to ensure that the various concrete types implement the expected interfaces
(this is a common pattern in Go, to make sure any change to a concrete type
to make it *not* implement a particular interface result in a compile-time
error).





*Josh Humphries*
jh...@bluegosling.com

On Mon, Nov 20, 2017 at 4:27 PM, 'Paulo Matos' via golang-nuts <
golang-nuts@googlegroups.com> wrote:

> Hello,
>
> I am trying to write a simple assembler file parser. I just started
> developing in Go so I have the wrong mindset. I am keen to understand the
> best way to write something like this in Go.
>
> An assembler file at first glance is a list of instructions, directives
> and labels. I know there are some other things but for the purposes of the
> example, that's enough.
>
> So I have
>
> type AsmFile list.List
>
> The elements of the list are the problematic part. It's well... a union.
> I have read on this and I have seen suggested an interface approach, where
> you can then cast to the right type.
>
> The entries of the list above are AsmEntry
>
> type AsmEntry interface {
> IsInstruction() bool
> IsLabel() bool
> IsDirective() bool
> }
>
> The problem is that I start then with:
>
> type Label string
>
> func (Label) IsLabel() bool {
> return true
> }
>
> func (Label) IsInstruction() bool {
> return false
> }
>
> -- same for IsDirective
>
> but then an instruction should be an interface since there could be
> ArmInstruction, IntelInstruction, etc
>
> type Instruction interface {
> GetMnemonic() string
> GetArgsLen() int
> GetArg(int) string
> }
>
> func (Instruction) IsInstruction() bool {
> return true
> }
>
> but this doesn't actually work because the receiver cannot be an
> instruction. This already looks like I am going on the wrong path.
> Any suggestions on how to design something like this with Go?
>
> Kind regards,
>
>
> --
> Paulo Matos
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [go-nuts] Re: golang and http2

2017-11-15 Thread Josh Humphries
One serious potential issue is that the URL scheme is still "http" (or
"https") for both. With TLS, the client and server can negotiate an
on-the-wire protocol using ALPN. This allows client and server to decide on
HTTP 1.1 or http/2 based on what they support.

But over plain-text, there is no such protocol negotiation phase. So the
client must assume HTTP 1.1 (because not all servers yet support HTTP/2).
There is an upgrade mechanism, whereby a client can start an HTTP 1.1
request and include special headers to request upgrading to HTTP/2 on the
same connection (see the spec
<https://http2.github.io/http2-spec/#discover-http> for more details). (I
am not sure if Go HTTP servers actually support this update mechanism,
though.)

But without a protocol negotiation step or upgrade request, it is unsafe
for a client to assume HTTP/2. You have to know what you are doing, and
thus it requires you to be more explicit in both client and server code to
make it work.



*Josh Humphries*
jh...@bluegosling.com

On Wed, Nov 15, 2017 at 3:43 PM, Albert Tedja <nicho.te...@gmail.com> wrote:

> Thank you for the links.
>
> I am still somewhat disappointed that the http/2 protocol would enforce a
> certain configuration. I understand the necessity of secure connections,
> but that's should be left as an option to the developers.
>
> If browsers want to strictly use TLS, that's fine because it's consumer
> facing, but at least Go should enable http/2 over non-TLS. We are engineers
> here, we should know the difference.
>
>
>
> On Wednesday, November 15, 2017 at 12:05:41 PM UTC-8, Howard C. Shaw III
> wrote:
>>
>> See
>> https://github.com/golang/go/issues/14141 - for discussion of the issue;
>> and
>> https://github.com/hkwi/h2c for a way to use the in
>> stdlib-but-not-linked-together support for h2c (http/2 over non-TLS).
>>
>> Howard
>>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[go-nuts] type returned by reflect.ArrayOf breaks the spec

2017-11-06 Thread Josh Humphries
I think I've found a bug regarding reflect.ArrayOf. The go doc is a bit
light, but suggests that the resulting type is a proper array type.
However, I've found that the resulting type has a few flaws:


   1. The resulting array type violates part of the language spec about
   arrays: it cannot be used as a map key. Using an array whose type was
   created via reflect.ArrayOf as a key in a map results in a runtime panic:


*runtime error: hash of unhashable type [8]int32 *
   See the link below for an example program that shows this error.

   2. The resulting array type seems to violate the reflect package Go doc
   regarding reflect.Type and type equality. The package doc states this:


*Type values are comparable, such as with the == operator. Two Type
   values are equal if they represent identical types. *
   And the section about type identity in the language spec states this:

   *Two array types are identical if they have identical element types
   and the same array length.*

   However, an array type created using reflect.ArrayOf returns false when
   compared to an identical type that was *not* created using
   reflect.ArrayOf.

   The link below also shows an example of this erroneous behavior.

Demonstrations of these issues:
https://play.golang.org/p/Qu0irn2rCF

I am guessing I should just file a bug in a Github issue, but wanted to
first check to see if this, somehow, might be expected behavior. (And if
so, to learn why.)


*Josh Humphries*
jh...@bluegosling.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.
For more options, visit https://groups.google.com/d/optout.


Re: [go-nuts] Iota with string constants

2017-10-16 Thread Josh Humphries
Comparing values will be a lot cheaper with ints than strings. So if your
enum type is possibly used in hot loops, ints will be your friend. Also,
with ints, you can provide an ordering that differs from the lexical order
of the string values. For example, with an int, you can easily sort by
day-of-week by defining the constants in order. With strings, you have to
use a custom compare function that acts on string names (ick).


*Josh Humphries*
jh...@bluegosling.com

On Sun, Oct 15, 2017 at 4:13 PM, <m...@inanc.io> wrote:

> Is it anything wrong just assigning string values to get rid of String()
> method attaching?
>
> *Like this:*
>
> type Weekday string
>
> const (
>   Sunday Weekday = "Sunday"
>   Monday Weekday = "Monday"
> )
>
> func main() {
>   fmt.Println(Sunday)
> }
>
>
>
> *Instead of this:*
>
> type weekday uint
>
> const (
>   Sunday weekday = iota
>   Monday
> )
>
> var weekdayNames = [...]string{"Sunday", "Monday"}
>
> func (day weekday) String() string {
>   return weekdayNames[day]
> }
>
>
> func main() {
>   fmt.Println(Sunday)
> }
>
>
>
> 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.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [go-nuts] Converting type map[string]interface {} to type map[interface {}]interface {}

2017-08-21 Thread Josh Humphries
You can't convert between maps with different types of keys or values. So
you have to copy the map into one with the correct target type:

https://play.golang.org/p/qmD2pypNbj


*Josh Humphries*
jh...@bluegosling.com

On Mon, Aug 21, 2017 at 10:48 AM, Tong Sun <suntong...@gmail.com> wrote:

> Hi,
>
> How to converting type map[string]interface {} to type map[interface
> {}]interface {}?
>
> I got
>
> cannot convert m (type map[string]interface {}) to type map[interface 
> {}]interface {}
>
>
> but I don't know how to fix it.
>
> https://play.golang.org/p/VU4ND_6JU_
>
> please help. 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.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [go-nuts] Re: Is this bad concurrency?

2017-08-18 Thread Josh Humphries
There's not a way to terminate a goroutine. But you can create a context
with cancellation. Each goroutine would need to periodically check
context.Err() and exit on its own.

When you exit, you cancel the context. You could combine this with a
WaitGroup in order to not exit until all other goroutines have completed
(e.g. cancel the context and then await, provided you've added to the wait
group for each task and each one marks their work as done on completion).


*Josh Humphries*
jh...@bluegosling.com

On Fri, Aug 18, 2017 at 5:19 PM, <bill.war...@talentinc.com> wrote:

> Thanks to both for replying. Both pieces of advice cover the use case of
> waiting for all goroutines to complete before exiting. I have the opposite
> problem. I want to end all goroutines if I exit. Is there anything in the
> sync package for that?
>
>
> On Friday, August 18, 2017 at 2:40:39 PM UTC-4, Tamás Gulácsi wrote:
>>
>> See golang.org/x/sync/errgroup.WithContext.
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [go-nuts] atomic package pointer operations with maps and channels

2017-08-12 Thread Josh Humphries
On Fri, Aug 11, 2017 at 6:22 PM, Ian Lance Taylor <i...@golang.org> wrote:

> On Fri, Aug 11, 2017 at 2:51 PM, Josh Humphries <jh...@bluegosling.com>
> wrote:
> >
> > It is possible to extract a map's actual value/address if it is stored in
> > the heap -- by using something like this:
> >   atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer()))
> > However, it does not appear to possible to go the other direction, even
> if
> > using unsafe. Specifically, to take an unsafe.Pointer and somehow store
> it
> > in a variable whose type is a map.
>
> var m map[int]bool
> *(*unsafe.Pointer)(unsafe.Pointer()) = myMapPointer
>
>
Thanks! I had thought about something like that and dismissed it because I
thought it would spill m to the heap instead of stack allocating it. (But I
guess the compiler is probably smart enough to see that  never escapes,
so it could still be stack allocated?)

Even if it does a heap allocation, it's still strictly better than the
solution I mentioned below of using an intermediate struct pointer. So not
sure why I didn't thank of that. Thanks again.


> > My use case wants to be able to lazily compute the map, but then use
> > atomic.StoreX to safely set the field value for a struct that could be
> > accessed from multiple goroutines. (Readers would, of course, use
> > atomic.LoadX).
> >
> > But it doesn't look like this is possible. And I cannot use atomic.Value
> > because I need the structs to be copy-able. I can't copy a struct with
> > atomic.Value nested in it because it embeds the special noCopy type. (I
> know
> > the compiler will allow the copy, but I want to do this in a library and
> > don't want users of the library to see errors reported by "go vet" due to
> > copying this type.)
> >
> > My current solution is to add another pointer indirection -- so I stick
> the
> > map in a struct, and then I can use atomic.LoadPointer and
> > atomic.StorePointer to atomically change a pointer to that struct.
> >
> > But that seemed a little silly since. Though the language spec does not
> > describe maps as pointers, blog posts describe them as reference types
> and
> > the doc for reflect.Value.Pointer() implies that they are (same for
> > channels).
> >
> >
> > Is there a particular reason that casting a map (or chan) to
> unsafe.Pointer,
> > and vice versa, is disallowed? We're already using the unsafe package,
> so I
> > can't think of a clear reason to prevent this.
>
> From a language perspective, there is no reason to lock map and
> channel values into always being pointer values.
>
> 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.
For more options, visit https://groups.google.com/d/optout.


[go-nuts] atomic package pointer operations with maps and channels

2017-08-11 Thread Josh Humphries
It is possible to extract a map's actual value/address if it is stored in
the heap -- by using something like this:
  atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer()))
However, it does not appear to possible to go the other direction, even if
using unsafe. Specifically, to take an unsafe.Pointer and somehow store it
in a variable whose type is a map.

My use case wants to be able to lazily compute the map, but then use
atomic.StoreX to safely set the field value for a struct that could be
accessed from multiple goroutines. (Readers would, of course, use
atomic.LoadX).

But it doesn't look like this is possible. And I cannot use atomic.Value
because I need the structs to be copy-able. I can't copy a struct with
atomic.Value nested in it because it embeds the special noCopy type. (I
know the compiler will allow the copy, but I want to do this in a library
and don't want users of the library to see errors reported by "go vet" due
to copying this type.)

My current solution is to add another pointer indirection -- so I stick the
map in a struct, and then I can use atomic.LoadPointer and
atomic.StorePointer to atomically change a pointer to that struct.

But that seemed a little silly since. Though the language spec does not
describe maps as pointers, blog posts describe them as reference types and
the doc for reflect.Value.Pointer() implies that they are (same for
channels).


Is there a particular reason that casting a map (or chan) to
unsafe.Pointer, and vice versa, is disallowed? We're already using the
unsafe package, so I can't think of a clear reason to prevent this.

----
*Josh Humphries*
jh...@bluegosling.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.
For more options, visit https://groups.google.com/d/optout.


[go-nuts] chaining contexts, best practices question

2017-08-08 Thread Josh Humphries
I noticed the Go doc for context.Context includes the following snippet:

Do not store Contexts inside a struct type; instead, pass a Context
> explicitly to each function that needs it.


I think one potential reason for going against this advice is maintaining
context chain relationships in servers. In a server object, it seems
reasonable to provide a context when starting the server (which is valid
for the lifetime the server is serving) and the server to then store that
context in a struct. The reason it would be stored is that it could be used
to create child contexts when handling incoming data from the socket (or
whatever the server does).

The reason I would do this is two-fold:

   1. It is convenient and IMO elegant (particularly, but not exclusively,
   in test code) to be able to simply cancel a top-level context and have that
   respected throughout the chain, resulting in the server stopping and
   tearing itself down.
   2. It is a natural place for server-scoped contextual data. For example,
   we use a log library that allows log writer configuration to be stored in
   context. We could configure the log writer once for the server and have it
   then correctly applied to every action taken by the server, including
   request dispatches.

Does this seem like a reasonable approach, or are there other possibly
better practices for addressing these issues?

Obviously we must do things differently for HTTP and GRPC servers since
those libraries do not expose a way to provide a "parent context" for the
whole server. In those cases, we provide a method for registering HTTP
handlers that will wrap an incoming handler with one that decorates the
request context (for bullet #2 above; and we can use interceptors for
GRPC). For bullet #1, we have to implement our own cancellation propagation
-- like a goroutine that will stop the server(s) when the root context gets
cancelled.

I'm curious how others tackle these kinds of concerns.


*Josh Humphries*
jh...@bluegosling.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.
For more options, visit https://groups.google.com/d/optout.


Re: [go-nuts] Get a copy of reflect.Value's underlying value

2017-08-01 Thread Josh Humphries
On Tue, Aug 1, 2017 at 2:43 PM, roger peppe <rogpe...@gmail.com> wrote:

> On 1 August 2017 at 19:33, Josh Humphries <jh...@bluegosling.com> wrote:
> > On Tue, Aug 1, 2017 at 11:44 AM, roger peppe <rogpe...@gmail.com> wrote:
> >>
> >> On 1 August 2017 at 13:57, Josh Humphries <jh...@bluegosling.com>
> wrote:
> >> > Although that solution creates a heap-allocated tmp for every element
> in
> >> > the
> >> > slice. Using an interface, the value will be inlined instead of
> >> > heap-allocated if it fits without boxing (so most primitive types and
> >> > pointer types won't need heap allocation).
> >>
> >> As it happens, it's the other way round - the solution using Interface
> can
> >> make an allocation per element, but the solution using Value does not.
> >
> >
> > The solution using Value is calling reflect.New inside the loop. Why do
> you
> > say that it does not make an allocation per element?
>
> The code I posted doesn't call reflect.New inside the loop - perhaps
> you're looking at some different code? (for the record, I'm talking
> about line 45 of https://play.golang.org/p/Q0VHbfL7Ij)
>

Ah, I see. Thanks for the clarification. That makes sense to allocate just
one for the whole operation.


>
> > Also, I'm not sure I follow that using Interface makes an allocation per
> > element. My understanding is that the actual value can be stored in the
> > interface value if it is small enough (1 or 2 words?). So boxing
> primitives
> > and pointers should generally store the value in the interface tuple
> (which
> > itself is stack allocated) as opposed to allocating heap space for it and
> > storing a pointer.
>
> As I think was pointed out earlier in this thread, this has changed since
> Go 1. Only pointer values are stored in interface values now - non-pointer
> value (for example the ints in the example) will usually cause an
> allocation.
> There are some optimisations for some cases that avoid that: creation
> of an interface from a constant value, and creation of an interface from
> small numeric values.
>
>
Ugh. I did not realize that. I had not dug into it too much other than
reading a Go blog post and this article by Russ Cox
<https://research.swtch.com/interfaces> (which suggest this memory
optimization is done).

I am guessing the conditional that decides between inline value vs.
pointer-chasing was too much runtime overhead?


> Try running the benchmark code that I posted. I think you'll find
> that the code that calls Interface is slower and allocates more,
> because it has to allocate a storage slot every time it creates
> an interface from an int, which the solution using Value does not,
> because it allocates the temporary only once for a given call to Reverse
> (even that could be amortised by using sync.Pool, but it's almost
> certainly not worth it).
>
>   cheers,
> rog.
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [go-nuts] Get a copy of reflect.Value's underlying value

2017-08-01 Thread Josh Humphries
On Tue, Aug 1, 2017 at 11:44 AM, roger peppe <rogpe...@gmail.com> wrote:

> On 1 August 2017 at 13:57, Josh Humphries <jh...@bluegosling.com> wrote:
> > Although that solution creates a heap-allocated tmp for every element in
> the
> > slice. Using an interface, the value will be inlined instead of
> > heap-allocated if it fits without boxing (so most primitive types and
> > pointer types won't need heap allocation).
>
> As it happens, it's the other way round - the solution using Interface can
> make an allocation per element, but the solution using Value does not.
>

The solution using Value is calling reflect.New inside the loop. Why do you
say that it does not make an allocation per element?

Also, I'm not sure I follow that using Interface makes an allocation per
element. My understanding is that the actual value can be stored in the
interface value if it is small enough (1 or 2 words?). So boxing primitives
and pointers should generally store the value in the interface tuple (which
itself is stack allocated) as opposed to allocating heap space for it and
storing a pointer.

For larger types (e.g. structs beyond a certain size) it will indeed
allocate on the heap. I don't see any simple way around this. There may be
some clever tricks, possibly involving cgo or asm, to avoid it though
(maybe like how reflect.Swapper
<https://golang.org/src/reflect/swapper.go?s=337:383#L3> works, although it
also heap allocates for values >8 bytes).



>
> https://play.golang.org/p/Q0VHbfL7Ij
>
> Additionally, the solution using Interface can lose the type information
> in some cases and panic as a result.
>


A simple guard for the nil case is necessary to prevent the panic (since
the nil interface results in an invalid reflect.Value):

tmp := a.Interface()
var tmprv reflect.Value
if tmp == nil {
  tmprv = reflect.Zero(a.Type())
} else {
  tmprv = reflect.ValueOf(tmp)
}
a.Set(b)
b.Set(tmprv)


>
> https://play.golang.org/p/WocF9CaPoR
>
>   cheers,
> rog.
>
>
> >
> > 
> > Josh Humphries
> > jh...@bluegosling.com
> >
> > On Tue, Aug 1, 2017 at 7:29 AM, roger peppe <rogpe...@gmail.com> wrote:
> >>
> >> FWIW, you don't have to use Interface to do the swap:
> >>
> >> https://play.golang.org/p/O8lGJGGOXP
> >>
> >> On 31 July 2017 at 15:18, eZio Pan <eziopa...@gmail.com> wrote:
> >> > Hello,
> >> > I want to build a "universal slice reverser" with reflect.MakeFunc.
> But
> >> > I
> >> > don't know how to get a copy of reflect.Value's underlying value,
> which
> >> > make
> >> > result not correct.
> >> >
> >> > Here is the code:
> >> >
> >> > package main
> >> >
> >> > import (
> >> > "fmt"
> >> > "reflect"
> >> > )
> >> >
> >> > func reverse(in []reflect.Value) (out []reflect.Value) {
> >> > inls := in[0]
> >> > inlslen := inls.Len()
> >> >
> >> > for i, j := 0, inlslen-1; i < j; i, j = i+1, j-1 {
> >> > a := inls.Index(i)
> >> > b := inls.Index(j)
> >> > // how to get underlying value of a and b ?
> >> > a.Set(b)
> >> > b.Set(a)
> >> > }
> >> > return in
> >> > }
> >> >
> >> > var intFlipper func([]int) []int
> >> >
> >> > func main() {
> >> > emptyFunc := reflect.ValueOf().Elem()
> >> > pseudoFunc := reflect.MakeFunc(emptyFunc.Type(), reverse)
> >> > emptyFunc.Set(pseudoFunc)
> >> > fmt.Printf("%v\n", intFlipper([]int{2, 3, 4, 5, 6, 7}))
> >> > }
> >> >
> >> > My code return [7 6 5 5 6 7], but excepting result is [7 6 5 4 3 2]
> >> >
> >> > --
> >> > You received this message because you are subscribed to the Google
> >> > Groups
> >> > "golang-nuts" group.
> >> > To unsubscribe from this group and stop receiving emails from it, send
> >> > an
> >> > email to golang-nuts+unsubscr...@googlegroups.com.
> >> > For more options, visit https://groups.google.com/d/optout.
> >>
> >> --
> >> You received this message because you are subscribed to the Google
> Groups
> >> "golang-nuts" group.
> >> To unsubscribe from this group and stop receiving emails from it, send
> an
> >> email to golang-nuts+unsubscr...@googlegroups.com.
> >> For more options, visit https://groups.google.com/d/optout.
> >
> >
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [go-nuts] Get a copy of reflect.Value's underlying value

2017-08-01 Thread Josh Humphries
Although that solution creates a heap-allocated tmp for every element in
the slice. Using an interface, the value will be inlined instead of
heap-allocated if it fits without boxing (so most primitive types and
pointer types won't need heap allocation).


*Josh Humphries*
jh...@bluegosling.com

On Tue, Aug 1, 2017 at 7:29 AM, roger peppe <rogpe...@gmail.com> wrote:

> FWIW, you don't have to use Interface to do the swap:
>
> https://play.golang.org/p/O8lGJGGOXP
>
> On 31 July 2017 at 15:18, eZio Pan <eziopa...@gmail.com> wrote:
> > Hello,
> > I want to build a "universal slice reverser" with reflect.MakeFunc. But I
> > don't know how to get a copy of reflect.Value's underlying value, which
> make
> > result not correct.
> >
> > Here is the code:
> >
> > package main
> >
> > import (
> > "fmt"
> > "reflect"
> > )
> >
> > func reverse(in []reflect.Value) (out []reflect.Value) {
> > inls := in[0]
> > inlslen := inls.Len()
> >
> > for i, j := 0, inlslen-1; i < j; i, j = i+1, j-1 {
> > a := inls.Index(i)
> > b := inls.Index(j)
> > // how to get underlying value of a and b ?
> > a.Set(b)
> > b.Set(a)
> > }
> > return in
> > }
> >
> > var intFlipper func([]int) []int
> >
> > func main() {
> > emptyFunc := reflect.ValueOf().Elem()
> > pseudoFunc := reflect.MakeFunc(emptyFunc.Type(), reverse)
> > emptyFunc.Set(pseudoFunc)
> > fmt.Printf("%v\n", intFlipper([]int{2, 3, 4, 5, 6, 7}))
> > }
> >
> > My code return [7 6 5 5 6 7], but excepting result is [7 6 5 4 3 2]
> >
> > --
> > You received this message because you are subscribed to the Google Groups
> > "golang-nuts" group.
> > To unsubscribe from this group and stop receiving emails from it, send an
> > email to golang-nuts+unsubscr...@googlegroups.com.
> > For more options, visit https://groups.google.com/d/optout.
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [go-nuts] Get a copy of reflect.Value's underlying value

2017-07-31 Thread Josh Humphries
You have to use a temporary to swap the values:

tmp := a.Interface()
a.Set(b)
b.Set(reflect.ValueOf(tmp))



*Josh Humphries*
jh...@bluegosling.com

On Mon, Jul 31, 2017 at 10:18 AM, eZio Pan <eziopa...@gmail.com> wrote:

> Hello,
> I want to build a "universal slice reverser" with reflect.MakeFunc. But I
> don't know how to get a copy of reflect.Value's underlying value, which
> make result not correct.
>
> Here is the code:
>
> package main
>
> import (
> "fmt"
> "reflect"
> )
>
> func reverse(in []reflect.Value) (out []reflect.Value) {
> inls := in[0]
> inlslen := inls.Len()
>
> for i, j := 0, inlslen-1; i < j; i, j = i+1, j-1 {
> a := inls.Index(i)
> b := inls.Index(j)
> // how to get underlying value of a and b ?
> a.Set(b)
> b.Set(a)
> }
> return in
> }
>
> var intFlipper func([]int) []int
>
> func main() {
> emptyFunc := reflect.ValueOf().Elem()
> pseudoFunc := reflect.MakeFunc(emptyFunc.Type(), reverse)
> emptyFunc.Set(pseudoFunc)
> fmt.Printf("%v\n", intFlipper([]int{2, 3, 4, 5, 6, 7}))
> }
>
> My code return [7 6 5 5 6 7], but excepting result is [7 6 5 4 3 2]
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [go-nuts] Create methods for structs at runtime

2017-06-20 Thread Josh Humphries
This is a problem that is usually solved in Go with code generation. You
would use a go:generate directive to generate implementations for an
interface of interest.

Something like java.lang.reflect.Proxy in Go would be very cool though.


*Josh Humphries*
jh...@bluegosling.com

On Tue, Jun 20, 2017 at 5:03 PM, Dat Huynh <audathu...@gmail.com> wrote:

> Hi Ian,
>
> The struct instance I create for an interface will actually take the role
> of transport layer.
> I will not implement the real logic of the methods of the interface in
> client side.
> The real implementation for the logic of the methods will be implemented
> on the server side only.
>
> In the implementation of the methods for the struct instance, I write code
> to send interface name, method name and parameters to the server via my own
> protocol (e.g HTTP).
> Then it also receives and returns results to the place where we call
> methods.
>
> After we have such a library, we can use it with any interfaces and any
> methods, client side and server side will talk each other in our own
> protocol.
> You can encrypt data, compress data and do whatever with the data before
> you transfer it.
>
> Programers in client side just need to know which interface they want to
> use and they just  use the library "servicefactory" to create a struct
> instance and use it to talk to the server. Before that, they must specify
> the IP to tell where the server is.
>
> I have successfully implemented the idea in Java and used it in my system
> with hundreds of interfaces.
> I wonder why I cannot do it in Go easily as what I did with Java.
>
> Regards,
> Dat.
>
>
>
>
>
>
>
> On Wed, Jun 21, 2017 at 6:00 AM, Ian Lance Taylor <i...@golang.org> wrote:
>
>> On Mon, Jun 19, 2017 at 8:38 PM, Dat Huynh <audathu...@gmail.com> wrote:
>> >
>> > On Tuesday, June 20, 2017 at 4:07:46 AM UTC+10, Ian Lance Taylor wrote:
>> >>
>> >> On Sat, Jun 17, 2017 at 5:17 PM, Dat Huynh <audat...@gmail.com> wrote:
>> >> > Why do you need this feature?
>> >
>> >
>> > I have already answered the question in my email replying Lutz Horn.
>>
>> Thanks.  Unfortunately, I don't understand your answer.  You still
>> have to write the methods somewhere.  reflect.MakeStruct is not going
>> to write the methods for you.  And once you write the methods, you
>> have a type that implements the interface that you want.
>>
>> 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.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.