[go-nuts] Re: %T, type assertions and the Go spec

2017-06-19 Thread Will Hawkins
Thank you very much for your response!

I definitely understand what you are getting at, but I don't think that 
it's technically correct. For instance, 

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

seems to pretty clearly say that an interface is a type. 

Moreover, there is the possibility of "typing" a variable as an interface 
that has neither a dynamic type nor dynamic value:

var i interface{}

has the type interface{} and it's dynamic type and value are both nil.

That said, again, I agree with the sentiment of your statement and it is 
exactly the point that I was hoping to clarify with this conversation.

Thanks again for your response!
Will

On Tuesday, June 20, 2017 at 1:50:16 AM UTC-4, Tamás Gulácsi wrote:
>
> AFAIK an interface is not a type, just behavior, and a type may implement 
> an interface, so each variable will have a concrete type.
> An variable with interface "type" will have a named interface and a 
> specific type which implements it.

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


[go-nuts] %T, type assertions and the Go spec

2017-06-19 Thread Tamás Gulácsi
AFAIK an interface is not a type, just behavior, and a type may implement an 
interface, so each variable will have a concrete type.
An variable with interface "type" will have a named interface and a specific 
type which implements it.

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


[go-nuts] Re: %T, type assertions and the Go spec

2017-06-19 Thread Will Hawkins
Sorry to reply to myself, but I gave this some additional thought and 
wanted to add a few comments. Please see below! 

Thanks again!

On Tuesday, June 20, 2017 at 12:52:58 AM UTC-4, Will Hawkins wrote:
>
> Hello great go community!
>
> I'm really struggling with something and I was hoping that you all could 
> provide some help. I am sure that I am missing something obvious, but I 
> can't get my head around it.
>
> In the Go spec, I see this statement:
>
> "If the type assertion holds, the value of the expression is the value 
> stored in x and its type is T. "
>
> That makes sense. I also see this:
>
> "If T is an interface type, x.(T) asserts that the dynamic type of x 
> implements the interface T."
>
> Still good. 
>
> In the Go documentation, I looked up the description of the %T verb:
>
> "a Go-syntax representation of the type of the value"
>
> I then write this code:
>
> package main
>
> import (
>   "fmt"
> )
>
> type Hello interface {
>   Speak()
> }
>
> type HelloListen interface {
>   Hello
>   Listen()
> }
>
> type HelloString string
>
> func (hs HelloString) Speak() {
>   fmt.Printf("Hello, World.\n");
> }
>
> type HelloInt int
>
> func (hi HelloInt) Speak() {
>   fmt.Printf("Hello, World.\n");
> }
> func (hi HelloInt) Listen() {
>   fmt.Printf("I'm listening.\n");
> }
>
> func main() {
>   var hello Hello
>   var hellolisten HelloListen
>
>   hello = HelloInt(1)
>   hellolisten = hello.(HelloListen)
>
>   hello.Speak()
>   hellolisten.Speak()
>   hellolisten.Listen();
>
>   fmt.Printf("hello: %T\n", hello);
>   fmt.Printf("hellolisten: %T\n", hellolisten);
> }
>
> The type assertions do as I would expect. The compiler allows me to call 
> Listen() on hellolisten and not on hello, so the types are handled 
> correctly. If I try to call hello.Listen(), the compiler gives me an error. 
> Again, this is as expected. 
>
> However, the last two lines of printed output do not give me what I 
> expect. They produce:
>
> hello: main.HelloInt
> hellolisten: main.HelloInt
>
> Having read that the %T verb gives me the type of the variable and that a 
> type assertion of the form used makes the assigned variable a HelloListen, 
> I would have expected it to print this:
>
> hello: main.Hello
> hellolisten: main.HelloListen
>
> I know that there is a difference between interface values and dynamic 
> types and dynamic values. Is it possible that the documentation about the 
> %T is misleading? Should it be more specific that it returns the variable's 
> "dynamic type." 
>
> This would seem to agree with the statement in the spec: (
> https://golang.org/ref/spec#Variables)
>
> "The *static type* (or just *type*) of a variable is the type given in 
> its declaration, the type provided in the new call or composite literal, 
> or the type of an element of a structured variable. Variables of interface 
> type also have a distinct *dynamic type*, which is the concrete type of 
> the value assigned to the variable at run time (unless the value is the 
> predeclared identifier nil, which has no type). The dynamic type may vary 
> during execution but values stored in interface variables are always 
> assignable to the static type of the variable."
>
> I am particularly reading the first sentence which suggests than an 
> unqualified use of the word "type" refers to the static type. Applying that 
> logic back to the %T documentation reinforces my incorrect expectation that 
> the final two lines of the output should be
>
> hello: main.Hello
> hellolisten: main.HelloListen
>
> I guess this, then, is the crux of my question:
>
> Should the documentation for %T be updated to say that it prints the 
> variable's dynamic type?
>

It seems perhaps that the ambiguity in the fmt package's documentation is 
not really the place to look for a solution (if this is even a problem). I 
say that because the reflect package seems to give, what I would consider, 
unexpected output. When calling the TypeOf() function, I would expect the 
result to be the "type" of the variable. Since that is an unqualified use 
of the term, after reading the spec I would expect it to return the static 
type.

If I add the following to the code snippet from above:

fmt.Printf("TypeOf(hello).String(): %v\n", reflect.TypeOf(hello).String());
fmt.Printf("TypeOf(hellolisten).String(): %v\n", 
reflect.TypeOf(hellolisten).String());

I would expect:

TypeOf(hello).String(): main.Hello
TypeOf(hellolisten).String(): main.HelloListen

and instead I get:

TypeOf(hello).String(): main.HelloInt
TypeOf(hellolisten).String(): main.HelloInt

That leads me to wonder if the best place to look at this is in the wording 
of that first sentence of the spec which seems to define what an 
unqualified use of the word type means. 

Again, I really hope that these questions aren't silly. Thank you for 
taking the time to educate me on where I have gone wrong!

Will


> I hope that this question makes sense. Please tell me where I have gone 
> wrong -- I know there are 

[go-nuts] %T, type assertions and the Go spec

2017-06-19 Thread Will Hawkins
Hello great go community!

I'm really struggling with something and I was hoping that you all could 
provide some help. I am sure that I am missing something obvious, but I 
can't get my head around it.

In the Go spec, I see this statement:

"If the type assertion holds, the value of the expression is the value 
stored in x and its type is T. "

That makes sense. I also see this:

"If T is an interface type, x.(T) asserts that the dynamic type of x 
implements the interface T."

Still good. 

In the Go documentation, I looked up the description of the %T verb:

"a Go-syntax representation of the type of the value"

I then write this code:

package main

import (
  "fmt"
)

type Hello interface {
  Speak()
}

type HelloListen interface {
  Hello
  Listen()
}

type HelloString string

func (hs HelloString) Speak() {
  fmt.Printf("Hello, World.\n");
}

type HelloInt int

func (hi HelloInt) Speak() {
  fmt.Printf("Hello, World.\n");
}
func (hi HelloInt) Listen() {
  fmt.Printf("I'm listening.\n");
}

func main() {
  var hello Hello
  var hellolisten HelloListen

  hello = HelloInt(1)
  hellolisten = hello.(HelloListen)

  hello.Speak()
  hellolisten.Speak()
  hellolisten.Listen();

  fmt.Printf("hello: %T\n", hello);
  fmt.Printf("hellolisten: %T\n", hellolisten);
}

The type assertions do as I would expect. The compiler allows me to call 
Listen() on hellolisten and not on hello, so the types are handled 
correctly. If I try to call hello.Listen(), the compiler gives me an error. 
Again, this is as expected. 

However, the last two lines of printed output do not give me what I expect. 
They produce:

hello: main.HelloInt
hellolisten: main.HelloInt

Having read that the %T verb gives me the type of the variable and that a 
type assertion of the form used makes the assigned variable a HelloListen, 
I would have expected it to print this:

hello: main.Hello
hellolisten: main.HelloListen

I know that there is a difference between interface values and dynamic 
types and dynamic values. Is it possible that the documentation about the 
%T is misleading? Should it be more specific that it returns the variable's 
"dynamic type." 

This would seem to agree with the statement in the spec: 
(https://golang.org/ref/spec#Variables)

"The *static type* (or just *type*) of a variable is the type given in its 
declaration, the type provided in the new call or composite literal, or the 
type of an element of a structured variable. Variables of interface type 
also have a distinct *dynamic type*, which is the concrete type of the 
value assigned to the variable at run time (unless the value is the 
predeclared identifier nil, which has no type). The dynamic type may vary 
during execution but values stored in interface variables are always 
assignable to the static type of the variable."

I am particularly reading the first sentence which suggests than an 
unqualified use of the word "type" refers to the static type. Applying that 
logic back to the %T documentation reinforces my incorrect expectation that 
the final two lines of the output should be

hello: main.Hello
hellolisten: main.HelloListen

I guess this, then, is the crux of my question:

Should the documentation for %T be updated to say that it prints the 
variable's dynamic type?

I hope that this question makes sense. Please tell me where I have gone 
wrong -- I know there are tons of smart people on this list with a deep, 
deep experience with the language and I look forward to learning anything 
that you can offer w.r.t this topic.

Thanks again for fostering such an amazing community of developers. It's a 
joy to be a part of it!

Will

-- 
You received this message because you are subscribed to the Google 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] Re: can not find .a file on linux platform

2017-06-19 Thread Dave Cheney


On Tuesday, 20 June 2017 13:10:17 UTC+10, Bicen Zhu wrote:
>
> Hello !
>
> I am building a golang project on linux, it has some libs located in my 
> $GOPATH. 
> If i build the project on windows,  I can find the .a file produced on 
> pkg/windows_amd64 directory. 
> But on linux i can not find that, even the directory "linux_amd64" is not 
> produced. 
> And The whole building process is good, I can got the final binary 
>
> Under most situations this is transparet to me, but now i want to release 
> the .a files without go sources to customer. Even I can build manully to 
> get the .a file, but i am curious where it is? Is is the defined behavious 
> on Linux?
>

Im sorry you are having difficulties. So we can assist you better can you 
please answer, in detail, the following

- What you did. eg. If you ran a command, list the entire command
- What you expected to see. eg, if you run a command on system a and get 
result b, does running the same command on another system give you result b
- What you saw instead. if, you didn't get the result you were expecting, 
what did you get, and if you think it's wrong, why you think its wrong


 

>
> I am using Golang 1.8 on Ubuntu
>
> Thanks!
>
> Bernard
>

-- 
You received this message because you are subscribed to the Google 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-19 Thread Dat Huynh

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  > wrote: 
> > Why do you need this feature? 
>

I have already answered the question in my email replying Lutz Horn.

Thank you very much.

Sincerely,
Dat.

-- 
You received this message because you are subscribed to the Google 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] can not find .a file on linux platform

2017-06-19 Thread Bicen Zhu
Hello !

I am building a golang project on linux, it has some libs located in my 
$GOPATH. 
If i build the project on windows,  I can find the .a file produced on 
pkg/windows_amd64 directory. 
But on linux i can not find that, even the directory "linux_amd64" is not 
produced. 
And The whole building process is good, I can got the final binary 

Under most situations this is transparet to me, but now i want to release 
the .a files without go sources to customer. Even I can build manully to 
get the .a file, but i am curious where it is? Is is the defined behavious 
on Linux?

I am using Golang 1.8 on Ubuntu

Thanks!

Bernard

-- 
You received this message because you are subscribed to the Google 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] Re: Set LD_LIBRARY_PATH while executing go test

2017-06-19 Thread David Collier-Brown
I used to write tons of interposers, what is it you are trying to do in Go?

-- 
You received this message because you are subscribed to the Google 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] Marshal and unmarshal data using in encoding/xml and encoding/json packages

2017-06-19 Thread Dat Huynh
Hi all,

I am using the libraries "encoding/xml" and "encoding/json" to marshal and
unmarshal a slice.

I wonder why the method Unmarshal in encoding/xml does not return a slice
as what I have from encoding/json.

The below is my example.
https://play.golang.org/p/ZlALkyCbzX

Do I miss something or is this a bug of the library?

Thank you very much.

Sincerely,
Dat.

-- 
You received this message because you are subscribed to the Google 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] Set LD_LIBRARY_PATH while executing go test

2017-06-19 Thread Michael Hudson-Doyle
On 16 June 2017 at 17:46,  wrote:

> Hello,
>
> Is there a way to set the LD_LIBRARY_PATH while executing go test command?
>
> My version is "go version go1.5.1 linux/amd64"
>

No. Why do you want to?

You can set the rpath of the generated executable with something like "go
test -ldflags='-r $foo'" or "go test -ldflags=-extldflags=-Wl,-rpath=$foo"
which might be another way to solve your problem. But I'm just guessing
really.

Cheers,
mwh

-- 
You received this message because you are subscribed to the Google 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] XML decoder vs xpath Performance

2017-06-19 Thread desaiabhijit
I need to integrateXML REST Api where dont need all the nodes / values 
return by thirdparty REST Api

There are main repeated 1500 nodes with lot of internal nodes

Please let me know which I suppose to use performance wise

1. Xml Decoder
2. Manual by using Token()
3. XPath to get values

Decoder and Manual both are taking 600 ms approx

Please let me know best possible way to achieve this to use less Memory 
with best performance

Please help

Rgds,

Abhi





-- 
You received this message because you are subscribed to the Google 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-19 Thread Ian Lance Taylor
On Sat, Jun 17, 2017 at 5:17 PM, Dat Huynh  wrote:
>
> Could you please let me know if there is any plan to fix the limitation?

There is an intent to fix it, but I wouldn't go so far as to say there
is a plan.  As far as I know nobody is working on it.  It's definitely
a bug, I just don't know when it will be fixed.

> Indeed, I am considering if it is worthwhile to rewrite my projects in Go.
> I have hundreds of interfaces in my Java apps and this feature will help me
> a lot.

I would be interested in hearing more about that.  This is a very
esoteric feature.  Essentially no Go programs call MakeStruct at all,
and even fewer call MakeStruct with an embedded field that has
methods.  Why do you need this feature?

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.


Re: [go-nuts] Curious about this snippet in /src/runtime/proc.go

2017-06-19 Thread n . s . glynn
It won't blank as much as it can get it's hands on. The default value for the 
pointer will be nil so it will try and assign (causing a panic() hopefully) to 
force an exit

-- 
You received this message because you are subscribed to the Google 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] Curious about this snippet in /src/runtime/proc.go

2017-06-19 Thread 'Thomas Bushnell, BSG' via golang-nuts
Something similar at
https://sourceware.org/git/?p=glibc.git;a=blob;f=stdlib/abort.c;h=19882f3e3dc1ab830431506329c94dcf1d7cc252;hb=HEAD#l138
in
the GNU C library. Sometimes you just need to be absolutely certain that a
function doesn't return.

On Thu, Jun 15, 2017 at 2:16 PM Rob Pike  wrote:

> Code comments can be helpful with unusual situations like this.
>
> -rob
>
>
> On Fri, Jun 16, 2017 at 4:25 AM, Goodwin Lawlor 
> wrote:
>
>> Thanks for the explanation.
>>
>> My random guess was that it's the compiler version of deleting your
>> browser cache... If exit fails, blank as much memory as we can get our
>> hands on. 
>>
>> On 15 Jun 2017 6:34 pm, "Ian Lance Taylor"  wrote:
>>
>>> On Thu, Jun 15, 2017 at 10:28 AM, Tyler Compton 
>>> wrote:
>>> > Why not just panic, though? And why the infinite loop, I wonder?
>>>
>>> The runtime is a special case in many ways, and this is among the more
>>> special parts.  This loop exists to catch problems while testing new
>>> ports.  If that loop is ever reached, something has gone badly wrong:
>>> the exit call should have caused the program to exit.  We can't assume
>>> that panic is working.  We can't really assume that anything is
>>> working.  What we want to do is stop the program.  Since exit failed,
>>> it's possible that a nil dereference will succeed.  If that fails too,
>>> we still have to do something, so we just loop.  We can't return
>>> because this is the main function that started the program; there is
>>> nothing to return to.
>>>
>>> Ian
>>>
>>> > On Thu, Jun 15, 2017 at 9:56 AM Aldrin Leal 
>>> wrote:
>>> >>
>>> >> Force a panic in case exit fails?
>>> >>
>>> >> --
>>> >> -- Aldrin Leal,  / http://about.me/aldrinleal
>>> >>
>>> >> On Thu, Jun 15, 2017 at 4:54 AM,  wrote:
>>> >>>
>>> >>> Hey,
>>> >>>
>>> >>> Learning golang at the moment and came across this at the end of func
>>> >>> main() in proc.go in the golang source tree.
>>> >>>
>>> >>> exit(0)
>>> >>> for {
>>> >>> var x *int32
>>> >>> *x = 0
>>> >>> }
>>> >>>
>>> >>> Ln 198 - 202 https://golang.org/src/runtime/proc.go
>>> >>>
>>> >>> How is the for loop ever reached and what's the purpose of the
>>> infinite
>>> >>> loop, zeroing memory?
>>> >>>
>>> >>> Thanks,
>>> >>>
>>> >>> Goodwin
>>> >>>
>>> >>> --
>>> >>> You received this message because you are subscribed to the Google
>>> 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.
>>> >
>>> > --
>>> > Tyler Compton
>>> > Software Engineering
>>> >
>>> > --
>>> > You received this message because you are subscribed to the Google
>>> 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.
>

-- 
You received this message because you are subscribed to the Google 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] Is it safe to invoke len(channel) on multi-gorountine

2017-06-19 Thread 'Thomas Bushnell, BSG' via golang-nuts
As you discovered, it is perfectly *safe *to call len on a channel in use
by multiple goroutines: you'll get a correct answer and you won't provoke a
crash or anything. But you can't use it as a signal that a following
receive will work if another goroutine might have received in the interim.

On Sat, Jun 17, 2017 at 6:58 AM  wrote:

> I almost got into the trap with this, trying to prioritize selected
> channel...
> https://play.golang.org/p/VOrPwx7HC_
>
> --
> You received this message because you are subscribed to the Google 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: RFC: Blog post: How to not use an HTTP router

2017-06-19 Thread 'Axel Wagner' via golang-nuts
Hey,

On Mon, Jun 19, 2017 at 12:43 PM,  wrote:

> I don t feel like expanding code helps to better explain
> the how/what/why of a sudden 42 question ? (why this /whatever/ has
> failed, I believe it should not)
>

I may be biased in this regard by personal experience. I am running (as an
ops-person) several large web service written in Java and C++ (and some
written in go) and I am pretty consistently frustrated by the lack of good
comprehension tools for routing. I very often run into the situation of,
for example, a black-box monitoring system telling me that a request failed
and needing to understand how it traces from the main entry point of the
server to the failure site and how all the parameters used are chosen. Or
developing against a service and needing to understand what I am doing
wrong when one of my requests is failing. Or just getting paged because we
are serving errors and needing to grep through logs for patterns in the
failing requests and then figuring out why these specific requests are the
ones that are failing.

I talking about the concern of tracing routing through code not because
it's fun to me to make up problems, but because it's a frequent source of
frustration for me.


> I m pretty sure its a good way to multiply keystrokes, and harden
> maintenance and changes.
>

I don't think it is either more typing or making maintenance harder,
obviously :) For the latter, I already described my reasoning in the post
itself, so I'm not going into detail. For the latter, I gave an example here
,
of how you can reduce the number of keystrokes necessary, if that's your
primary concern while maintaining the same pattern and the advantages I'm
talking about.

I don't think you *should* do that, though; just as you shouldn't use test
frameworks with assert-functions. If what you are doing is comparing
values, you should write them as an if-clause, that's readable and what
they are designed for. But if you really want to, you can do it. It's an
orthogonal concern to what I'm talking about.


> The gorilla handler can handle the type checking and return a proper error
> code.
>

But that ignores the issue. The issue isn't, that the muxer (let's not talk
too specifically about gorilla, I only use it as an example) can't figure
out that there is a non-int given as a parameter. The issue is, that *by
design* (that is pretty much the point of a muxer), you can have
intersecting sets of routes that might or might not match; the muxer will
pick a strategy and try each route out in series, until it finds a match.

A request like "/foo/12a" would fail a pattern like "/foo/{id:[0-9]+}". But
should the muxer, when it tries this pattern for this path return a 400,
because the pattern is invalid, a 404, because there is no matching pattern
defined, a 405, because you used GET instead of POST or should it continue
trying? There might be another route to try, which defines a pattern for
/foo/12a. Or a route that defines "/foo/{id:0-9a-z]+". Or any other set of
routes.
Should it, when it exhausted all the configured routes, return the 400 of
the pattern "/foo/{id:[0-9]+}" it tried, the 405 of the route
Methods("GET").Path("/foo/12a") it tried or a 404?

I would boldy claim, that to solve this problem in general, a muxer API
would need to basically be Turing-complete (which is exactly why this
 exists, by
the way). In my view, this negates the supposed advantages of a muxer.
Instead of calling the checks as Methods on the muxer, I can also just
write them in my handler, in the component, they belong to anyway.

It's not actually more verbose or complicated than calling methods on a
muxer-value, but it enables you to make an authoritative decision purely
based on local knowlege, so it becomes a *much* simpler problem to solve.
Plus, you actually *have* a Turing-complete language at your disposal.

The fact that it also makes the handler self-contained, so it can be
maintained by a separate team than the rest of the application or reused in
completely different applications is a then bonus.


>
> So, you can resolve the 42 question,
> not by diving in the code,
> but by reading the error messages,
> or *reading at the documentation.*
>
> (note: reading the error messages=> totally fail when you develop a
> website, not an api, as the error page is often generic and do not provide
> a deep explanation of the error, as the end user does not care about it
>

Totally disagree here. HTTP is primarily built for web pages and provides
well-defined status codes. A user might not need to care about the detailed
reasons for a 500, but they definitely want to know, that this is an
unforseen error condition in the server, as opposed to something they did
wrong. They want to know, if they entered an invalid phone number, that the
problem is the phone 

[go-nuts] Re: RFC: Blog post: How to not use an HTTP router

2017-06-19 Thread mhhcbon
hi,

I understand what / why you came to that given your explanation,
but I disagrees a lot to it.

I don t feel like expanding code helps to better explain 
the how/what/why of a sudden 42 question ? (why this /whatever/ has failed, 
I believe it should not)

I m pretty sure its a good way to multiply keystrokes, and harden 
maintenance and changes.

In the example you taken, because its not representative of all 42 
questions** (only few ones),
the solution is to provide a more speaky app.

In your post you take that route example,
"/articles/{category}/{id:[0-9]+}"

And later expand and rewrite it to return a proper error when an id is not 
an int,
Behavior that is totally excluded at the moment you decided
to apply a pattern on your route.

You are comparing things that are not comparable, 

the route can be
"/articles/{category}/{id}"

The gorilla handler can handle the type checking and return a proper error 
code.

So, you can resolve the 42 question,
not by diving in the code,
but by reading the error messages, 
or *reading at the documentation.*

(note: reading the error messages=> totally fail when you develop a 
website, not an api, as the error page is often generic and do not provide 
a deep explanation of the error, as the end user does not care about it, 
sometimes you can trick about it (put that in some comments/whatever/) but 
any serious security test team will warn you about it)

Or that /foo/123 is, technically, an illegal argument, not a missing page. 
I couldn't really find a good answer to any of these questions in the 
documentation of gorilla/mux for what it's worth. Which meant that when my 
web app suddenly didn't route requests correctly, I was stumped and needed 
to dive into code.


None of the solution compared here, ie gorilla vs plain code, manages 
correctly this feature.
In both case its an additional job to be done, in one way or another.

Somewhere you also talk about the idea that using a router would tightly 
link
components by their types, adn that is bad in your opinion.

In my opinion, I m very happy about tight types coupling. 
Like very very very very very very very happy about that.

Its the only thing i can rely on 
to apply an understanding and validates that things gonna work 
without being able to provide a formal proof (if i could, tbh).

*Type* here can be an interface or a value, that does not matter, their 
guarantees matter.


Something i truly agree with you,

They only need to know about the immediate handlers they delegate to and 
they only need to know about the sub-path they are rooted at


Local problem solving is always way easier to handle 
than large scaled problems across files/packages/concepts.

In that regard i do agree with you about the last proposal you give in its 
intentions,
I clearly disagree in its implementation,
it just not gonna work for me to write that much of code to solve those 
problems.

** the other kind of 42 questions is about functions that behaves 
differently from what the user expects.
Which happens in few cases, wrong documentation from author, misreading 
from consumer, and at least that third one, a name which is both too vague 
and too precise to give sufficient meaning about its purposes by itself,
example

/whatever/.Each() /whatever/ {...}

You can t tell what s going to happen in Each (will that call allocate?) 
without knowing what is /whatever/,
if whatever is an array, you can *deduce* there will be an allocation,
if its something else like a stream, you can *deduce* it won t.
Because the name is not sufficient to describe its meaning on a so vague / 
general context, 
the problems takes scale, thus have an air of mystery.

That happens only with some kind of names, 
as soon as you enter a specific context (what mean to Put to a dht table 
?), 
you gonna need to learn the specifics of the problem before, 
by definition the local question is scaled to the context of your general 
situation (something like this),
naturally its has an air of mystery, 
naturally you need to learn and assert about the details (via the code or 
the doc).

_

about the question, why there s so much alternative routers.

My personal opinion, gorilla mux is great, but its an enter step for many 
people,
so they need to learn both the language + the framework + quickly they need 
to assimilate
some pretty fine tune trick of the language to keep going,
and so it become difficult, and so alternatives has a reason to happen.

Also some constructs, while being very verbose, are not obvious...

http.Handle("/static/", http.StripPrefix("/static/", 
http.FileServer(http.Dir("./public"


Super verbose.

So clear that we need stackoverflow to make it happen the first time.

Another possible reason, as all in things in golang, 
it has to be verbose,
we ain t all like that, 
easy path for a developer to think that i can fix that.

And no, i m not saying verbosity is bad, 
i m saying that verbosity is not 

[go-nuts] Re: RFC: Blog post: How to not use an HTTP router

2017-06-19 Thread fusi . enrico . maria
Hi Axel

I agree on the suggestions you give on the article, even I have another 
view of the "epidemic".

To be short: almost none of the "Basic/Simple/lightweight http 
rest/mux/routers/socallframeworks" is supposed to have a real usage.

Sometimes I have the task (I'm the lucky guy) to do technical interview 
with people applying for my company, and I see that almost EVERYBODY
has , in the resumee, a "personal project" to show. Seems good? Uhm

In my experience, ~80% of that projects are "*Basic* something", "*Simple* 
whatever",  piece of code. Meaning they are very primitive, incomplete, not 
ready, but they  create a new entry in the Resumee or Linkedin. 

Nothing I would call "a product", neither close to it.

Lot of Resumee also mentions how many forks their projects has, so the best 
way to have forks is to write "libraries" and "API".  So that, some 
softwares in use by the HR are confirming "sure, this guy is very famous 
for his Basic HTTP proxy". (Until you don't try to use it, I mean. But no 
software in use by the HR is able to do it. Hope the AI will, someday.).

I am not a developer (I work as a system architect), nevertheless I find 
golang very good for prototyping.  Many times I've  hit my head on those 
"libraries", "so call frameworks" and "API". 

100% of times I implemented my POC following instructions and documentation 
(when given. ~90% has no decent documentation),  just to realize that the 
"framework" was barely able to fit 1/2 use-cases an inexperienced Junior 
was able to imagine. So I ended up to rewrite everything from scratch. 
Fortunately golang has this amazing feature of Interfaces, so I just needed 
to change "the meaning" of a specific call.

Anyhow, I think you are worrying for code which is not written to be 
useful, neither utilized, and not even taken in consideration  : is written 
for some Human Resource office here and there.

According with github, there is a plenty of good software written in 
golang. When you exclude the "Simple", "Easy", "Basic" stuffs, 
(=unfinished/incomplete) you find an amount of "ready+complete" software 
which is still impressive, but  much smaller.  

The epidemic of "simple this/easy that/basic whatever" , regarding API / 
libraries /proxy /routers   (written in golang or others)  will not finish 
even if/when you convince everybody this is not useful:  none of that 
software* is supposed to be useful. *

They are just another line on the Resumee/Linkedin. 

Just my two cents, of course.

Besides, nice article.

FEM

On Monday, 19 June 2017 00:02:37 UTC+2, Axel Wagner wrote:
>
> Hey gophers,
>
> in an attempt to rein in the HTTP router epidemic,
>

-- 
You received this message because you are subscribed to the Google 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] Re: RFC: Blog post: How to not use an HTTP router

2017-06-19 Thread Egon
On Monday, 19 June 2017 01:02:37 UTC+3, Axel Wagner wrote:
>
> Hey gophers,
>
> in an attempt to rein in the HTTP router epidemic, I tried writing down a) 
> why I think *any* router/muxer might not be a good thing to use (much 
> less write) and b) what I consider good, practical advice on how to route 
> requests instead. It's not rocket science or especially novel, but I wanted 
> to provide more useful advice than just saying "just use net/http" and 
> haven't seen that a lot previously.
>
> Feedback is welcome :)
> http://blog.merovius.de/2017/06/18/how-not-to-use-an-http-router.html
>

I've also used this approach for very simple endpoints:

func ServeHTTP(w http.ResponseWriter, r *http.Request) {
type rr struct{ method, path string } // rr = "resource request"
switch (rr{r.Method, r.URL.Path}) {
default:
http.Error(w, "Invalid request.", http.StatusBadRequest)
retun
case rr{http.MethodGet, "/"}:
// handle index
case rr{http.MethodGet, "/favicon.ico"}:
// serve icon
case rr{http.MethodGet, "/list"}:
// serve list
case rr{http.MethodPost, "/save"}:
// ..
}
}

Of course this can be combined with getting the ShiftPath and other things, 
when necessary.

+ Egon

-- 
You received this message because you are subscribed to the Google 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] production PDF to text service

2017-06-19 Thread Kiki Sugiaman
My experience (production) consists of calling external processes (both 
existing open source programs and my custom c++ code) using os/exec.


However, I remember evaluating https://github.com/rsc/pdf for extracting 
text from unencrypted pdf and it did the job fine.




On 19/06/17 08:21, svj...@gmail.com wrote:
Can someone with experience with the problem suggest a best package for 
building a production PDF to text conversion service in Go? I am working 
with Go and Google App Engine. A cursory Google search brings up two 
packages, the first considerably more popular but with external 
dependencies I would like to avoid.


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] RFC: Blog post: How to not use an HTTP router

2017-06-19 Thread 'Axel Wagner' via golang-nuts
I like the notion/notation of a resource graph and will use it in the
future :)

On Mon, Jun 19, 2017 at 12:31 AM, Kevin Conway 
wrote:
>
> That being said, having access to easy-to-use, parameterized routes makes
> things much simpler IMO. It cleanly separates the logic required for
> resource graph traversal from the endpoint rendering.
>

I don't think that's mutually exclusive with what I'm proposing. Indeed,
ServeHTTP can contain all of the traversal logic, while the rendering logic
is contained in separate methods of the Handler.
All I'm arguing is, that the graph traversal should be written as local as
possible; best case, no node knows about anything but its immediate
neighbors. But even that is not forced; a handler might contain more logic
than just a single component, if necessary (an example of this in my post
is the last UserHandler; it may shift more than one component, to consume
the user-id and then continue routing). All I'm advocating for is that you
somehow create a routing-graph in a logical manner and then make the
decisions in the component that is responsible.


> A large concept that this article also ignores is middleware. The
> decorator pattern is quite a powerful one and is facilitated by nearly
> every 3rd party mux implementation. Top level support for middleware makes
> adding decorators to some, or all, endpoint rendering resources  an easy
> task regardless of the specific resource graph traversal required to
> activate them. The ability to take a single purpose, well tested endpoint
> and wrap it in other single purpose, well tested functionality (such as
> logging, stats, tracing, retries, backoffs, circuit breaking,
> authentication, etc.) without modifying the core logic of the endpoint is a
> large value add. It's unclear how the "resource as a router" model could
> easily provide such a feature. This is not to say it's impossible, I simply
> haven't seen it done well outside the mux model before.
>

It is true that I largely ignore that. So far I've assumed that you likely
want to have middleware near or at the top of the routing tree, so you'd
end up wrapping your handler as a whole.

There are ways to integrate middleware for subtrees, though. If you forego
the advantage of easy static analysis (which you'd inherently have to, with
middleware) you could use http.Handlers in the individual routing notes,
instead of concrete types. Alternatively, you could add a `Middleware
func(http.Handler) http.Handler` to your nodes, defaulting to a nop.

These do require cooperation from the nodes (in that they need to provide
the ability to hook things into subnodes), though. I find that realistic,
given that it's one application, but if you heavily rely on third parties
for individual nodes (think /debug/* handlers from the stdlib) this would
be a problem.

Depending on the complexity of the graph and your needs an easy solution is
probably to just combine the two approaches; create a resource graph with
concrete nodes and easy, statically deducible traversal for routing the
request and wrap it with a mux, to inject middle-ware. As the mux only
needs to do matching, not routing, it can be a lot simpler.

I agree, that this needs some thinking. Personally, I don't rely heavily on
middleware, much less deep in the routing graph, so this isn't a huge
concern for me, personally. But it should get a better answer at some point
:)



>
> On Sun, Jun 18, 2017 at 5:02 PM 'Axel Wagner' via golang-nuts <
> golang-nuts@googlegroups.com> wrote:
>
>> Hey gophers,
>>
>> in an attempt to rein in the HTTP router epidemic, I tried writing down
>> a) why I think *any* router/muxer might not be a good thing to use (much
>> less write) and b) what I consider good, practical advice on how to route
>> requests instead. It's not rocket science or especially novel, but I wanted
>> to provide more useful advice than just saying "just use net/http" and
>> haven't seen that a lot previously.
>>
>> Feedback is welcome :)
>> http://blog.merovius.de/2017/06/18/how-not-to-use-an-http-router.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.