[go-nuts] Re: Calling Once (in the code)

2017-08-11 Thread dc0d
Well said! Still I prefer functions to comments, when possible. As it's 
been said, code never lies, comments sometimes do. And a boom is simpler to 
understand (for me). Functions go boom; comments do not.

On Saturday, August 12, 2017 at 1:48:05 AM UTC+4:30, Egon wrote:
>
> There are no good things... only trade-offs.
>
> Clarity is not directly about naming, but rather balancing locus of 
> attention and working memory. When you put too many things together (such 
> as a long function), you fill up your short term memory when reading the 
> code... on the other side, when you make too many pieces you have to 
> constantly switch from one piece to another to understand something. But 
> yes, good names enable learning chunks and make recalling easier.
>
> So yeah... you want balance between these two aspects... though people 
> have different strengths -- e.g. some people have better working memory and 
> some have better focus switching skills... I suspect this what leads some 
> people to prefer one style over the other.
>
> On Friday, 11 August 2017 22:12:09 UTC+3, dc0d wrote:
>>
>> Thanks for suggesting guru. I'll try it.
>>
>> If there is a convention for naming, it makes code more clear, otherwise, 
>> yes, it makes code more unclear - in my experience. In times it's not an 
>> easy task. But having a long function too, is not a good thing (IMHO).
>>
>> On Friday, August 11, 2017 at 6:02:31 PM UTC+4:30, Egon wrote:
>>>
>>> Note, this can fragment the code and make it harder to understand... (
>>> http://number-none.com/blow/john_carmack_on_inlined_code.html)
>>>
>>> As for the tool:
>>>
>>> guru can give you the callers of a function, so you might be able to 
>>> derive something from it.
>>>
>>> + Egon
>>>
>>> On Friday, 11 August 2017 10:39:16 UTC+3, dc0d wrote:

 "When you feel the need to write a comment, first try to refactor the 
 code so that any comment becomes superfluous."
 - Martin Fowler, Kent Beck, John Brant, William Opdyke, and Don Roberts 
 (1999) Refactoring: Improving the Design of Existing Code. Addison-Wesley.

 Based on this practice, the code below (this code's sole purpose is to 
 demonstrate):

 func sampleSloppyFuncForDescribingThisSpecificProblem(data *Data, p *
 DLO) error {
 if !isNameOK(data.FirstName, data.MiddleName, data.LastName) {
 return errInvalidName
 }

 if !isAddressOK(data.Address1, data.Address2) {
 return errInvalidAddress
 }

 if !isPhoneOK(data.PhoneNumber, data.MobileNumber) {
 return errInvalidPhone
 }

 p.Address1 = data.Address1
 p.Address2 = data.Address2
 p.BirthDate = data.BirthDate
 p.FirstName = data.FirstName
 p.LastName = data.LastName
 p.MiddleName = data.MiddleName
 p.MobileNumber = data.MobileNumber
 p.PhoneNumber = data.PhoneNumber

 return nil
 }

 Can get refactored to (instead of adding comments):

 func sampleSloppyFuncForDescribingThisSpecificProblem(data *Data, p *
 DLO) error {
 if err := validateData(data); err != nil {
 return err
 }

 transferData(data, p)

 return nil
 }

 func validateData(data *Data) error {
 if !isNameOK(data.FirstName, data.MiddleName, data.LastName) {
 return errInvalidName
 }

 if !isAddressOK(data.Address1, data.Address2) {
 return errInvalidAddress
 }

 if !isPhoneOK(data.PhoneNumber, data.MobileNumber) {
 return errInvalidPhone
 }

 return nil
 }

 func transferData(data *Data, p *DLO) {
 p.Address1 = data.Address1
 p.Address2 = data.Address2
 p.BirthDate = data.BirthDate
 p.FirstName = data.FirstName
 p.LastName = data.LastName
 p.MiddleName = data.MiddleName
 p.MobileNumber = data.MobileNumber
 p.PhoneNumber = data.PhoneNumber
 }

 Now the sole purpose of functions validateData and transferData is 
 providing a clean and more descriptive code. They should appear only in 
 one 
 place in the code inside the body of 
 sampleSloppyFuncForDescribingThisSpecificProblem. This is what I need to 
 check.

 On Friday, August 11, 2017 at 8:57:46 AM UTC+4:30, Henry wrote:
>
> I don't fully understand the problem, but if you need a quick and 
> dirty way to ensure a function is called exactly once, you can always use 
> a 
> global variable, have the function checks the variable when the function 
> is 
> called. If the function is called the first time, it will set the 
> variable. 
> If the function has been called more than once, it should panic and 
> returns 
> the stacktrace.
>
> On Friday, August 11, 2017 at 3:02:47 AM UTC+7, dc0d wrote:

Re: [go-nuts] Why does vet's 'rangeloop' check only check the last statement of a loop?

2017-08-11 Thread Ian Lance Taylor
On Thu, Aug 10, 2017 at 1:43 PM,   wrote:
>
> Yes, it makes sense that it would be impossible to really check at that
> level. What surprised me was that this does not trigger vet:
>
> for i := range slice {
> go f(i)
> _ = 1
> }
>
> Yet this does trigger vet:
>
> for i := range slice {
> _ = 1
> go f(i)
> }
>
> Is there something special about the last statement that makes it easier to
> check?
>
> For what it's worth, this exact bug caused real user-impacting issues at my
> company. The team responsible for the code was very surprised that vet did
> not alert them to the issue before it made it into production.

I agree that this appears to be a bug.  I filed https://golang.org/issue/21412.

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] golang.org/x/crypto/ssh hangs when connecting to some servers

2017-08-11 Thread Philip Stein
Hello,
I'm working on a utility that uses the golang.org/x/crypto/ssh library to 
connect to about 100 servers. Most of the connections work fine, but there 
are 6 servers where the connection hangs during the ssh.Dial. Using delve, 
I've been able to track it down to clientAuthenticate in client_auth.go, 
specifically line 20 in the current source:
packet, err := c.transport.readPacket()

As soon as execution reaches this line, it hangs indefinitely.

The servers all have different versions of OpenSSH, and servers that work 
have the same versions as the servers that don't. If I use "ssh 
username@server" from the command line in linux, or try to SSH in using 
putty in Windows, I can connect with no problems.

I can reproduce the same problem with this program:

package main


import (

"fmt"

"log"


"golang.org/x/crypto/ssh"

)


func main() {

config := &ssh.ClientConfig{

User: "username",

Auth: []ssh.AuthMethod{

ssh.Password("password"),

},

HostKeyCallback: ssh.InsecureIgnoreHostKey(),

}

client, err := ssh.Dial("tcp", "server:22", config)

if err != nil {

log.Fatal("Failed to dial: ", err)

}

client.Close()

fmt.Println("Done")

}


Is there something wrong in my code, could it be a configuration problem on 
these servers, or is there a bug?

I'm using go1.8.3 windows/amd64 and also cross compiling for linux/amd64.

-- 
You received this message because you are subscribed to the Google 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: [Blog] Context should go away for Go 2

2017-08-11 Thread Sam Vilain
On Monday, 7 August 2017 09:06:23 UTC-7, Daniel Theophanes wrote:
>
> In the projects I've worked on the switch to Context has been a huge win 
> all across the board. I think it would be sweet to find an effect way to 
> make io.Reader take a context (I often want just that, and when I really 
> need it the solution tends to be more inefficient then it could be).
>

Right; the blocking-style interface of io.Reader is a problem here; I 
didn't really consider this, but my proposal (on its own thread) solves 
this problem; readers that know how can read from the sync.Done channel 
(which would have to be a 'close on cancel' type channel to allow multiple 
readers).
 

> As for Context.Values, I think you are dismissive of the real use-cases 
> without giving proper weight to them. It can be abused. Just like 
> go-routines and channels. I'm not saying we can't do better then the 
> current implementation, we probably can if the benefit is seen as worth the 
> cost of the change.
>

+1.  I used the values interface first and found it much better than adding 
extra parameters to every function, or passing around large interface types 
with a bunch of getter methods.

You're saying context is viral. It is. Just like errors are viral. Once you 
> start returning them you need to propagate them back. Having a context 
> argument is saying "this function, or something this function calls may 
> block for undisclosed amounts of time and we need to know when to stop 
> blocking and back out." 
>

Or "this function wants to log or profile some inner function" or "this 
function wants to use cached objects read within the same transaction".

In my experience, in real server applications you always want these 
abilities, but few structure their code to include context arguments. The 
status quo is that logging is almost always really bad in Go server 
applications.  Caching values read within a transaction is too hard so 
you'll make more DB calls than necessary.  Profiling never covers the 
tightest loops in your code.  This should be easy to add to an existing 
application without massive refactoring.
 

> There might be a better way to do ctx (and maybe errors) if the language 
> was adjusted; I'm fairly sure go-routine local storage isn't the answer but 
> maybe something else would be. Maybe you could create an Arena with a 
> context and a pattern for returning execution on error and an Arena could 
> use multiple go-routines and such. However I think where you would need to 
> start is a named real experience building and maintaining a solution in Go 
> that gets real use. Then look at it and see where it was painful and how it 
> was so.
>

"Goroutine Local Storage" is bad in my opinion because it's effectively a 
global, even if it is private to the goroutine.  I believe context.Context 
is the right pattern, in that values are rolled back as the call stack 
unwinds, and building it inside the runtime allows performance 
optimizations (variable elimination, slot unrolling, combination of context 
values into per-scope arenas) which would otherwise be impractical or ugly.

Sam

-- 
You received this message because you are subscribed to the Google 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-11 Thread Ian Lance Taylor
On Fri, Aug 11, 2017 at 2:51 PM, Josh Humphries  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(&m)))
> 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(&m)) = myMapPointer


> 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(&m)))
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] Go 2.0 proposal: context scoped variables

2017-08-11 Thread Sam Vilain
Many have written about this; there's an index on Go wiki under 
ExperienceReports#context 
 including my 
own writing for the 2016 advent calendar.

I would like to propose a simpler way to solve the "optional variable 
access" part of context as a language feature.  The core problem I'm trying 
to solve is the necessity for large scale refactoring to add the ctx 
variable to every caller in a stack.  I've done this before for the purpose 
of adding log tagging, tracing, cancellation, and database 
transactions/savepoints management.  I believe it is a good fit for those 
cases.  I've also seen bad usages of it - people shoehorning required 
variables into it to escape the difficulties of rethinking their design.

The basics:

   - the runtime adds an extra stack argument for its equivalent of the 
   Context structure.
  - this argument is not directly accessible
  - it may be eliminated/optimized out by the compiler where not used
  - it may be "unrolled" to more than one stack argument for performance
   - a special keyword added for declaring/accessing 'context variables'
   - assigning to a context variable creates a new context
   - may make cancelation easy and natural

*Setting context variables*

So, for example, this use of context.Context:

type myPrivateType struct{}
var myPrivateKey myPrivateType

func someFunc(ctx context.Context, args... interface{}) {
localInfo := &LocalInfo{}
ctx := context.WithValue(ctx, myPrivateKey, localInfo)
...
}


Would instead be:

func someFunc(args... interface{}) {
context var localInfo := &LocalInfo{}
...
}

 
*Retrieving context variables*

*Retrieving* a value would change from:
 

func otherFunc(ctx context.Context, args... interface{}) {
localInfo, ok := ctx.Value(myPrivateKey).(*LocalInfo)
...
}

To:

 func otherFunc(args... interface{}) {
 context var localInfo *LocalInfo
 ...
}


*Mid-function variable re-assignment*

Re-assigning a previously declared variable would have the same effect as 
re-assigning a ctx variable in scope:

func someFunc(ctx context.Context, args... interface{}) {
localInfo, ok := ctx.Value(myPrivateKey).(*LocalInfo)
... 
if somecondition {
ctx = context.WithValue(ctx, myPrivateKey, localInfo)
}
...
}


Would be equivalent to:

func someFunc(ctx context.Context, args... interface{}) {
context var localInfo *LocalInfo
... 
if somecondition {
localInfo = &LocalInfo{}
}
...
}


I wouldn't treat this exact equivalence as a hard rule; this re-assigning 
would only be expected to affect that particular context variable. 

*Public context variables*

It could also be possible to access other packages' public context 
variables:

func someFunc(args... interface{}) {
context var pkg.FooVariable otherPkg.SomeType 
...
}

This declaration is a little weird, because it includes a package name in 
the variable name.  The immediate question is, is this variable accessed 
later as "pkg.FooVariable" or just "FooVariable"?  I would lean towards the 
former to be less surprising and to avoid potential namespace clashes.

This could be useful for log tagging; APIs would look like;

context var logging.Tags []zap.Field
logging.Tags = append(logging.Tags, zap.String("rqID", rqUUID))

Where logging is some project-global logging module.

This isn't quite the pattern I used in my context logging post, which was:

logging module:

// WithRqId returns a context which knows its request ID
func WithRqId(ctx context.Context, rqId string) context.Context {
return context.WithValue(ctx, requestIdKey, requestId)
}


calling package:

func RequestHandler(w http.ResponseWriter, r *http.Request) {
rqId := uuid.NewRandom()*rqCtx := logging.WithRqId(httpContext, 
rqId)
*...


This one-line style of tagging a context in that last block could be 
supported with this sort of call:

context var logging.Tags := logging.WithRqID(rqID)

In this instance, as logging.WithRqID is evaluated before the logging.Tags 
context variable is assigned, it accesses the prior value.  The function 
returns the new variable instead of an entire context.Context struct. 

*Context variable scope*

The scope of a context variable would be essentially the same as in context: 
it passes down, but not up. Declaring a context variable without 
immediately assigning it will behave as in context: if it's there, you get 
the prior value.  If it's not, you get a zero value (well, context gives 
you a nil, but the idea is the same).

This style makes it easier to identify use of uninitialized context 
variables:


func badFunc(args... interface{}) {
context var logging.Logger zap.Logger 
logging.Logger.Info("in badFunc()", zap.Object("args", args))
...
}


It's quite easy to see here that the logging.Logger variable might be being 
used uninitialized.  It also

[go-nuts] Re: Calling Once (in the code)

2017-08-11 Thread Egon
There are no good things... only trade-offs.

Clarity is not directly about naming, but rather balancing locus of 
attention and working memory. When you put too many things together (such 
as a long function), you fill up your short term memory when reading the 
code... on the other side, when you make too many pieces you have to 
constantly switch from one piece to another to understand something. But 
yes, good names enable learning chunks and make recalling easier.

So yeah... you want balance between these two aspects... though people have 
different strengths -- e.g. some people have better working memory and some 
have better focus switching skills... I suspect this what leads some people 
to prefer one style over the other.

On Friday, 11 August 2017 22:12:09 UTC+3, dc0d wrote:
>
> Thanks for suggesting guru. I'll try it.
>
> If there is a convention for naming, it makes code more clear, otherwise, 
> yes, it makes code more unclear - in my experience. In times it's not an 
> easy task. But having a long function too, is not a good thing (IMHO).
>
> On Friday, August 11, 2017 at 6:02:31 PM UTC+4:30, Egon wrote:
>>
>> Note, this can fragment the code and make it harder to understand... (
>> http://number-none.com/blow/john_carmack_on_inlined_code.html)
>>
>> As for the tool:
>>
>> guru can give you the callers of a function, so you might be able to 
>> derive something from it.
>>
>> + Egon
>>
>> On Friday, 11 August 2017 10:39:16 UTC+3, dc0d wrote:
>>>
>>> "When you feel the need to write a comment, first try to refactor the 
>>> code so that any comment becomes superfluous."
>>> - Martin Fowler, Kent Beck, John Brant, William Opdyke, and Don Roberts 
>>> (1999) Refactoring: Improving the Design of Existing Code. Addison-Wesley.
>>>
>>> Based on this practice, the code below (this code's sole purpose is to 
>>> demonstrate):
>>>
>>> func sampleSloppyFuncForDescribingThisSpecificProblem(data *Data, p *DLO
>>> ) error {
>>> if !isNameOK(data.FirstName, data.MiddleName, data.LastName) {
>>> return errInvalidName
>>> }
>>>
>>> if !isAddressOK(data.Address1, data.Address2) {
>>> return errInvalidAddress
>>> }
>>>
>>> if !isPhoneOK(data.PhoneNumber, data.MobileNumber) {
>>> return errInvalidPhone
>>> }
>>>
>>> p.Address1 = data.Address1
>>> p.Address2 = data.Address2
>>> p.BirthDate = data.BirthDate
>>> p.FirstName = data.FirstName
>>> p.LastName = data.LastName
>>> p.MiddleName = data.MiddleName
>>> p.MobileNumber = data.MobileNumber
>>> p.PhoneNumber = data.PhoneNumber
>>>
>>> return nil
>>> }
>>>
>>> Can get refactored to (instead of adding comments):
>>>
>>> func sampleSloppyFuncForDescribingThisSpecificProblem(data *Data, p *DLO
>>> ) error {
>>> if err := validateData(data); err != nil {
>>> return err
>>> }
>>>
>>> transferData(data, p)
>>>
>>> return nil
>>> }
>>>
>>> func validateData(data *Data) error {
>>> if !isNameOK(data.FirstName, data.MiddleName, data.LastName) {
>>> return errInvalidName
>>> }
>>>
>>> if !isAddressOK(data.Address1, data.Address2) {
>>> return errInvalidAddress
>>> }
>>>
>>> if !isPhoneOK(data.PhoneNumber, data.MobileNumber) {
>>> return errInvalidPhone
>>> }
>>>
>>> return nil
>>> }
>>>
>>> func transferData(data *Data, p *DLO) {
>>> p.Address1 = data.Address1
>>> p.Address2 = data.Address2
>>> p.BirthDate = data.BirthDate
>>> p.FirstName = data.FirstName
>>> p.LastName = data.LastName
>>> p.MiddleName = data.MiddleName
>>> p.MobileNumber = data.MobileNumber
>>> p.PhoneNumber = data.PhoneNumber
>>> }
>>>
>>> Now the sole purpose of functions validateData and transferData is 
>>> providing a clean and more descriptive code. They should appear only in one 
>>> place in the code inside the body of 
>>> sampleSloppyFuncForDescribingThisSpecificProblem. This is what I need to 
>>> check.
>>>
>>> On Friday, August 11, 2017 at 8:57:46 AM UTC+4:30, Henry wrote:

 I don't fully understand the problem, but if you need a quick and dirty 
 way to ensure a function is called exactly once, you can always use a 
 global variable, have the function checks the variable when the function 
 is 
 called. If the function is called the first time, it will set the 
 variable. 
 If the function has been called more than once, it should panic and 
 returns 
 the stacktrace.

 On Friday, August 11, 2017 at 3:02:47 AM UTC+7, dc0d wrote:
>
> Is there a tool/linter to check if a private package function gets 
> called exactly once *in the code*? (I'm not looking for a runtime 
> solution like *sync.Once* but a code analysis tool/linter).
>
> Purpose: A guideline on commenting code by Martin Fowler states that 
> before writing a comment, see if it is possible to put that part inside a 
> meaningful function. I've followed that guide

[go-nuts] Re: Calling Once (in the code)

2017-08-11 Thread dc0d
Thanks for suggesting guru. I'll try it.

If there is a convention for naming, it makes code more clear, otherwise, 
yes, it makes code more unclear - in my experience. In times it's not an 
easy task. But having a long function too, is not a good thing (IMHO).

On Friday, August 11, 2017 at 6:02:31 PM UTC+4:30, Egon wrote:
>
> Note, this can fragment the code and make it harder to understand... (
> http://number-none.com/blow/john_carmack_on_inlined_code.html)
>
> As for the tool:
>
> guru can give you the callers of a function, so you might be able to 
> derive something from it.
>
> + Egon
>
> On Friday, 11 August 2017 10:39:16 UTC+3, dc0d wrote:
>>
>> "When you feel the need to write a comment, first try to refactor the 
>> code so that any comment becomes superfluous."
>> - Martin Fowler, Kent Beck, John Brant, William Opdyke, and Don Roberts 
>> (1999) Refactoring: Improving the Design of Existing Code. Addison-Wesley.
>>
>> Based on this practice, the code below (this code's sole purpose is to 
>> demonstrate):
>>
>> func sampleSloppyFuncForDescribingThisSpecificProblem(data *Data, p *DLO) 
>> error {
>> if !isNameOK(data.FirstName, data.MiddleName, data.LastName) {
>> return errInvalidName
>> }
>>
>> if !isAddressOK(data.Address1, data.Address2) {
>> return errInvalidAddress
>> }
>>
>> if !isPhoneOK(data.PhoneNumber, data.MobileNumber) {
>> return errInvalidPhone
>> }
>>
>> p.Address1 = data.Address1
>> p.Address2 = data.Address2
>> p.BirthDate = data.BirthDate
>> p.FirstName = data.FirstName
>> p.LastName = data.LastName
>> p.MiddleName = data.MiddleName
>> p.MobileNumber = data.MobileNumber
>> p.PhoneNumber = data.PhoneNumber
>>
>> return nil
>> }
>>
>> Can get refactored to (instead of adding comments):
>>
>> func sampleSloppyFuncForDescribingThisSpecificProblem(data *Data, p *DLO) 
>> error {
>> if err := validateData(data); err != nil {
>> return err
>> }
>>
>> transferData(data, p)
>>
>> return nil
>> }
>>
>> func validateData(data *Data) error {
>> if !isNameOK(data.FirstName, data.MiddleName, data.LastName) {
>> return errInvalidName
>> }
>>
>> if !isAddressOK(data.Address1, data.Address2) {
>> return errInvalidAddress
>> }
>>
>> if !isPhoneOK(data.PhoneNumber, data.MobileNumber) {
>> return errInvalidPhone
>> }
>>
>> return nil
>> }
>>
>> func transferData(data *Data, p *DLO) {
>> p.Address1 = data.Address1
>> p.Address2 = data.Address2
>> p.BirthDate = data.BirthDate
>> p.FirstName = data.FirstName
>> p.LastName = data.LastName
>> p.MiddleName = data.MiddleName
>> p.MobileNumber = data.MobileNumber
>> p.PhoneNumber = data.PhoneNumber
>> }
>>
>> Now the sole purpose of functions validateData and transferData is 
>> providing a clean and more descriptive code. They should appear only in one 
>> place in the code inside the body of 
>> sampleSloppyFuncForDescribingThisSpecificProblem. This is what I need to 
>> check.
>>
>> On Friday, August 11, 2017 at 8:57:46 AM UTC+4:30, Henry wrote:
>>>
>>> I don't fully understand the problem, but if you need a quick and dirty 
>>> way to ensure a function is called exactly once, you can always use a 
>>> global variable, have the function checks the variable when the function is 
>>> called. If the function is called the first time, it will set the variable. 
>>> If the function has been called more than once, it should panic and returns 
>>> the stacktrace.
>>>
>>> On Friday, August 11, 2017 at 3:02:47 AM UTC+7, dc0d wrote:

 Is there a tool/linter to check if a private package function gets 
 called exactly once *in the code*? (I'm not looking for a runtime 
 solution like *sync.Once* but a code analysis tool/linter).

 Purpose: A guideline on commenting code by Martin Fowler states that 
 before writing a comment, see if it is possible to put that part inside a 
 meaningful function. I've followed that guideline for sometime and it 
 helps 
 to have a cleaner code base. But those explanatory functions should get 
 called only from where that they are meant to make it more clear.

>>>

-- 
You received this message because you are subscribed to the Google 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] (Un)Expected compiler behavior on named/unnamed parameters of interface functions

2017-08-11 Thread Ian Lance Taylor
On Fri, Aug 11, 2017 at 11:51 AM, Penguin Enormous
 wrote:
> My eyes has just been opened. Silly me, I get it now. Thank you very much.
>
> May I ask which section in the Language Specification mention this allowance
> of int (or float64, ... etc.) for use as identifier names?

https://golang.org/ref/spec#Keywords
https://golang.org/ref/spec#Predeclared_identifiers

Ian



> On Saturday, August 12, 2017 at 1:30:04 AM UTC+7, Ian Lance Taylor wrote:
>>
>> On Fri, Aug 11, 2017 at 11:03 AM, Penguin Enormous
>>  wrote:
>> >
>> > I think that there is inconsistency in the way Go compiler report error
>> > regarding name/unnamed parameters. This is a bit hard for me to explain
>> > in
>> > words so please check out this short snippet first:
>> >
>> > https://play.golang.org/p/Sg0DtCtgF2
>> >
>> > Is this unexpected behavior or it's just me that's feeling strange?
>>
>> Go does not permit mixing named and unnamed parameters in a parameter
>> list.
>>
>> In a declaration like Run(int, f float64) you have two parameters of
>> type `float64`.  The first parameter is named `int` and the second
>> parameter is named `f`.  (The essential point here, of course, is that
>> in Go `int` is not a keyword, and it's OK, though weird, to have a
>> parameter or variable named `int`).
>>
>> 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] (Un)Expected compiler behavior on named/unnamed parameters of interface functions

2017-08-11 Thread Penguin Enormous
My eyes has just been opened. Silly me, I get it now. Thank you very much.

May I ask which section in the Language Specification 
 mention this allowance of int (or float64, 
... etc.) for use as identifier names?

On Saturday, August 12, 2017 at 1:30:04 AM UTC+7, Ian Lance Taylor wrote:
>
> On Fri, Aug 11, 2017 at 11:03 AM, Penguin Enormous 
> > wrote: 
> > 
> > I think that there is inconsistency in the way Go compiler report error 
> > regarding name/unnamed parameters. This is a bit hard for me to explain 
> in 
> > words so please check out this short snippet first: 
> > 
> > https://play.golang.org/p/Sg0DtCtgF2 
> > 
> > Is this unexpected behavior or it's just me that's feeling strange? 
>
> Go does not permit mixing named and unnamed parameters in a parameter 
> list. 
>
> In a declaration like Run(int, f float64) you have two parameters of 
> type `float64`.  The first parameter is named `int` and the second 
> parameter is named `f`.  (The essential point here, of course, is that 
> in Go `int` is not a keyword, and it's OK, though weird, to have a 
> parameter or variable named `int`). 
>
> 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] (Un)Expected compiler behavior on named/unnamed parameters of interface functions

2017-08-11 Thread Ian Lance Taylor
On Fri, Aug 11, 2017 at 11:03 AM, Penguin Enormous
 wrote:
>
> I think that there is inconsistency in the way Go compiler report error
> regarding name/unnamed parameters. This is a bit hard for me to explain in
> words so please check out this short snippet first:
>
> https://play.golang.org/p/Sg0DtCtgF2
>
> Is this unexpected behavior or it's just me that's feeling strange?

Go does not permit mixing named and unnamed parameters in a parameter list.

In a declaration like Run(int, f float64) you have two parameters of
type `float64`.  The first parameter is named `int` and the second
parameter is named `f`.  (The essential point here, of course, is that
in Go `int` is not a keyword, and it's OK, though weird, to have a
parameter or variable named `int`).

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] Why can't we do timer related works in sysmon rather than another timer goroutine?

2017-08-11 Thread Ian Lance Taylor
On Thu, Aug 10, 2017 at 10:32 PM, Cholerae Hu  wrote:
> Currently if we use timer or something, runtime will start a new goroutine
> to do timerproc works. Why can't we check timer heap in each iteration of
> sysmon if any timer exists? This may reduce some context switchs, I think.

A significant complexity would be that the sysmon thread runs without
a p, but the timer goroutine is just a normal goroutine.  That means
that the either the sysmon thread can not directly invoke the
functions on the timer heap, or those functions have to be carefully
written and audited to be able to run without a p (which implies, for
example, that they can not allocate memory).

I would be surprised if we see any performance benefit sufficient to
justify the increase in complexity.

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] (Un)Expected compiler behavior on named/unnamed parameters of interface functions

2017-08-11 Thread Penguin Enormous
I think that there is inconsistency in the way Go compiler report error 
regarding name/unnamed parameters. This is a bit hard for me to explain in 
words so please check out this short snippet first:

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

Is this unexpected behavior or it's just me that's feeling strange?

-- 
You received this message because you are subscribed to the Google 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 can I decrypt "ENCRYPTED PRIVATE KEY" using golang

2017-08-11 Thread Konstantin Khomoutov
On Fri, Aug 11, 2017 at 12:30:56AM -0700, terry.an...@gmail.com wrote:

> My private key is generated by "openssl req -new -x509 -keyout a.key -out 
> a.crt -days 3650" with password.
> 
> And I tried to decrypted it by x509.DecryptPEMBlock(keyBlock, password), 
> but failure.  error message: %!(EXTRA *errors.errorString=x509: no DEK-Info 
> header in block)
> 
> my privatekey is in below, and password is '123456'
> 
> anyone else can help me ? 
> 
> -BEGIN ENCRYPTED PRIVATE KEY-
> MIIFDjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQIQgjjAaLRMbsCAggA
> MBQGCCqGSIb3DQMHBAi4V74SzJ52kwSCBMiZ7gONJxBWnJsqaiyhDBvLrMQW5c/G
[...]

As you can see in [1], typically a PEM-encoded encrypted key indeed
contains a header block detailing how it was encoded, like this:

  -BEGIN RSA PRIVATE KEY-
  Proc-Type: 4,ENCRYPTED
  DEK-Info: DES-EDE3-CBC,02306CD22AAC94CD
  ...

As you can gather from the accepted answer in [1], `openssl req`
uses DES-EDE3-CBC.

I don't know what to do but I see two ways to attack this:

* Decode the PEM (it's just a base64 encoding of a DER-encoded stream
  IIRC) and then try decoding it with some API function which allows
  specifying the encryption type directly.

* Try monkey-patching the PEM data by a bogus DEK-Info header.

1. https://security.stackexchange.com/q/93417

-- 
You received this message because you are subscribed to the Google 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: Calling Once (in the code)

2017-08-11 Thread Egon
Note, this can fragment the code and make it harder to understand... 
(http://number-none.com/blow/john_carmack_on_inlined_code.html)

As for the tool:

guru can give you the callers of a function, so you might be able to derive 
something from it.

+ Egon

On Friday, 11 August 2017 10:39:16 UTC+3, dc0d wrote:
>
> "When you feel the need to write a comment, first try to refactor the code 
> so that any comment becomes superfluous."
> - Martin Fowler, Kent Beck, John Brant, William Opdyke, and Don Roberts 
> (1999) Refactoring: Improving the Design of Existing Code. Addison-Wesley.
>
> Based on this practice, the code below (this code's sole purpose is to 
> demonstrate):
>
> func sampleSloppyFuncForDescribingThisSpecificProblem(data *Data, p *DLO) 
> error {
> if !isNameOK(data.FirstName, data.MiddleName, data.LastName) {
> return errInvalidName
> }
>
> if !isAddressOK(data.Address1, data.Address2) {
> return errInvalidAddress
> }
>
> if !isPhoneOK(data.PhoneNumber, data.MobileNumber) {
> return errInvalidPhone
> }
>
> p.Address1 = data.Address1
> p.Address2 = data.Address2
> p.BirthDate = data.BirthDate
> p.FirstName = data.FirstName
> p.LastName = data.LastName
> p.MiddleName = data.MiddleName
> p.MobileNumber = data.MobileNumber
> p.PhoneNumber = data.PhoneNumber
>
> return nil
> }
>
> Can get refactored to (instead of adding comments):
>
> func sampleSloppyFuncForDescribingThisSpecificProblem(data *Data, p *DLO) 
> error {
> if err := validateData(data); err != nil {
> return err
> }
>
> transferData(data, p)
>
> return nil
> }
>
> func validateData(data *Data) error {
> if !isNameOK(data.FirstName, data.MiddleName, data.LastName) {
> return errInvalidName
> }
>
> if !isAddressOK(data.Address1, data.Address2) {
> return errInvalidAddress
> }
>
> if !isPhoneOK(data.PhoneNumber, data.MobileNumber) {
> return errInvalidPhone
> }
>
> return nil
> }
>
> func transferData(data *Data, p *DLO) {
> p.Address1 = data.Address1
> p.Address2 = data.Address2
> p.BirthDate = data.BirthDate
> p.FirstName = data.FirstName
> p.LastName = data.LastName
> p.MiddleName = data.MiddleName
> p.MobileNumber = data.MobileNumber
> p.PhoneNumber = data.PhoneNumber
> }
>
> Now the sole purpose of functions validateData and transferData is 
> providing a clean and more descriptive code. They should appear only in one 
> place in the code inside the body of 
> sampleSloppyFuncForDescribingThisSpecificProblem. This is what I need to 
> check.
>
> On Friday, August 11, 2017 at 8:57:46 AM UTC+4:30, Henry wrote:
>>
>> I don't fully understand the problem, but if you need a quick and dirty 
>> way to ensure a function is called exactly once, you can always use a 
>> global variable, have the function checks the variable when the function is 
>> called. If the function is called the first time, it will set the variable. 
>> If the function has been called more than once, it should panic and returns 
>> the stacktrace.
>>
>> On Friday, August 11, 2017 at 3:02:47 AM UTC+7, dc0d wrote:
>>>
>>> Is there a tool/linter to check if a private package function gets 
>>> called exactly once *in the code*? (I'm not looking for a runtime 
>>> solution like *sync.Once* but a code analysis tool/linter).
>>>
>>> Purpose: A guideline on commenting code by Martin Fowler states that 
>>> before writing a comment, see if it is possible to put that part inside a 
>>> meaningful function. I've followed that guideline for sometime and it helps 
>>> to have a cleaner code base. But those explanatory functions should get 
>>> called only from where that they are meant to make it more clear.
>>>
>>

-- 
You received this message because you are subscribed to the Google 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] how can I decrypt "ENCRYPTED PRIVATE KEY" using golang

2017-08-11 Thread terry . an . bj
My private key is generated by "openssl req -new -x509 -keyout a.key -out 
a.crt -days 3650" with password.

And I tried to decrypted it by x509.DecryptPEMBlock(keyBlock, password), 
but failure.  error message: %!(EXTRA *errors.errorString=x509: no DEK-Info 
header in block)

my privatekey is in below, and password is '123456'

anyone else can help me ? 


-BEGIN ENCRYPTED PRIVATE KEY-
MIIFDjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQIQgjjAaLRMbsCAggA
MBQGCCqGSIb3DQMHBAi4V74SzJ52kwSCBMiZ7gONJxBWnJsqaiyhDBvLrMQW5c/G
qdoGCChEHrKV2ndr0MKTJM5xuGUk+dtrAbezosFBb+6511HOzBReM6beQ+bEPRUe
zV7GQYozeCt7+Be/vM+PmcV9s7C6MsBD2iHV6An7TeVSbJMJWJxyXT7jI7w+N7Or
dS0SUSlCGBd0IoI+cMPyGdNLJat3ZaoNPKnM7R3/0dmSk0AkEF7Kdu83m6oByNZy
dlXEOSffeSfgN8g/CX2Sih1Bx1646WUZ3VzWWPbJxsg7Hr34TfDA/+uU/MtGi9AL
W1gfaTpj5Lsz1h6Gtw/0GVLoeloJj/I28P/aWHq26wfxbSo03gQkFaPedZh+M1Rp
75VGrx10MwM4a669P7suUMPAiPWk8fD5m8xinchcp82EuH0YINtjKXOgpvETQj3X
qDyZuxfDShJ899dRRB6NK1cdKcjXoofrYdIREBFrfOZbgEZRIozLhgp5/1B8f1Cp
sD+sqhH/7uhJQLFQ8ce9BlnsooURqe0z7sCQd+nQT93TvnRTJsiHt3bzz+UPN7pz
WHCTZ5Hq5uwswfUqszVGRX/LbVYeXSSCkzzBBKhB8jQPxokklyrH4QkDcupy7HP1
m2/S1I0H5662nv0BOFrssMQVYBtGWThVrskaJccyA4GSiMX4f1XjtXku6jzphkvO
PHnCFMfpYsV8hDWOyULZacdkKxN5BO/M45qmTxrNKnSKtI4bbjO3AG0uE/3SmhK2
RjUXbX/rXKTfcHb4F2Ur4cMb6mMBzZqA92vw2aZLr49DQERuhaCmgcIBAB27fO7X
Umg/DLyB0Qj0X02Pc/BPBMfdLl2nBxcBkKUlRqt01jkINwiMed161G3rf7HbzHiT
Y41VfWlocc5iYxKnKFUVLCPHBwHAx5oIG4Wsa9REmzvtssBOt/4bts25ZVsU/MDa
ic4cX1wL65BwxUBmD2XUifB+107vF9gbIz4U/nd5DkfeKoXxAM+kdpoS5+Th1rGn
7NHJMP658bwDI4le7Z5snrWWm8fZCVmWJKQPE5bklImuJic7PW8+nHLNhhzArGnf
1RXWS1imGNTJBEsxwc93EPc+h6N3laXusuZrNdRKNnGWvpZpGxEPAXrX+BtPzgNj
EOJyDn/VXMV0lUXKVKjlFDmmuvB5oquq/j2LGze6xbgDWOI7wHP3DWmLw/RhNrTo
DWGg4n3pnU9yb1vEhM/F8JF/HgjiDeAn6VMWNoVYlgsfkWrHC4oTHp3dywg2LDw7
4CgoD+XIU4ogYqxOCKhk5N71P29Jvrwj/eiwH+H2QSDlyeLR0CcEH2YxoGmwVdKc
S6bSvWuxCAcxOA4/k8d77aGvobGOkzFtYmKEbxgqUXgtrSfhIIijICV69vWVQjW9
7EGJVg1Vz/niGt/Mj6iPX84sBxt8Y/xiEfWas0rvEUf1osJK8lXrobIh5LfwQN7T
0CGUhA03Sbk4x5BkXHjBEaWmqf17GLlVnveV+sMLcFt6QhLcn1ZVcMFNJdsRzWne
2z0suse9iDROUVnRDIuixodjMoT5pWaFOoSCzhlVZO8OXzp6VjK5rD/3Kgagw0Gd
HgCa9oxd3Jf7qndTxbBx2uwrAkK26NXBMTj291Z9y3+KdnBGGAVBc3M3wf5PrWM4
ed4=
-END ENCRYPTED PRIVATE KEY-

-- 
You received this message because you are subscribed to the Google 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: Calling Once (in the code)

2017-08-11 Thread dc0d
As he cleared up in his later quotes and tweets it's about replacing 
comments with functions. IMHO this way comments will turn into active 
(code) specifications and would help greatly specially in a statically 
types languages. They might even make writing more clear tests easier. But 
(IMHO) having more functions does not necessarily means having better 
reusable code.

In this case the functions in question are *private* functions in a package 
and their sole purpose is to replace comments in another (one specific) 
function.

On Friday, August 11, 2017 at 4:43:29 PM UTC+4:30, Henry wrote:
>
> I am not aware of any such tools exist. You may need to roll out your own. 
>
> However, don't you think that the purpose of Fowler,et al. proposing such 
> guideline is to encourage function reuse?
>
> On Friday, August 11, 2017 at 2:39:16 PM UTC+7, dc0d wrote:
>
>> "When you feel the need to write a comment, first try to refactor the 
>> code so that any comment becomes superfluous."
>> - Martin Fowler, Kent Beck, John Brant, William Opdyke, and Don Roberts 
>> (1999) Refactoring: Improving the Design of Existing Code. Addison-Wesley.
>>
>> Based on this practice, the code below (this code's sole purpose is to 
>> demonstrate):
>>
>> func sampleSloppyFuncForDescribingThisSpecificProblem(data *Data, p *DLO) 
>> error {
>> if !isNameOK(data.FirstName, data.MiddleName, data.LastName) {
>> return errInvalidName
>> }
>>
>> if !isAddressOK(data.Address1, data.Address2) {
>> return errInvalidAddress
>> }
>>
>> if !isPhoneOK(data.PhoneNumber, data.MobileNumber) {
>> return errInvalidPhone
>> }
>>
>> p.Address1 = data.Address1
>> p.Address2 = data.Address2
>> p.BirthDate = data.BirthDate
>> p.FirstName = data.FirstName
>> p.LastName = data.LastName
>> p.MiddleName = data.MiddleName
>> p.MobileNumber = data.MobileNumber
>> p.PhoneNumber = data.PhoneNumber
>>
>> return nil
>> }
>>
>> Can get refactored to (instead of adding comments):
>>
>> func sampleSloppyFuncForDescribingThisSpecificProblem(data *Data, p *DLO) 
>> error {
>> if err := validateData(data); err != nil {
>> return err
>> }
>>
>> transferData(data, p)
>>
>> return nil
>> }
>>
>> func validateData(data *Data) error {
>> if !isNameOK(data.FirstName, data.MiddleName, data.LastName) {
>> return errInvalidName
>> }
>>
>> if !isAddressOK(data.Address1, data.Address2) {
>> return errInvalidAddress
>> }
>>
>> if !isPhoneOK(data.PhoneNumber, data.MobileNumber) {
>> return errInvalidPhone
>> }
>>
>> return nil
>> }
>>
>> func transferData(data *Data, p *DLO) {
>> p.Address1 = data.Address1
>> p.Address2 = data.Address2
>> p.BirthDate = data.BirthDate
>> p.FirstName = data.FirstName
>> p.LastName = data.LastName
>> p.MiddleName = data.MiddleName
>> p.MobileNumber = data.MobileNumber
>> p.PhoneNumber = data.PhoneNumber
>> }
>>
>> Now the sole purpose of functions validateData and transferData is 
>> providing a clean and more descriptive code. They should appear only in one 
>> place in the code inside the body of 
>> sampleSloppyFuncForDescribingThisSpecificProblem. This is what I need to 
>> check.
>>
>> On Friday, August 11, 2017 at 8:57:46 AM UTC+4:30, Henry wrote:
>>>
>>> I don't fully understand the problem, but if you need a quick and dirty 
>>> way to ensure a function is called exactly once, you can always use a 
>>> global variable, have the function checks the variable when the function is 
>>> called. If the function is called the first time, it will set the variable. 
>>> If the function has been called more than once, it should panic and returns 
>>> the stacktrace.
>>>
>>> On Friday, August 11, 2017 at 3:02:47 AM UTC+7, dc0d wrote:

 Is there a tool/linter to check if a private package function gets 
 called exactly once *in the code*? (I'm not looking for a runtime 
 solution like *sync.Once* but a code analysis tool/linter).

 Purpose: A guideline on commenting code by Martin Fowler states that 
 before writing a comment, see if it is possible to put that part inside a 
 meaningful function. I've followed that guideline for sometime and it 
 helps 
 to have a cleaner code base. But those explanatory functions should get 
 called only from where that they are meant to make it more clear.

>>>

-- 
You received this message because you are subscribed to the Google 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 channels overused and hyped?

2017-08-11 Thread Chris Hopkins
[sorry for the side question but:]
When there is the "channels are expensive" consideration, I assume that is 
from a latency perspective rather than a throughput perspective.
i.e. it was my understanding that channels had a small overhead on top of a 
basic lock, but otherwise added very little workload. The microsecond or so 
of cost you see I understood was *not* due to there being thousands of 
operations needed to run the channel, but the latency added by the stall, 
and scheduler overhead.
I also understood that in the case of an uncontested buffered partially 
full channel*, the cost of a channel was effectively that of checking the 
head and tail pointers; therefore as close to nothing as makes no 
difference.

* I know this is a rare case, but I'd also argue it's the only interesting 
one in data flow applications if you're concerned about the latency as in 
other cases you will have a contested lock and therefore the overhead of 
the locking will dominate. (I'm not wanting to worry at the moment about 
say a lock on a shared data structure (state table?) that is modified 
infrequently as I'd be surprised if this was done by channels in most 
applications)

If that makes sense?

Regards


On Friday, 11 August 2017 12:58:54 UTC+1, Jesper Louis Andersen wrote:
>
> On Tue, Aug 8, 2017 at 8:01 AM snmed > 
> wrote:
>
>>
>> I stumbled over a nice and very interesting Blog entry "Go channels are 
>> bad and you should feel bad 
>> "
>>  
>> , I would like to hear some opinions about that article
>> from seasoned go developers. Because I just used go for a couple of 
>> months for my private web projects and rarely get in touch with channels.
>>
>>
> One way of putting it is that any synchronization/communication primitive 
> will have an overhead in a system. Channels are "fairly expensive" compared 
> to other methods. But if the processing you are doing is going to take 
> orders of magnitude more time than the channel communication, then you can 
> usually benefit from channels having some extra features in them, 
> especially w.r.t. system correctness: they are often easier to program with.
>
> You can create an exaggerated situation: suppose you are in the EU and you 
> decide that you want to distribute your system. You buy a server in 
> Australia. Imagine you have a mythical failure free connection to Australia 
> and you are doing RPC. You are easily looking at 300+ ms roundtrip times. 
> If the task you execute on the Australian server is "add two numbers", then 
> the 300ms overhead is a problem.
>
> But, if the task you are shipping to Australia is an NP-complete route 
> planning you want solved to optimality, you are easily looking at hours of 
> processing time. And then 300ms seems pretty quick!
>
> Channels work much the same, but the window is at the microsecond level. 
> If you protect an operation in the nanosecond scale by a channel, then the 
> channel overhead will dominate. But if you require milliseconds of 
> processing time, then a channel is fairly cheap.
>
> Note that any communication to the outside world is likely to be on the 
> millisecond scale, and that makes channels excellent as a tool to handle an 
> operation which block on some foreign input. 
>

-- 
You received this message because you are subscribed to the Google 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: Calling Once (in the code)

2017-08-11 Thread Henry
I am not aware of any such tools exist. You may need to roll out your own. 

However, don't you think that the purpose of Fowler,et al. proposing such 
guideline is to encourage function reuse?

On Friday, August 11, 2017 at 2:39:16 PM UTC+7, dc0d wrote:

> "When you feel the need to write a comment, first try to refactor the code 
> so that any comment becomes superfluous."
> - Martin Fowler, Kent Beck, John Brant, William Opdyke, and Don Roberts 
> (1999) Refactoring: Improving the Design of Existing Code. Addison-Wesley.
>
> Based on this practice, the code below (this code's sole purpose is to 
> demonstrate):
>
> func sampleSloppyFuncForDescribingThisSpecificProblem(data *Data, p *DLO) 
> error {
> if !isNameOK(data.FirstName, data.MiddleName, data.LastName) {
> return errInvalidName
> }
>
> if !isAddressOK(data.Address1, data.Address2) {
> return errInvalidAddress
> }
>
> if !isPhoneOK(data.PhoneNumber, data.MobileNumber) {
> return errInvalidPhone
> }
>
> p.Address1 = data.Address1
> p.Address2 = data.Address2
> p.BirthDate = data.BirthDate
> p.FirstName = data.FirstName
> p.LastName = data.LastName
> p.MiddleName = data.MiddleName
> p.MobileNumber = data.MobileNumber
> p.PhoneNumber = data.PhoneNumber
>
> return nil
> }
>
> Can get refactored to (instead of adding comments):
>
> func sampleSloppyFuncForDescribingThisSpecificProblem(data *Data, p *DLO) 
> error {
> if err := validateData(data); err != nil {
> return err
> }
>
> transferData(data, p)
>
> return nil
> }
>
> func validateData(data *Data) error {
> if !isNameOK(data.FirstName, data.MiddleName, data.LastName) {
> return errInvalidName
> }
>
> if !isAddressOK(data.Address1, data.Address2) {
> return errInvalidAddress
> }
>
> if !isPhoneOK(data.PhoneNumber, data.MobileNumber) {
> return errInvalidPhone
> }
>
> return nil
> }
>
> func transferData(data *Data, p *DLO) {
> p.Address1 = data.Address1
> p.Address2 = data.Address2
> p.BirthDate = data.BirthDate
> p.FirstName = data.FirstName
> p.LastName = data.LastName
> p.MiddleName = data.MiddleName
> p.MobileNumber = data.MobileNumber
> p.PhoneNumber = data.PhoneNumber
> }
>
> Now the sole purpose of functions validateData and transferData is 
> providing a clean and more descriptive code. They should appear only in one 
> place in the code inside the body of 
> sampleSloppyFuncForDescribingThisSpecificProblem. This is what I need to 
> check.
>
> On Friday, August 11, 2017 at 8:57:46 AM UTC+4:30, Henry wrote:
>>
>> I don't fully understand the problem, but if you need a quick and dirty 
>> way to ensure a function is called exactly once, you can always use a 
>> global variable, have the function checks the variable when the function is 
>> called. If the function is called the first time, it will set the variable. 
>> If the function has been called more than once, it should panic and returns 
>> the stacktrace.
>>
>> On Friday, August 11, 2017 at 3:02:47 AM UTC+7, dc0d wrote:
>>>
>>> Is there a tool/linter to check if a private package function gets 
>>> called exactly once *in the code*? (I'm not looking for a runtime 
>>> solution like *sync.Once* but a code analysis tool/linter).
>>>
>>> Purpose: A guideline on commenting code by Martin Fowler states that 
>>> before writing a comment, see if it is possible to put that part inside a 
>>> meaningful function. I've followed that guideline for sometime and it helps 
>>> to have a cleaner code base. But those explanatory functions should get 
>>> called only from where that they are meant to make it more clear.
>>>
>>

-- 
You received this message because you are subscribed to the Google 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] Regexp documentation error?

2017-08-11 Thread Jesse McNelis
On Fri, Aug 11, 2017 at 9:03 PM, Jens Hausherr  wrote:
> I see,
>
> I was just confused by the fact that fmt.Printf("%q/%v") apparently renders
> a nil array as an empty array ([]) while rendering other nil values (e.g.
> pointers) as .

Yep, a nil slice is also an empty slice. You can check it's length
(which will be zero), check it's capacity(which will be zero), range
over all the items it contains (which will be zero) and append items
to 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.


Re: [go-nuts] Go channels overused and hyped?

2017-08-11 Thread Jesper Louis Andersen
On Tue, Aug 8, 2017 at 8:01 AM snmed  wrote:

>
> I stumbled over a nice and very interesting Blog entry "Go channels are
> bad and you should feel bad
> "
> , I would like to hear some opinions about that article
> from seasoned go developers. Because I just used go for a couple of months
> for my private web projects and rarely get in touch with channels.
>
>
One way of putting it is that any synchronization/communication primitive
will have an overhead in a system. Channels are "fairly expensive" compared
to other methods. But if the processing you are doing is going to take
orders of magnitude more time than the channel communication, then you can
usually benefit from channels having some extra features in them,
especially w.r.t. system correctness: they are often easier to program with.

You can create an exaggerated situation: suppose you are in the EU and you
decide that you want to distribute your system. You buy a server in
Australia. Imagine you have a mythical failure free connection to Australia
and you are doing RPC. You are easily looking at 300+ ms roundtrip times.
If the task you execute on the Australian server is "add two numbers", then
the 300ms overhead is a problem.

But, if the task you are shipping to Australia is an NP-complete route
planning you want solved to optimality, you are easily looking at hours of
processing time. And then 300ms seems pretty quick!

Channels work much the same, but the window is at the microsecond level. If
you protect an operation in the nanosecond scale by a channel, then the
channel overhead will dominate. But if you require milliseconds of
processing time, then a channel is fairly cheap.

Note that any communication to the outside world is likely to be on the
millisecond scale, and that makes channels excellent as a tool to handle an
operation which block on some foreign input.

-- 
You received this message because you are subscribed to the Google 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] godoc.or is unreachable from Germany

2017-08-11 Thread Jan Mercl
On Fri, Aug 11, 2017 at 11:47 AM Norbert Fuhs 
wrote:

> it seems https://godoc.org/ is unreachable from Germany.

Works from Germany now.

-- 

-j

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


Re: [go-nuts] Regexp documentation error?

2017-08-11 Thread Jens Hausherr
I see,

I was just confused by the fact that fmt.Printf("%q/%v") apparently renders
a nil array as an empty array ([]) while rendering other nil values (e.g.
pointers) as .

Thanks for the clarification.

Jan Mercl <0xj...@gmail.com> schrieb am Fr., 11. Aug. 2017 um 12:50 Uhr:

> On Fri, Aug 11, 2017 at 12:43 PM Jens Hausherr 
> wrote:
>
> > Is the documentation wrong in this case or am I just missing the case
> where nil is returned?
>
> The docs are correct: https://play.golang.org/p/6fiID64IAt
>
>
> --
>
> -j
>

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


Re: [go-nuts] Regexp documentation error?

2017-08-11 Thread Jan Mercl
On Fri, Aug 11, 2017 at 12:43 PM Jens Hausherr  wrote:

> Is the documentation wrong in this case or am I just missing the case
where nil is returned?

The docs are correct: https://play.golang.org/p/6fiID64IAt


-- 

-j

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


[go-nuts] Regexp documentation error?

2017-08-11 Thread Jens Hausherr
Hi,

I was using some Regexp and noted that all functions are documented to 
return 'nil' if the RE does not match.

I was using FindSubmatchString(s string) ad got an empty string array when 
the expression did not match a string.

Example: https://play.golang.org/p/_kSYXM5e_j

Is the documentation wrong in this case or am I just missing the case where 
nil is returned?

Regards
Jens


-- 
You received this message because you are subscribed to the Google 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: Why can't we do timer related works in sysmon rather than another timer goroutine?

2017-08-11 Thread Chris Hopkins
I had written a really long answer, but I suspect I may be misunderstanding 
what you are proposing. (Apologies if I misunderstand you here, but if I am 
misunderstanding you, then my long answer would have been even more 
patronising than i worry this already is.)

You have some code you wish to run each timer event. In a large system 
there may be a great many things that you want to run on some multiple 
count of this timer event.

At the moment the code you wish to run is in a go routine that (I am 
assuming) waits for a channel event to run. Therefore you have many 
routines waiting to be triggered by a number of channel events. 
Instead you believe it would be better to register a (lambda?) function you 
wish to run on each timer event so that rather than having to do a full cpu 
context swap between threads, you could instead simply jump to the code 
that needs running.

Best Regards

Chris


On Friday, 11 August 2017 06:32:33 UTC+1, Cholerae Hu wrote:
>
> Currently if we use timer or something, runtime will start a new goroutine 
> to do timerproc works. Why can't we check timer heap in each iteration of 
> sysmon if any timer exists? This may reduce some context switchs, I think.
>

-- 
You received this message because you are subscribed to the Google 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] godoc.or is unreachable from Germany

2017-08-11 Thread Henrik Johansson
Not just there. I got internal server error.

On Fri, 11 Aug 2017, 11:47 Norbert Fuhs,  wrote:

> Hi,
>
> it seems https://godoc.org/  is unreachable from Germany.
>
> Its also noted on Go Forums:
> https://forum.golangbridge.org/t/godoc-org-is-down/6265
>
>
> --
> You received this message because you are subscribed to the Google 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] godoc.or is unreachable from Germany

2017-08-11 Thread Norbert Fuhs
Hi,

it seems https://godoc.org/  is unreachable from Germany.

Its also noted on Go Forums: 
https://forum.golangbridge.org/t/godoc-org-is-down/6265


-- 
You received this message because you are subscribed to the Google 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: Code Review - Applying functions on custom types

2017-08-11 Thread Egon
I've suggested this approach based in the slack, adding it here as well to 
make it searchable.

Implement Reader/Writer such that you can do:

func ProcessLine(in *Reader, out *Writer) error {
start, finish, participant := in.Float64(), in.Float64(), in.String()
if err := in.Err(); err != nil {
return err
}

out.String(participant)
out.Float64(finish - start)
return nil
}

+ Egon

On Thursday, 10 August 2017 19:17:04 UTC+3, Sofiane Cherchalli wrote:
>
> Hi Medina,
>
> Sorry I was on vacations.
>
> So do you mean the way to do it is to hardcode most of functionality. No 
> need to use custom types, interfaces. Just plain text parsing?
>
> In that case, how easy is it to evolve or refactor the code?
>
> Thanks
>
> On Wednesday, July 26, 2017 at 8:36:15 PM UTC+2, Diego Medina wrote:
>>
>> I think we have a similar setup to what you are trying to do, we also 
>> started with Scala and about 3 years ago we moved it to Go (still use Scala 
>> for other parts of our app).
>>
>> While working in Scala and other languages you are encourage to abstract 
>> things as much as you can, in Go it is often better to just address the 
>> issues/requirements at hand and be clear on what you are doing.
>> In our case we define a struct that has the expected fields and types for 
>> each column, and as we walk each row, we check that we get the expected 
>> type, then it's a matter of cleaning/adjusting values as we need to, assign 
>> the result of this cell to a variable and continue with the rest of the 
>> cells on this row, once done, we initialize our struct and save it to the 
>> database, move to the next row and repeat.
>>
>> Hope it helps.
>>
>>
>> On Wednesday, July 26, 2017 at 10:09:07 AM UTC-4, Sofiane Cherchalli 
>> wrote:
>>>
>>> The schema is statically specified. The values always arrive in a 
>>> defined order. Each value has a defined type.
>>>
>>> On Tuesday, July 25, 2017 at 3:01:14 AM UTC+2, rog wrote:

 On 24 July 2017 at 23:21, Sofiane Cherchalli  wrote:

> Yes, I'm trying to stream CSV values encoded in strings. A schema 
> defines a type of each value, so I have to parse values to verify they 
> match the type. Once validation is done, I apply functions on each value.
>

 Is the schema dynamically or statically specified? That is, do you know
 in advance what the schema is, or do are you required to write
 general code that deals with many possible schemas?




-- 
You received this message because you are subscribed to the Google 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: Calling Once (in the code)

2017-08-11 Thread dc0d
"When you feel the need to write a comment, first try to refactor the code 
so that any comment becomes superfluous."
- Martin Fowler, Kent Beck, John Brant, William Opdyke, and Don Roberts 
(1999) Refactoring: Improving the Design of Existing Code. Addison-Wesley.

Based on this practice, the code below (this code's sole purpose is to 
demonstrate):

func sampleSloppyFuncForDescribingThisSpecificProblem(data *Data, p *DLO) 
error {
if !isNameOK(data.FirstName, data.MiddleName, data.LastName) {
return errInvalidName
}

if !isAddressOK(data.Address1, data.Address2) {
return errInvalidAddress
}

if !isPhoneOK(data.PhoneNumber, data.MobileNumber) {
return errInvalidPhone
}

p.Address1 = data.Address1
p.Address2 = data.Address2
p.BirthDate = data.BirthDate
p.FirstName = data.FirstName
p.LastName = data.LastName
p.MiddleName = data.MiddleName
p.MobileNumber = data.MobileNumber
p.PhoneNumber = data.PhoneNumber

return nil
}

Can get refactored to (instead of adding comments):

func sampleSloppyFuncForDescribingThisSpecificProblem(data *Data, p *DLO) 
error {
if err := validateData(data); err != nil {
return err
}

transferData(data, p)

return nil
}

func validateData(data *Data) error {
if !isNameOK(data.FirstName, data.MiddleName, data.LastName) {
return errInvalidName
}

if !isAddressOK(data.Address1, data.Address2) {
return errInvalidAddress
}

if !isPhoneOK(data.PhoneNumber, data.MobileNumber) {
return errInvalidPhone
}

return nil
}

func transferData(data *Data, p *DLO) {
p.Address1 = data.Address1
p.Address2 = data.Address2
p.BirthDate = data.BirthDate
p.FirstName = data.FirstName
p.LastName = data.LastName
p.MiddleName = data.MiddleName
p.MobileNumber = data.MobileNumber
p.PhoneNumber = data.PhoneNumber
}

Now the sole purpose of functions validateData and transferData is 
providing a clean and more descriptive code. They should appear only in one 
place in the code inside the body of 
sampleSloppyFuncForDescribingThisSpecificProblem. This is what I need to 
check.

On Friday, August 11, 2017 at 8:57:46 AM UTC+4:30, Henry wrote:
>
> I don't fully understand the problem, but if you need a quick and dirty 
> way to ensure a function is called exactly once, you can always use a 
> global variable, have the function checks the variable when the function is 
> called. If the function is called the first time, it will set the variable. 
> If the function has been called more than once, it should panic and returns 
> the stacktrace.
>
> On Friday, August 11, 2017 at 3:02:47 AM UTC+7, dc0d wrote:
>>
>> Is there a tool/linter to check if a private package function gets called 
>> exactly once *in the code*? (I'm not looking for a runtime solution like 
>> *sync.Once* but a code analysis tool/linter).
>>
>> Purpose: A guideline on commenting code by Martin Fowler states that 
>> before writing a comment, see if it is possible to put that part inside a 
>> meaningful function. I've followed that guideline for sometime and it helps 
>> to have a cleaner code base. But those explanatory functions should get 
>> called only from where that they are meant to make it more clear.
>>
>

-- 
You received this message because you are subscribed to the Google 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.