Re: [go-nuts] Go 1.22 code simplification

2024-01-16 Thread David Finkel
I don't know of anything that does those rewrites (and haven't looked), but
it looks like gofmt -s could support it by extending this type-switch:
https://cs.opensource.google/go/go/+/master:src/cmd/gofmt/simplify.go;l=16-103;drc=9b89c380208ea2e85985ee6bf2b1d684274dfa1d

I like the idea of an automatic rewrite of those loop primitives, though.

(it's possible that the x := x case may need type/declaration-location
information that gofmt doesn't have to do robustly, though)

Note: the go fix directory hasn't had any commits since August, so it
doesn't appear to have it either. (that might be the right place for that
rewrite -- although, I think vet also has a suggested fix capacity that
would make sense for any module with the go line set to 1.22+)

On Tue, Jan 16, 2024 at 1:33 AM Amnon  wrote:

> Go 1.22 contains some cool features which will allow us to write simpler
> code.
>
> Would it be possible for gofmt -s to help us do transformations which
> clean up old code such as
> for i := 0; i < n; i++   -> for i := range n
> removing x := x assignments inside range loops
> or updating code to use the new math/rand/v2 API?
>
> If not, has anyone written any refactoring tools to do this?
>
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/91a531a9-5043-4357-b643-d1600dcae119n%40googlegroups.com
> 
> .
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CANrC0BjVSPpqKF%3DUWppq3zS_NNjKvjsjKj6UmaaMy%2BCnrR7q4A%40mail.gmail.com.


Re: [go-nuts] Generic assembly function

2023-12-19 Thread David Finkel
On Thu, Dec 14, 2023 at 10:43 PM Clément Jean 
wrote:

> Hi,
>
> I'm currently learning how to write Go assembly on arm64 and I made the
> following functions:
>
> TEXT ·AddVector16(SB),NOSPLIT,$0-48
> MOVD a+0(FP), R0
> MOVD a+8(FP), R1
> MOVD a+16(FP), R2
> MOVD a+24(FP), R3
> VMOV R0, V0.D[0]
> VMOV R1, V0.D[1]
> VMOV R2, V1.D[0]
> VMOV R3, V1.D[1]
> VADD V1.B16, V0.B16, V0.B16
> VMOV V0.D[0], R0
> VMOV V0.D[1], R1
> MOVD R0, ret+32(FP)
> MOVD R1, ret+40(FP)
> RET
>
> TEXT ·AddVector32(SB),NOSPLIT,$0-96
> MOVD a+0(FP), R0
> MOVD a+8(FP), R1
> MOVD a+16(FP), R2
> MOVD a+24(FP), R3
> MOVD a+32(FP), R4
> MOVD a+40(FP), R5
> MOVD a+48(FP), R6
> MOVD a+56(FP), R7
> VMOV R0, V0.D[0]
> VMOV R1, V0.D[1]
> VMOV R2, V1.D[0]
> VMOV R3, V1.D[1]
> VMOV R4, V2.D[0]
> VMOV R5, V2.D[1]
> VMOV R6, V3.D[0]
> VMOV R7, V3.D[1]
> VADD V2.B16, V0.B16, V0.B16
> VADD V3.B16, V1.B16, V1.B16
> VMOV V0.D[0], R0
> VMOV V0.D[1], R1
> VMOV V1.D[0], R2
> VMOV V1.D[1], R3
> MOVD R0, ret+64(FP)
> MOVD R1, ret+72(FP)
> MOVD R2, ret+80(FP)
> MOVD R3, ret+88(FP)
> RET
> While these work, I'm forced to add the 16 and 32 suffixes. Is there any
> way to have only one function name and link the assembly to something like:
> type Uint8x16 [16]uint8
> type Uint8x32 [32]uint8
>
> //go:noescape
> func AddVector[T Uint8x16 | Uint8x32](a, b T) T
> If there is let me know, otherwise is there some other alternatives?
>
>
Unfortunately, I think a suffix is the best you can do without jumping
through some serious (and ugly) hoops.
The generics implementation opted for a "stenciling" approach, (and doesn't
support specializations) so although the symbols do encode the GC shape a
bit.
Here's the design doc for GC Shape Stenciling
https://go.googlesource.com/proposal/+/refs/heads/master/design/generics-implementation-gcshape.md



> Btw any feedback on the assembly is welcome, I'm new 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.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/3224bd47-2747-4e1d-bbc5-4a5c4a300f85n%40googlegroups.com
> 
> .
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CANrC0Bh8ZB2R87pEJJ8eKA%3DZiSRjGpa%2BawjX8vdc0dfCMExuBQ%40mail.gmail.com.


Re: [go-nuts] I need confirmation about whether I'm in front of a linter false positive.

2023-08-14 Thread David Finkel
On Mon, Aug 14, 2023 at 4:54 PM Pablo Caballero  wrote:

> I started working on a Golang project (from my work). The following
> pattern makes the company configured linter to complain with:
> sloppyReassign: re-assignment to `err` can be replaced with `err :=
> myFunc2()` (gocritic)
>
> func myFunc() error {
> ...
> blah, err := getBlah()
> if err != nil {
> return err
> }
> ...
> if err = myFunc2; err != nil {
> return err
> }
> ...
> }
>
> What bothers me the most is the fact that if I listen to the linter and
> change the code according to its suggestion I get another complaint saying
> that I should use the if short version.
>
> Yes, I have found silenced sloppyReassign following this pattern.
>
> What do you think? What linter complaint should I mute? I don't like the
> idea of a code base polluted with instructions to tell the linter to shut
> up. Do you think I should suggest stopping using linters? :)
>
My recommendation is to stop re-using the "err" variable.
I eliminated missed if err != nil checks in my codebases by using unique
names for my error-typed variables. (and reserving the "err" itself for
innermost scopes -- short if statements like the second case you have there)


>
> Thank you!
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/CAPxFe-utkjMEVrc3DtTR5rmsiEuK8ZLvA6d228PjnroaxRtBkw%40mail.gmail.com
> 
> .
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CANrC0Bj5Q6N6otD0QS1i3JFqB9EzPNwYbmTrDOW6PRGxX0Fr8g%40mail.gmail.com.


Re: [go-nuts] Why is runtime.Gosched needed in this single-threaded, no-goroutines cgo program?

2023-02-16 Thread David Finkel
On Wed, Feb 15, 2023 at 4:05 PM Ian Lance Taylor  wrote:

> On Wed, Feb 15, 2023 at 8:42 AM 'Marko Bencun' via golang-nuts
>  wrote:
> >
> > I am running into a a weird error in C code that only materializes
> > when calling it from Go using cgo. I hope you could help me understand
> > this behaviour and why calling runtime.Gosched() seems to resolve the
> > issue. I worry that this may not be the right fix, so I want to
> > understand what is going on.
> >
> > I communicate to a USB HID device and get an error every once in a
> > while, only when using cgo, in around 5% of the messages sent to the
> > device, non-deterministically. The messages sent and received are all
> > the same and work most of the time.
> >
> > The C functions I am calling are hid_write and hid_read from here:
> >
> https://github.com/libusb/hidapi/blob/4ebce6b5059b086d05ca7e091ce04a5fd08ac3ac/mac/hid.c
> >
> > If I call hid_write and hid_read in a loop in a C program, everything
> > works as expected:
> >
> > ```
> > #include "hidapi.h"
> > #include "hidapi_darwin.h"
> >
> > int run(hid_device *handle) {
> > int res;
> >
> > const uint8_t write[64] = "";
> > const uint8_t expected[64] = "";
> > uint8_t read[64] = {0};
> >
> > while(1) {
> > res = hid_write(handle, write, sizeof(write));
> > if(res < 0) return -1;
> > res = hid_read(handle, read, sizeof(read));
> > if(res < 0) return -1;
> > if (memcmp(read, expected, 64)) return -1;
> > }
> >
> > return 0;
> > }
> > ```
> >
> > I ported the above to Go using cgo like below. I link `hid.o`, the
> > same object file used in the C program, to make sure the same code is
> > running to rule out differences in compilation:
> >
> > ```
> > package main
> >
> > import (
> > "bytes"
> > "encoding/hex"
> > )
> >
> > /*
> > #cgo darwin LDFLAGS: -framework IOKit -framework CoreFoundation
> > -framework AppKit hid.o
> > #include "hidapi.h"
> > #include "hidapi_darwin.h"
> > */
> > import "C"
> >
> > func main() {
> > dev := C.hid_open(...)
> > if dev == nil {
> > panic("no device")
> > }
> > write := []byte("")
> > expected := []byte("")
> > b := make([]byte, 64)
> > for {
> > written := C.hid_write(dev, (*C.uchar)([0]),
> C.size_t(len(write)))
> > if written < 0 {
> > panic("error write")
> > }
> > read := C.hid_read(dev, (*C.uchar)([0]), C.size_t(len(b)))
> > if read < 0 {
> > panic("error read")
> > }
> > if !bytes.Equal(b, expected) {
> > panic("not equal")
> > }
> > }
> > }
> > ```
> >
> > The Go program errors on hid_write with a "generic error" error code
> > non-deterministically in about 5% of the messages sent. The USB device
> > receives the message and responds normally however.
> >
> > I randomly tried adding `runtime.Gosched()` at the bottom of the
> > Go-loop, and the issue disappeared completely. I am very confused why
> > that would help, as the Go program has, as far as I can tell, no
> > threads and no goroutines (except main).
> >
> > Other things I have checked:
> >
> > - If I move the loop from Go to C by calling `C.run(dev)` (the looping
> > function defined above) from Go, there is no issue.
> > - LockOSThread: if the loop runs in a goroutine and that goroutine
> > switches OS threads, the issue reappears after some time (not
> > immediately after a thread switch - the error happens
> > non-deterministically) even if `runtime.Gosched()` is called.
> > `runtime.LockOSThread()` is needed to fix it in that case. Since the
> > goroutine is locked to an OS thread during the execution of a C
> > function call anyway, this indicates that either hidapi or the macOS
> > HID functions rely on thread-local vars across multiple C calls in
> > some way, which seems a bit crazy.
> > - In the above code (no goroutines), I checked that the OS thread ID
> > (pthread_self()) is constant for all calls, and yet the issue appears
> > unless runtime.Gosched() is called, which seems to contradict the
> > previous point
> > - I tried multiple Go versions between 1.16 and 1.20 and multiple
> > macOS SDK versions between 10.13 and 13.1, all with the same problem
> > (and same working fix).
> > - only macOS is affected - on linux and Windows, there is no similar
> > issue (these platforms use different C code to interact with the
> > device).
> >
> > Does anyone have any insight into why invoking the scheduler could be
> > necessary here or what could be going on in general? My worry is that
> > using `runtime.LockOSThread()` and `runtime.Gosched()` are not proper
> > fixes.
>
>
> I didn't try to look at this in detail, but I did glance at the C code
> you are calling, and it uses pthread_mutex_lock and friends.  In
> general pthread mutexes must be unlocked by the thread that locked
> them, so it is quite possible that LockOSThread is required for
> correct operation.  I don't have an 

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

2023-02-13 Thread David Finkel
On Mon, Feb 13, 2023 at 6:48 PM Pat Farrell  wrote:

> This won't compile
>
> var ExtRegex =
> regexp.MustCompile("(M|m)(p|P)(3|4))|((F|f)(L|l)(A|a)(C|c))$")
>
> with a
> ./prog.go:10:18:
> regexp.MustCompile("((M|m)(p|P)(3|4))|((F|f)(L|l)(A|a)(C|c))$") (value of
> type *regexp.Regexp) is not constant
>
That error indicates that you wrote `const ExtRegex = `

>
> while
> const pat = "((M|m)(p|P)(3|4))|((F|f)(L|l)(A|a)(C|c))$"
> var ExtRegex = regexp.MustCompile(pat)
>
> Works fine.
> So, why can't the regexp be a constant?
>
 Only primitive types are allowed to be constant in go


> Is there some state that is kept in the regexp.Regexp store?
>
It used to, but that was removed in an earlier version (see the deprecation
notice on regexp.Copy )

>
> And perhaps more importantly, what is the proper go style to
> have a compiled regexp?
> I could put the var statement outside all blocks, so its in effect
> a package variable. But I think having package variable is bad form.
>
For cases like this, I tend to create an unexported package variable that's
initialized with MustCompile.
package-level variables are generally bad-form, but there are cases where
you have mostly-readonly things that must be initialized at startup in
which they make sense. (constant-initialized regexps are one of these)

>
> I'm using the regexp in a loop for all the strings in all the files in a
> directory tree.
> I really don't want to compile them for ever pass thru the lines
>
> Thanks
> Pat
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/39ae6e9f-1c27-45cd-93c2-39a3b75cc6a3n%40googlegroups.com
> 
> .
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CANrC0Bj8UUaNeq0pKrx_xUrDkndaS13e4LBPnp5TdAZctBsG3Q%40mail.gmail.com.


Re: [go-nuts] Silly question about parentheses

2023-02-01 Thread David Finkel
On Wed, Feb 1, 2023 at 11:22 AM Chris Burkert 
wrote:

> Looking into the spec:
>
> https://go.dev/ref/spec#Return_statements
> ReturnStmt = "return" [ ExpressionList ] .
> ExpressionList = Expression { "," Expression } .
> ... no () here
>
> https://go.dev/ref/spec#Function_types
> FunctionType   = "func" Signature .
> Signature  = Parameters [ Result ] .
> Result = *Parameters | Type* .
> Parameters = *"("* [ ParameterList [ "," ] ] *")"* .
> ParameterList  = ParameterDecl { "," ParameterDecl } .
> ParameterDecl  = [ IdentifierList ] [ "..." ] Type .
> ... a *Type* does not need () but *Parameters* needs them.
>
> But now I am puzzled. I can actually omit the variable name for the
> arguments: https://play.golang.com/p/g4Sz8rh06QW.
>
> This seems to be useless, but it is actually allowed, right?
>

It's not useless because sometimes you need to take a specific
parameter-list to satisfy an interface, but that specific implementation
doesn't need that input.
Similarly, when defining a method in an interface
, sometimes the type says it all, so
there's no value in defining a name for the argument.

Note: I'm not saying that one should never name variables in interface
definitions, so much that in some cases, it's clearer with just types.
  There are definitely many interface definitions that are
underspecified without argument-names)


> Am Mi., 1. Feb. 2023 um 17:04 Uhr schrieb Raphael Clancy <
> raphael.cla...@gmail.com>:
>
>> This is really helpful! Thank you!
>>
>> At first I assumed that it was down to 'go fmt' letting you be fairly
>> loose with your syntax and that you could omit parentheses where the
>> meaning wouldn't be ambiguous.  But on closer examination, there must be
>> something else going on because 'return a, b' works fine and 'return (a,
>> b)' generates an error. But, both 'func(a string) string {}' and  'func(a
>> string) (string){}' work fine.
>>
>> Maybe it's because 'return' isn't really a function call and has it's own
>> syntax?
>>
>> On Wednesday, February 1, 2023 at 8:13:10 AM UTC-7
>> axel.wa...@googlemail.com wrote:
>>
>>> Good point, didn't think of that
>>>
>>> On Wed, Feb 1, 2023, 15:30 p...@morth.org  wrote:
>>>
 It would actually be ambiguous in the very place they're required.

 Consider this not completely unreasonable example:
 https://go.dev/play/p/OL0uOnPZXju

 Also, with generics it could be ambiguous in type parameters.
 To summarize, parentheses are needed around the return types because
 otherwise anywhere a list of types is used, it would be ambiguous.

 Regards,
 Per Johansson

 On Tuesday, January 31, 2023 at 8:38:46 PM UTC+1
 axel.wa...@googlemail.com wrote:

> I'm not sure there really is a "reason", per se. The language could
> just as well have been designed not to require parentheses around the
> return types (at least I see no parsing ambiguity with that, though there
> might be) or designed to require parentheses in the return statement. It
> probably just felt more intuitive and readable to the designers at the 
> time.
>
> FWIW I find it more interesting that `func() T` requires no
> parentheses, but `func() (S, T)` does.
>
> On Tue, Jan 31, 2023 at 5:55 PM Raphael Clancy 
> wrote:
>
>> Hey all, I figured it was time to move to a "modern" language and I
>> thought I'd give go a try. So far, I'm really enjoying it. I'm just 
>> getting
>> started and I had a question about parentheses. Though, I guess it's 
>> really
>> about how go parses lines of code and what counts as a delimiter.
>>
>> Anyway, in the get started section on error handling
>> , why are parentheses
>> required around string and error here:
>>
>> func Hello(name string) (string, error) {...
>>
>> but not around message and nil here:
>>
>> return message, nil
>>
>> I tried searching a bit but I couldn't come up with anything about
>> such a basic topic.
>>
>> Thanks!
>>
>> --
>> You received this message because you are subscribed to the Google
>> Groups "golang-nuts" group.
>> To unsubscribe from this group and stop receiving emails from it,
>> send an email to golang-nuts...@googlegroups.com.
>> To view this discussion on the web visit
>> https://groups.google.com/d/msgid/golang-nuts/b49dc8c2-26ea-46bc-b76a-708a2537207cn%40googlegroups.com
>> 
>> .
>>
> --
 You received this message because you are subscribed to the Google
 Groups "golang-nuts" group.
 To unsubscribe from this group and stop receiving emails from it, send
 an email to golang-nuts...@googlegroups.com.

>>> To view this 

Re: [go-nuts] Underscore symbol

2022-11-05 Thread David Finkel
On Sat, Nov 5, 2022 at 4:57 AM Chris Burkert 
wrote:

> I am curious: from a compiler perspective, does that mean that by using _
> simply less assembler instructions are created by not handling those
> registers which relate to _?
>
>
That kind of depends on what you mean by "not handling". Since it's a
compile-time error (in the GC compiler) to have an unused variable, you'd
have to do something else with that value.
Depending on what type that ignored return value is, whether the call is
inlined and whether the call is using the newer, register-based calling
convention the compiler *may* be able to prune instructions related to that
variable.

Here are a few scenarios off the top of my head (in no particular order and
by no means exhaustive, but some of them are interesting -- and some are
completely hypothetical optimizations as I haven't looked at a lot of the
relevant compiler code myself):

   - The call doesn't get inlined, and it's a trivial value that can be
   passed around in a register, so that return register is simply never read
   (and gets clobbered at some later point when it's needed)
   - The call is inlined, and the variable that it's returned from doesn't
   interact with anything in the callee, so the code for generating that
   return variable can be removed during a dead-code removal pass
   - The call is inlined and that return value is a pointer to something on
   the heap, in which case the stack pointer-liveness map for that point in
   the function will mark that pointer as dead (I'm not certain about this
   one) -- this might let the heap object get GC'd from that moment.
   - The call is assembly so it's eligible for neither the newer
   register-calling convention nor inlining, so the spot on the stack for that
   return value just gets ignored until the function returns (or that
   stack-space gets allocated to another variable)
   - cgo can't return multiple values, but if you ignore the return value
   in AMD64 calling conventions it's a register that can be ignored. (although
   it may be a pointer to something elsewhere in memory, in which case gets
   more interesting)
   - The call is inlined and the return value is a pointer which would
   normally be marked as escaping but because the pointer gets ignored, the
   compiler can go back to stack-allocating. (I'm not sure if the compiler has
   a second escape-analysis pass like this, but it could be interesting)


Marcel Huijkman  schrieb am Sa. 5. Nov. 2022
> um 09:18:
>
>> When I explain it during my training I always say it is a trashcan
>> variable, anything you put in is to be ignored on the spot.
>>
>> On Friday, November 4, 2022 at 10:10:20 PM UTC+1 Konstantin Khomoutov
>> wrote:
>>
>>> On Fri, Nov 04, 2022 at 04:58:35AM -0700, Canuto wrote:
>>>
>>> > I'm just starting out with go ...
>>> > I have searched for lights on this string but without success.
>>> > What does this sign mean " _, err " , what the underscore symbol means
>>> here?
>>>
>>> If you're starting with Go, please start with the Go Tour [1].
>>> For instance, the use of this underscore sign is covered in [2].
>>>
>>> 1. https://go.dev/tour/
>>> 2. https://go.dev/tour/moretypes/17
>>>
>>> --
>> You received this message because you are subscribed to the Google Groups
>> "golang-nuts" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to golang-nuts+unsubscr...@googlegroups.com.
>> To view this discussion on the web visit
>> https://groups.google.com/d/msgid/golang-nuts/6c745c54-b212-4bb6-8e40-00273e6ee2fan%40googlegroups.com
>> 
>> .
>>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/CALWqRZo-n%3D_16Ug8Rids3E502dFZcW5PPZueGKfDqA%2Bcg30X6A%40mail.gmail.com
> 
> .
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CANrC0BjkRus%2B-kV5Wdq7vwiLinqiuRyX7o5LbtXnDh_BHqD%2BxQ%40mail.gmail.com.


Re: [go-nuts] Any information about adding a trailing comma in ast CompositeLit (for structs)

2022-10-26 Thread David Finkel
On Mon, Oct 24, 2022 at 9:27 PM Tajmeet Singh  wrote:

> Thanks for looking at it :smile:
>
> Could you elaborate more on how the `SetLines` would work on a
> `token.FileSet`? I thought that `SetLines` is only for the `os.File` types
> :sweat: Do you mean that I should create offsets (using SetLines) before I
> create the FileSet out of it?
>
Sure, so what I was thinking is that you'd use a different fileset than the
one used to parse the AST, and only give it synthetic line-boundaries (the
line-widths don't actually have to make sense), and then, when picking the
token locations for the different elements in the CompositeLiteral, you'd
override the locations of those tokens in the AST so nodes you want to
appear on the same line will appear on the same line. (up to formatting
constraints)

Another other option (which is much simpler -- and I wish I had thought of
before) is to pass the ast.FieldList 
from the StructType  instead
of the slice of fields, then you can use the token.Pos from the Closing
field . If you use Pos()
 for the field to set the `Colon
` field on the KeyValueExpr
, the formatter will see the
line boundaries in between fields as appropriate and match the formatting
of the struct definition. (AFAICT)


>
> reference code:
> https://github.com/tjgurwara99/constr/blob/0e0f8952c652b7a7a10b7238daed90132b924084/construct.go#L31
>
> On Tuesday, 25 October 2022 at 01:07:23 UTC+1 david@gmail.com wrote:
>
>> On Sat, Oct 22, 2022 at 10:00 PM Tajmeet Singh 
>> wrote:
>>
>>> Hello,
>>>
>>> I've been working on a utility to generate constructors for me when I
>>> provide it with a path to the file containing the struct and it `Ident`.
>>> The idea was that I would just create a ast.Node (FuncDecl) with all the
>>> necessary fields but I'm not able to figure out the positioning of the
>>> commas.
>>>
>>> The function that I'm working on looks something like this:
>>>
>>> ```Go
>>> func generateConstructor(typeName string, fields ...*ast.Field)
>>> *ast.FuncDecl {
>>> var elts []ast.Expr
>>>
>>> for _, field := range fields {
>>> elts = append(elts, {
>>> Key:   field.Names[0],
>>> Value: field.Names[0],
>>> })
>>> }
>>> return {
>>> Doc:  nil,
>>> Recv: nil,
>>> Name: ast.NewIdent("New" + typeName),
>>> Type: {
>>> TypeParams: nil,
>>> Params: {
>>> List: fields,
>>> },
>>> Results: nil,
>>> },
>>> Body: {
>>> Lbrace: 1,
>>> List: []ast.Stmt{
>>> {
>>> Results: []ast.Expr{
>>> {
>>> Op: token.AND,
>>> X: {
>>> Type:   ast.NewIdent(typeName),
>>> Elts:   elts,
>>> Rbrace: 1,
>>> },
>>> },
>>> },
>>> },
>>> },
>>> Rbrace: 2,
>>> },
>>> }
>>> }
>>> ```
>>>
>>> And when I provide it with a struct like this:
>>>
>>> ```Go
>>> type Data struct {
>>> something string
>>> data  string
>>> ddint
>>> }
>>> ```
>>> I get this when I do `format.Node` on the generated node `functionDecl`.
>>>
>>> ```Go
>>> func NewData(something string,
>>> data string,
>>> dd int) {
>>> return {something: something,
>>> data: data,
>>> dd: dd}
>>> }
>>> ```
>>>
>>> However, I was thinking that it would look something like this.
>>>
>>> ```Go
>>> func NewData(something string,
>>> data string,
>>> dd int,
>>> ) {
>>> return {something: something,
>>> data: data,
>>> dd: dd,
>>> }
>>> }
>>> ```
>>> (wishful thinking :joy:)
>>>
>>> Anyways, I tried to figure out how the `token.COMMA` is used in the
>>> parser and how the ast is affected but I couldn't figure it out. Maybe it
>>> is related to the `Lbrace` and `Rbrace` values which I'm deliberately
>>> missing. Any help would be much appreciated :smile: :pray:
>>>
>>
>> Looking at the code, I think you're on the right track with Rbrace's
>> location being the determining factor when to insert a comma and move put
>> the closing brace on a new line.
>> My recommendation would be to use `SetLines`
>>  on the (hopefully
>> clean) `token.FileSet` you're passing to `format.Node` to declare some
>> new-line offsets. I don't think the offsets have to make sense as they
>> would in a file that was parsed, but the formatter needs to see the last
>> expression and close brace as being 

Re: [go-nuts] Any information about adding a trailing comma in ast CompositeLit (for structs)

2022-10-24 Thread David Finkel
On Sat, Oct 22, 2022 at 10:00 PM Tajmeet Singh 
wrote:

> Hello,
>
> I've been working on a utility to generate constructors for me when I
> provide it with a path to the file containing the struct and it `Ident`.
> The idea was that I would just create a ast.Node (FuncDecl) with all the
> necessary fields but I'm not able to figure out the positioning of the
> commas.
>
> The function that I'm working on looks something like this:
>
> ```Go
> func generateConstructor(typeName string, fields ...*ast.Field)
> *ast.FuncDecl {
> var elts []ast.Expr
>
> for _, field := range fields {
> elts = append(elts, {
> Key:   field.Names[0],
> Value: field.Names[0],
> })
> }
> return {
> Doc:  nil,
> Recv: nil,
> Name: ast.NewIdent("New" + typeName),
> Type: {
> TypeParams: nil,
> Params: {
> List: fields,
> },
> Results: nil,
> },
> Body: {
> Lbrace: 1,
> List: []ast.Stmt{
> {
> Results: []ast.Expr{
> {
> Op: token.AND,
> X: {
> Type:   ast.NewIdent(typeName),
> Elts:   elts,
> Rbrace: 1,
> },
> },
> },
> },
> },
> Rbrace: 2,
> },
> }
> }
> ```
>
> And when I provide it with a struct like this:
>
> ```Go
> type Data struct {
> something string
> data  string
> ddint
> }
> ```
> I get this when I do `format.Node` on the generated node `functionDecl`.
>
> ```Go
> func NewData(something string,
> data string,
> dd int) {
> return {something: something,
> data: data,
> dd: dd}
> }
> ```
>
> However, I was thinking that it would look something like this.
>
> ```Go
> func NewData(something string,
> data string,
> dd int,
> ) {
> return {something: something,
> data: data,
> dd: dd,
> }
> }
> ```
> (wishful thinking :joy:)
>
> Anyways, I tried to figure out how the `token.COMMA` is used in the parser
> and how the ast is affected but I couldn't figure it out. Maybe it is
> related to the `Lbrace` and `Rbrace` values which I'm deliberately missing.
> Any help would be much appreciated :smile: :pray:
>

Looking at the code, I think you're on the right track with Rbrace's
location being the determining factor when to insert a comma and move put
the closing brace on a new line.
My recommendation would be to use `SetLines`
 on the (hopefully
clean) `token.FileSet` you're passing to `format.Node` to declare some
new-line offsets. I don't think the offsets have to make sense as they
would in a file that was parsed, but the formatter needs to see the last
expression and close brace as being on different lines

The type-switch line that handles CompositeLit's call handling insertions:
https://cs.opensource.google/go/go/+/refs/tags/go1.19.2:src/go/printer/nodes.go;l=1021;drc=7e72d384d66f48a78289edc6a7d1dc6ab878f990
The lines that handle making the decision about inserting a new line:
https://cs.opensource.google/go/go/+/refs/tags/go1.19.2:src/go/printer/nodes.go;l=297-299;drc=a1901f898bc05aac966edd247ff122f52fbb8d2e

>
> PS: I'm not aware of any utility out there so have to roll my own :joy:
> and learn whilst at it; if people are aware of it, please let me know and
> I'll inspect their code and figure things out :smile:
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/ffa312d0-5652-4c2d-9c71-c74bc4bfc56bn%40googlegroups.com
> 
> .
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CANrC0BgETovBLDUFrQeEEbCEgtoA7qWTOUgq-Wft4%2B%2Bxn1MRfg%40mail.gmail.com.


Re: [go-nuts] google code style is the same as gofmt in go codes?

2022-09-13 Thread David Finkel
On Tue, Sep 13, 2022 at 5:39 PM Axel Wagner 
wrote:

>
>
> On Tue, Sep 13, 2022 at 10:46 PM David Finkel 
> wrote:
>
>> On Tue, Sep 13, 2022 at 3:55 PM Moein Halvaei 
>> wrote:
>>
>>> When I read codes from https://cs.opensource.google/go, indents are 2
>>> spaces and when using gofmt indents are 2 tabs. Why?
>>>
>> Google's Codesearch defaults to matching Google's C++ style guide rather
>> than Go's recommended style:
>> https://google.github.io/styleguide/cppguide.html#Spaces_vs._Tabs
>> To be clear: gofmt uses an 8-spaces per tab, not two tabs.
>>
>
> gofmt doesn't determine how many spaces are tab stops aligned to at all.
> That's a property of your editor, IDE or code browser and usually
> configurable. That's part of the appeal of using tabs for indentation and
> why spaces are better for alignment.
>
Well, that's partially true.
There are a few places where gofmt aligns tokens after indentation where
the alignment doesn't quite work out correctly if the tab-stop interval
isn't exactly 8 characters.
The `go/printer` package's Config includes a Tabwidth
<https://pkg.go.dev/go/printer@go1.19.1#Config.Tabwidth> field for a reason
(it's actually passed to a
<https://cs.opensource.google/go/go/+/refs/tags/go1.19.1:src/go/printer/printer.go;l=1391;drc=54182ff54a687272dd7632c3a963e036ce03cb7c>
TabWriter <https://pkg.go.dev/text/tabwriter#Writer> to do the alignment).

(I didn't realize before that the go/printer package actually underlies the
implementation of go/format and cmd/gofmt -- I had assumed that it was a
reimplementation like go/ast vs the compiler-internal ast)

>
>
>> --
>>> You received this message because you are subscribed to the Google
>>> Groups "golang-nuts" group.
>>> To unsubscribe from this group and stop receiving emails from it, send
>>> an email to golang-nuts+unsubscr...@googlegroups.com.
>>> To view this discussion on the web visit
>>> https://groups.google.com/d/msgid/golang-nuts/3b43a2be-8001-4f53-a952-417b6a909bd9n%40googlegroups.com
>>> <https://groups.google.com/d/msgid/golang-nuts/3b43a2be-8001-4f53-a952-417b6a909bd9n%40googlegroups.com?utm_medium=email_source=footer>
>>> .
>>>
>> --
>> You received this message because you are subscribed to the Google Groups
>> "golang-nuts" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to golang-nuts+unsubscr...@googlegroups.com.
>> To view this discussion on the web visit
>> https://groups.google.com/d/msgid/golang-nuts/CANrC0BgCHM_m2nkAjkqnLDP02-FfYFtOyRv9SW8SAup4NHp1UA%40mail.gmail.com
>> <https://groups.google.com/d/msgid/golang-nuts/CANrC0BgCHM_m2nkAjkqnLDP02-FfYFtOyRv9SW8SAup4NHp1UA%40mail.gmail.com?utm_medium=email_source=footer>
>> .
>>
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CANrC0BjJTwmM9QKL5vKCYCd6o8dwd%2BKSG6OyMJ3brwHZNu0tYw%40mail.gmail.com.


Re: [go-nuts] google code style is the same as gofmt in go codes?

2022-09-13 Thread David Finkel
On Tue, Sep 13, 2022 at 3:55 PM Moein Halvaei  wrote:

> When I read codes from https://cs.opensource.google/go, indents are 2
> spaces and when using gofmt indents are 2 tabs. Why?
>
Google's Codesearch defaults to matching Google's C++ style guide rather
than Go's recommended style:
https://google.github.io/styleguide/cppguide.html#Spaces_vs._Tabs
To be clear: gofmt uses an 8-spaces per tab, not two tabs.

> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/3b43a2be-8001-4f53-a952-417b6a909bd9n%40googlegroups.com
> 
> .
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CANrC0BgCHM_m2nkAjkqnLDP02-FfYFtOyRv9SW8SAup4NHp1UA%40mail.gmail.com.


Re: [go-nuts] Any package implementing FIFO mutex?

2022-09-09 Thread David Finkel
Not a drop-in replacement, but there is net/textproto.Pipeline
. (intended for sequencing
text-based network protocols going over a socket, but it's not too far off)

You'd call `Next()` to grab the sequence-handle and then
call `p.StartRequest(id)` to grab the lock. Unlocking would be
`p.EndRequest(id)`.
I think you can ignore the response-side for this use-case, but I'm not
certain.

On Fri, Sep 9, 2022 at 3:12 PM ChrisLu  wrote:

> "sync.Mutex" is not FIFO. Has any package implemented a dropping for FIFO
> mutex?
>
> One similar solution is to use buffered channel, but it is limited by the
> buffer size, and requires non-trivial re-architecturing.
>
> Chris
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/f4772670-65d8-4b31-a71a-d01ad20214ebn%40googlegroups.com
> 
> .
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CANrC0BhtxnmU%2B71h_GCph50fCBo5GxCiAJSvrt07JjcFiSMiSw%40mail.gmail.com.


Re: [go-nuts] Type switch on generic parameter

2022-08-11 Thread David Finkel
On Thu, Aug 11, 2022 at 7:40 PM 'Matt Rosencrantz' via golang-nuts <
golang-nuts@googlegroups.com> wrote:

> I'd really love to be able to do:
>
> type allowedTypes{
>   int64|float64|string
> }
>
> func Foo[T allowedTypes](arg T) {
> switch t := arg {
>case int64:
>// something
>case string:
>   // something completely different
>}
> }
>
>
As a way of having the type checker disallow other types from being passed
> so I don't have to return an error for incorrect types.  I guess this would
> be the same as asking for typesets to be allowed in normal interfaces like:
>
> func Foo(arg allowedTypes) {...}
>
> Is there another way to achieve this? Is there a reason it is not possible?
>

The type-parameters proposal discusses this a little.
You can cast your arg to an interface-type before type-asserting.
https://go.googlesource.com/proposal/+/HEAD/design/43651-type-parameters.md#identifying-the-matched-predeclared-type
Note that the design uses the interface{} syntax, while you can now use
"any" when converting to an interface.

Worth noting: you'll still have a runtime cost to the type-switch.


> Thanks!
> Matt
>
>
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/870bc9bd-2fcf-4598-9287-2da7adbc524an%40googlegroups.com
> 
> .
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CANrC0Bh_bAL%2B_NH5YA1tvM8s4bDOJ3ug2veFOd3q2JjyKaLGdQ%40mail.gmail.com.


Re: [go-nuts] GO program's memory footprint is confusing

2022-05-09 Thread David Finkel
Looking at proc-10451, I see that there are two mappings with anonymous
huge pages in that smaps output, and none on the other.
Does one machine have transparent hugepages enabled, and the other not?
You can check whether they're enabled on that system by looking
at /sys/kernel/mm/transparent_hugepage/enabled.


Here are the relevant smaps sections:

c0-c00040 rw-p  00:00 0
Size:   4096 kB
KernelPageSize:4 kB
MMUPageSize:   4 kB
Rss:2048 kB
Pss:2048 kB
Shared_Clean:  0 kB
Shared_Dirty:  0 kB
Private_Clean: 0 kB
Private_Dirty:  2048 kB
Referenced: 2048 kB
Anonymous:  2048 kB
LazyFree:  0 kB
AnonHugePages:  2048 kB
ShmemPmdMapped:0 kB
Shared_Hugetlb:0 kB
Private_Hugetlb:   0 kB
Swap:  0 kB
SwapPss:   0 kB
Locked:0 kB
VmFlags: rd wr mr mw me ac sd

7f716a5e2000-7f716c953000 rw-p  00:00 0
Size:  36292 kB
KernelPageSize:4 kB
MMUPageSize:   4 kB
Rss:2092 kB
Pss:2092 kB
Shared_Clean:  0 kB
Shared_Dirty:  0 kB
Private_Clean: 0 kB
Private_Dirty:  2092 kB
Referenced: 2092 kB
Anonymous:  2092 kB
LazyFree:  0 kB
AnonHugePages:  2048 kB
ShmemPmdMapped:0 kB
Shared_Hugetlb:0 kB
Private_Hugetlb:   0 kB
Swap:  0 kB
SwapPss:   0 kB
Locked:0 kB
VmFlags: rd wr mr mw me ac sd


On Fri, Apr 29, 2022 at 12:18 PM garenchan  wrote:

> *What version of Go are you using (go version)?*
>
> $ go version
> go version go1.17.6 linux/amd64
>
> *Does this issue reproduce with the latest release?*
>
> uncertain
>
> *What operating system and processor architecture are you using (go env)?*
>
> $ go env
> GO111MODULE="on"
> GOARCH="amd64"
> GOBIN=""
> GOCACHE="/root/.cache/go-build"
> GOENV="/root/.config/go/env"
> GOEXE=""
> GOEXPERIMENT=""
> GOFLAGS=""
> GOHOSTARCH="amd64"
> GOHOSTOS="linux"
> GOINSECURE=""
> GOMODCACHE="/root/go/pkg/mod"
> GONOPROXY=""
> GONOSUMDB=""
> GOOS="linux"
> GOPATH="/root/go"
> GOPRIVATE=""
> GOPROXY=""
> GOROOT="/home/go"
> GOSUMDB="off"
> GOTMPDIR=""
> GOTOOLDIR="/home/go/pkg/tool/linux_amd64"
> GOVCS=""
> GOVERSION="go1.17.6"
> GCCGO="gccgo"
> AR="ar"
> CC="gcc"
> CXX="g++"
> CGO_ENABLED="1"
> GOMOD="/home/demo/go.mod"
> CGO_CFLAGS="-g -O2"
> CGO_CPPFLAGS=""
> CGO_CXXFLAGS="-g -O2"
> CGO_FFLAGS="-g -O2"
> CGO_LDFLAGS="-g -O2"
> PKG_CONFIG="pkg-config"
> GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0
> -fdebug-prefix-map=/tmp/go-build4023324410=/tmp/go-build
> -gno-record-gcc-switches"
>
> *What did you do?*
>
> I encountered a memory problem with the GO program, see here for details.(
> https://stackoverflow.com/questions/71994609/memory-footprint-of-the-same-program-varies-greatly-in-two-similar-environments
> )
>
> In order to simplify the analysis, I wrote a simple program to test.
>
> ```go
> package main
>
> import (
> "time"
> )
>
> func main() {
> time.Sleep(60*time.Second)
> }
> ```
>
>
>- I compiled it into binary file on a linux host `host1` with kernel
>4.18. Then I run it on `host1` and the process takes up close to 5MB RSS.
>- I then copy the binary file to another host `host2` with kernel
>4.18. I also ran it on `host2`, but this time the process took up less than
>1MB RSS.
>- I repeated the test many times and observed the same thing.
>
>
> ```
> $ uname -a
> Linux host1 4.18.0 #1 SMP Wed Nov 10 20:46:19 CST 2021 x86_64 x86_64
> x86_64 GNU/Linux
>
> $ uname -a
> Linux host2 4.18.0 #1 SMP Fri May 8 10:59:10 UTC 2021 x86_64 x86_64 x86_64
> GNU/Linux
> ```
>
> Why is memory footprint of the same program in similar environments so
> different? What factors might be contributing to this problem?
>
> *What did you expect to see?*
>
> I would expect to see the memory footprint of the same program in similar
> environments be close. I look forward to your answers. Thank you very much.
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/daba9d60-7c45-45f3-83c8-afc2471841c6n%40googlegroups.com
> 
> .
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 

Re: [go-nuts] Is there a way to specify or use the tmp directory used in testing?

2022-02-23 Thread David Finkel
On Wed, Feb 23, 2022 at 1:47 PM Gergely Brautigam 
wrote:

> Hi!
>
> The best way to do it is, to have these files in a folder next to the test
> called `testdata` and then when the test starts, simply copy them into a
> temp location. And then make your program work with an environment property
> or setting which can configure the path in which is loads these files from
> and set that environment property for the test to the Temp folder you just
> copied your files to.
>
> And don't forget to defer os.RemoveAll(tmp) :)
>
You don't need this if you use t.TempDir
 to create the tempdir. :)

>
> On Wednesday, 23 February 2022 at 16:30:06 UTC+1 david@gmail.com
> wrote:
>
>> On Wed, Feb 23, 2022 at 8:53 AM Leam Hall  wrote:
>>
>>> My program uses data and template files located relative to the binary.
>>> Since go test creates the binary under test in /tmp/go-build., there
>>> are no data or template files. How do I either specify what directory to
>>> build in so I can create the files, or get the tmp directory name before
>>> the tests are run so I can write files to it?
>>>
>>
>> When go test runs tests, they run with the current working directory
>> inside the package's directory, so relative paths should work.
>>
>> Another option that you might want to consider is using //go:embed
>> directives to embed those files in your binary. (package doc:
>> https://pkg.go.dev/embed)
>> This way you never need to resolve anything relative to the binary again.
>>
>> Note: unless you use mlock(2) embedding in the binary shouldn't bloat
>> memory usage, since the data will only be paged into memory at first-access.
>>
>>>
>>> Thanks!
>>>
>>> Leam
>>>
>>> --
>>> Site Automation Engineer   (reuel.net/resume)
>>> Scribe: The Domici War (domiciwar.net)
>>> General Ne'er-do-well  (github.com/LeamHall)
>>>
>>> --
>>> You received this message because you are subscribed to the Google
>>> Groups "golang-nuts" group.
>>> To unsubscribe from this group and stop receiving emails from it, send
>>> an email to golang-nuts...@googlegroups.com.
>>> To view this discussion on the web visit
>>> https://groups.google.com/d/msgid/golang-nuts/7d8cf3dc-14ab-315f-ce5a-9e3cca877e17%40gmail.com
>>> .
>>>
>> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/8ffeae9e-ce1d-4a7d-af01-b24a1d13c7cdn%40googlegroups.com
> 
> .
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CANrC0BjvgCD%3D7GrhSsV1xHuZjGj6wHso_-qpCWBRbEj8MW-%3DgA%40mail.gmail.com.


Re: [go-nuts] Is there a way to specify or use the tmp directory used in testing?

2022-02-23 Thread David Finkel
On Wed, Feb 23, 2022 at 8:53 AM Leam Hall  wrote:

> My program uses data and template files located relative to the binary.
> Since go test creates the binary under test in /tmp/go-build., there
> are no data or template files. How do I either specify what directory to
> build in so I can create the files, or get the tmp directory name before
> the tests are run so I can write files to it?
>

When go test runs tests, they run with the current working directory inside
the package's directory, so relative paths should work.

Another option that you might want to consider is using //go:embed
directives to embed those files in your binary. (package doc:
https://pkg.go.dev/embed)
This way you never need to resolve anything relative to the binary again.

Note: unless you use mlock(2) embedding in the binary shouldn't bloat
memory usage, since the data will only be paged into memory at first-access.

>
> Thanks!
>
> Leam
>
> --
> Site Automation Engineer   (reuel.net/resume)
> Scribe: The Domici War (domiciwar.net)
> General Ne'er-do-well  (github.com/LeamHall)
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/7d8cf3dc-14ab-315f-ce5a-9e3cca877e17%40gmail.com
> .
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CANrC0Bj5UWhsA16_6kK%3D38oROOZ4P24QKEYUP2tTCvYG0bydjQ%40mail.gmail.com.


Re: [go-nuts] Re: Why, oh why, do people do this? Things that annoy me in Go code.

2022-01-29 Thread David Finkel
On Sat, Jan 29, 2022 at 6:21 AM Tim Hardcastle 
wrote:

> Agree with Rudolf on point 2. Long meaningful variable/function names are
> good. Comments become obsolete, they become detached from their code,
> they're only used to explain the name of the variable once and then you're
> left with something than reads
>
> // urn contains the userlist
> fxn := rx (frn)
>
>  Now that editors have autocomplete to make up for my meagre typing speed,
> you bet your ass I'm going to have [eg from current project] a local
> variable called lastTokenWasColon and a method called addWordsToParser.
> Because knowing exactly what they do when I need to modify or debug saves
> me so much time and trouble. (Perhaps this varies from person to person. If
> my memory is poorer than yours, it has more of an upside for me than for
> you.)
>

There's a lot of middle-ground between a three-letter variable or
function-name and encoding the whole doc-comment for a function or variable
in its name.
Humans only have so much working memory, once a name gets long enough we
start dropping parts of the name and it tends to be stuff in the middle
that gets dropped.

If you have a parser type, and a variable with that type, often, it would
be better to have an addWords() method on the parser type. Then if you also
need a special-case addWord() it's easy to tell what's going on.

I try to have meaningful names, but beyond some threshold, but I try to
prevent things from being redundant with the types involved (the entire
function signature and type of the variable).

Also, comments are not about just describing what something is. (those are
the least useful types of comments) They're also quite useful for
describing what's being attempted, what corner-cases are being addressed
and if there's any tricky logic that needs to be handled. Additionally,
IMO, just about any function or method should have a doc-comment explaining
what it expects. (helpers under ~3 lines may be exempt)

>
> And is there a better solution to the problem in point 1 than to break the
> function down into lots of little functions *with meaningful names*? (If
> the names (and pieces) aren't meaningful you've only technically broken it
> down.)
>
> On Friday, January 28, 2022 at 10:12:48 AM UTC-8 Rudolf Martincsek wrote:
>
>> > 2) Long variable names.
>>
>> Where I work (not in Go), writing comments is frowned upon. That includes
>> "docblock" style comments. If a function needs to be documented, it means
>> the implementation is too complex and must be broken apart to reduce
>> cyclomatic or whatever perceived complexity. Also uncle bob told us that
>> functions should never be longer than 2-3 lines of code, so it should be
>> enough to look at the source code to see what it does. That's the general
>> sentiment in my team.
>> Comments are considered sign of "un"clean code.
>>
>> So we use long variable and function names to make the code self
>> documenting. (Hint: it doesn't)
>> Points 3,4,5 have similar roots, because in dynamic languages it was a
>> trend many years ago. (ie: hungarian notation)
>>
>> On Thursday, December 9, 2021 at 2:10:18 PM UTC+2 Amnon wrote:
>>
>>> 1) Long functions that go on forever and contain long lambdas and 8
>>> levels of indentation.
>>>
>>> 2) Long variable names.
>>>
>>> 3) Variable names which include the type of the variable.
>>>
>>> 4) Packages whose name contain the word '/pkg/'
>>>
>>> 5) Repos which contain the prefix go-
>>>
>>> 6) Code where almost every line prefixed by `_, _ =`
>>> and the underscores won't go away when you wipe your screen
>>>
>>>
>>> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/6a824f2c-d1b6-43f7-8c07-a1e9b8f5376en%40googlegroups.com
> 
> .
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CANrC0BgMG03iVChUjD7O876H1Yu7r2Vvcwm5TT6zCWYtyVJqWg%40mail.gmail.com.


Re: [go-nuts] Looping and tail-end code

2022-01-12 Thread David Finkel
On Wed, Jan 12, 2022 at 5:02 AM Tobias Klausmann 
wrote


> So what is the *idiomatic* way of being able to use `continue` (or
> something like it), yet have "always do this" code at the end of the
> loop? As I understand it, `defer` only works for ends of functions, not
> ends of blocks, and label breaks only work for breaks, obviously.
>

I generally pull the bulk of the loop body into another function/method
(usually called tick()) that I call inside the loop just before sleeping.
 (or more typically, a select{} block checking a ticker and a context)

(I like Rob's option, too. -- although that doesn't work with select{}
blocks as well)

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CANrC0Bi4k%2BURHVmOsiZkMTp9UR1EGSDO0hvgij20zv1dsrP%2BFg%40mail.gmail.com.


Re: [go-nuts] Re: Alternatives to wrapping errors

2022-01-01 Thread David Finkel
On Fri, Dec 31, 2021 at 5:12 AM Brian Candler  wrote:

> On Friday, 31 December 2021 at 08:10:49 UTC Henry wrote:
>
>> The purpose of error wrapping is to give contextual information about the
>> error. It is supposed to help you understand and locate the error. For
>> instance, *"invalid filename"* is not particularly useful when compared
>> to *"fail to load customer data: invalid filename"*. Error wrapping is a
>> stack trace in a human-friendly language.
>
>
> I disagree with that explanation, because what you describe can be done
> without wrapping:
> return fmt.Errorf("Failed to load customer data: %v", err)
> or with wrapping:
> return fmt.Errorf("Failed to load customer data: %w", err)
>
> Both provide exactly the same human-friendly trace.  The difference is
> that with the wrapped error, the error value can be destructured to
> retrieve the "cause" error object, and hence to match on that object. It's
> an invitation to your API consumer to couple directly to error types which
> your code doesn't return, but which originate from elsewhere, typically
> system libraries or third-party libraries.
>
> The question then is, under what circumstances is that a good idea?  It
> depends.  Perhaps one example is if your code is using an underlying
> database API, and you are happy to expose raw database-level errors.  That
> allows your own library to wash its hands of responsibility of how to deal
> with these, and let the consumer deal with them if it wants to.  (Was it a
> temporary connection error? Was it a uniqueness constraint violation?  Not
> My Problem™)
>

There's a good argument to be made against wrapping errors at
api-boundaries in some cases. IMO, that's something that's definitely
case-by-case as there are situations where bubbling up the underlying error
is 100% the right thing to do.
e.g. io/fs.FS  implementations are
constrained to returning the io/fs.PathError
 type by the interface documentation in
some cases. However, there are specific underlying sentinel values that
should be bubbled up and accessible.

IMO, within a package (or somewhat intentionally nebulously: "between API
boundaries"), it's generally a good idea to use error wrapping so outer
layers can make the actual wrapping, unwrapping, switching decisions.
By using error-wrapping, you're free to break functions up and add context
as it bubbles up, without losing the ability to switch on the original
error. (or at least use errors.Is or errors.As)

As an example of a the above trade-off, here's an io/fs.FS implementation I
pushed up recently:
https://gitlab.com/dfinkel/go-safefs/-/blob/ca532e3c5c5c/fs_linux.go#L78-105
It's switching on errno values and wrapping specific sentinel errors with
context for the errno values I knew I could see, with specific diagnostics
for those errors.

Worth noting: stack traces rarely have argument values, and don't generally
have other context information, e.g. EMFILE handling specifically checks
the rlimit to get the fd limit value to include in the error message. Stack
traces are nice for the programmer if they've opened the right version of
the code, but useless for everyone else. Errors with context are orders of
magnitude more useful if written correctly. (one of the reasons I don't
like exceptions is that most of the time you just get the stack trace and
original error, which is only barely useful for debugging if you have the
most trivial bugs)

> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/fa907dec-1dc7-4909-9743-4d91eb146481n%40googlegroups.com
> 
> .
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CANrC0BgDVcWOxf_hvnPF7yAUoG3JJ16cFHVVhjZpX-bSS8jNCw%40mail.gmail.com.


Re: [go-nuts] grpc and golang struct tags

2021-11-30 Thread David Finkel
On Sat, Nov 27, 2021 at 10:53 AM Sankar  wrote:

> Hi
>
> I have a database that has a column `2xxCode`. This database is part of a
> legacy system and I cannot make changes to this, as there are multiple
> applications that depend on this, and some of the applications are
> unchangeable.
>
> Now I want to create a new gRPC server in golang that has to interact with
> the data stored in this database.
>
> Since golang variable names cannot begin with a number, I need create a
> `.proto` file which should generate a golang struct member like:
>
> type mystruct {
> TwoxxCode `db:"2xxCode"`
> }
>
> from my .proto file. But I could not find out how to generate a golang
> struct from a .proto file, with adding custom tags to the struct. On
> searching, I found https://github.com/golang/protobuf/issues/52 and the
> second comment on the issue seems very strongly worded as if this would
> never happen in protobuf. Also, the bug seems open for a long time.
>
> How have others solved this problem to add custom tags to proto generated
> golang structs ? Are there any best-known-methods for this ? There were a
> couple of scripts mentioned in the comments, but I am not sure what to
> pick. Any recommendations ?
>
My general recommendation is "don't".
It's quite rare that DBs and RPC interfaces will stay a direct mapping.
Usually one or the other will need to evolve over time, and a bit of
separation is not a bad thing.

Usually, my recommendation is to create "model" structs representing what's
actually in the DB, and then have translation functions to convert to/from
the protobuf forms. (I also recommend having an interface around the DB
implementation itself to make testing and migrations easier)

I'm in the process of moving one of the services I own off gogo protobuf
 (which is quasi-abandoned
 and looking for new ownership
because it needs to be rewritten on top of the new go protobuf api)


> Thanks.
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/239e2f6a-09f7-4e89-a921-ec3fead637c7n%40googlegroups.com
> 
> .
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CANrC0BiTG08mpC4qZoj5UcD6N_xU2r3cyctgKXt7Lajs1Sv9Uw%40mail.gmail.com.


Re: [go-nuts] Which error handling pattern do you prefer?

2021-11-12 Thread David Finkel
On Fri, Nov 12, 2021 at 7:48 AM Miguel Angel Rivera Notararigo <
ntr...@gmail.com> wrote:

> I tend to use errX (X is adapted according to context) for function scoped
> errors, and err for block scoped errors
>
> func MyFunc() error {
>>   v, errDS := doSomething()
>>   ...
>>   errDA := doAnotherthing()
>> }
>>
>
> if err := doAnotherthing(); err != nil {
>> return err
>> }
>>
>
> That way you don't shadow errors.
>


I can't +1 this enough.

I've caught *so* many bugs from shadowed errors (and re-used error
variables). I consider it a rather bad anti-pattern to have a single
err variable
that's reused throughout a scope.
If you have unique error variable names and you forget to do something with
an error that you've assigned a name you automatically get unused variable
compile-errors. (just this is enough to be worthwhile)


With that said, constraining the scope using the initializer statement on
an if (or switch) statement suffices when you don't need any other return
values, at which point I may use the err variable-name (although I often
make those unique for clarity anyway).

> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/CAF9DLCmR4ZdnVs4A28BSrPcbiHsQ_ufub5cSPjCt2SDy2dA1xA%40mail.gmail.com
> 
> .
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CANrC0Bjc%2BTgHZvdY9oAqBgBUFDdd-KbkMi38bHmeYHPaDZANPA%40mail.gmail.com.


Re: [go-nuts] HPC image processing in go?

2021-11-04 Thread David Finkel
On Thu, Nov 4, 2021 at 5:43 AM quin...@gmail.com  wrote:

> Hi,
>
> Has anyone got any experience of high performance image processing in go?
>
> By this I mean doing complex image processing in real time at 4K
> resolution on commodity hardware. This is really pushing it using carefully
> written C++ but when we tried writing similar code using go slices we go a
> significant slowdown (x4 over gcc).
>
> We experimented using unsafe pointers thinking it is go's slice range
> checking that cause the problems, but surprisingly saw no improvement.
>
> Has anyone had success saturating the memory bandwidth using go?  Is my
> result a surprise to people? Is it just that gcc's code generator is very
> mature and Go's is less so, or should I keep looking for dropoffs in my
> code?
>
This doesn't particularly surprise me. The Go GC compiler is optimised for
fast compile-times and does very limited vectorization.

I think the general advice in cases where one needs better optimization
paths has been to use gccgo or gollvm (if possible).


>
> I haven't looked at the generated assembly yet, but that is my next step.
>
> Any opinions?
>
> -Steve
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/8419a816-8058-48c1-874b-09a34be0f3fcn%40googlegroups.com
> 
> .
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CANrC0Bgua02tU4h1QayM%2BHVmOWNznKnYiSdzFTsKkUT_wVZNYw%40mail.gmail.com.


Re: [go-nuts] Re: Why go plugin addresses do not load with go binary #49225

2021-11-01 Thread David Finkel
On Mon, Nov 1, 2021 at 9:44 AM Manoj Chauhan 
wrote:

> Hi Brian,
>
> greeter.go calls plugin.open and it will be work only for one sub version
> of go. If plugin and binary are made in different sub versions of go1.15
> then plugin.open will not work.
>
It sounds like you want to ignore a major warning on the use of plugins.
It's my understanding that go plugins' limitations on requiring that both
the plugin and the main binary to be built with identical toolchains (same
go version) comes from the lack of a stable internal ABI within Go binaries
across versions. (also the possibility of runtime changes across versions).
Using LD_PRELOAD does not seem advisable as a way to bypass that
limitation. (unfortunately, I don't have a better option other than to more
tightly constrain your build system so both the original binary and the
plugin are built with the same toolchain)

>
> On Monday, November 1, 2021 at 6:55:02 PM UTC+5:30 Brian Candler wrote:
>
>> > My question was how to load plugin address in go runtime using
>> LD_PRELOAD. I am using LD_PRELOAD because plug.open is failed. Is there any
>> other solution?
>>
>> When I tried it, I didn't need to set any environment variables (and
>> certainly no LD_XXX variables).  Follow this tutorial:
>>
>> https://medium.com/learning-the-go-programming-language/writing-modular-go-programs-with-plugins-ec46381ee1a9
>>
>> It works fine for me:
>>
>> ubuntu@builder:~/go-plugin-example$ *cat /etc/lsb-release*
>> DISTRIB_ID=Ubuntu
>> DISTRIB_RELEASE=18.04
>> DISTRIB_CODENAME=bionic
>> DISTRIB_DESCRIPTION="Ubuntu 18.04.5 LTS"
>> ubuntu@builder:~/go-plugin-example$ *ls*
>> LICENSE  README.md  chi  eng  greeter.go  swe
>> ubuntu@builder:~/go-plugin-example$ *go version*
>> go version go1.16.6 linux/amd64
>> ubuntu@builder:~/go-plugin-example$ *go build -buildmode=plugin -o
>> eng/eng.so eng/greeter.go*
>> ubuntu@builder:~/go-plugin-example$ *go run greeter.go english*
>> Hello Universe
>> ubuntu@builder:~/go-plugin-example$
>>
>> If you're still using Ubuntu 16, note that it went obsolete nearly a year
>> ago (unless you're paying for extended maintenance).
>>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/42e3d250-cb69-43b6-a297-7a56fcbe688en%40googlegroups.com
> 
> .
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CANrC0BiRTDZpQ5SiAxk2%2BDT5hV1vYzZRiJgtpsUSPkdsbiC%2B%3DQ%40mail.gmail.com.


Re: [go-nuts] ast.NewPackage errors for built in types

2021-10-11 Thread David Finkel
On Mon, Oct 11, 2021 at 5:48 AM Steven Hartland 
wrote:

> If the ast.Files passed to ast.NewPackage includes built in types such as
> int it returns an error e.g.
> file1.go:5:6: undeclared name: int
>
> Is there a way to prevent that?
>

Generally, I always add the `builtin` package to the list of packages I'm
parsing.
I wrote a little library for exactly this kind of package loading a few
years ago:
https://gitlab.com/dfinkel/goastpkg/-/blob/master/go_ast_parser.go
(https://pkg.go.dev/golang.spin-2.net/astpkg)

>
> Playground example: https://play.golang.org/p/Yg30TTzoLHP
>
> My goal is to take multiple files, resolve inter file dependencies e.g. a
> type referencing another type in a different file and process the resulting
> ast.Files. So if there is a better way to achieve this I'm all ears.
>

In general, I've stopped using the `go/ast` internal references as much and
have started using resolved `go/types` references as they're more reliable
and better-specified.
(golang.org/x/tools/go/packages
 has a LoadMode
flag for generating `go/types.Info` (NeedTypesInfo
))

>
>Regards
>Steve
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/CAHEMsqbJoJxuo3c-mofMtzXXJhYCzV2skW2ZB3ZPY6WtA8%2BxHw%40mail.gmail.com
> 
> .
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CANrC0BiwYY32yTC-SivuYm2-pYEuxeuf4KEz%2BatjeLoAsLr27g%40mail.gmail.com.


Re: [go-nuts] Idea extending xerror.As

2021-09-21 Thread David Finkel
On Mon, Sep 20, 2021 at 10:52 PM Andrey T. 
wrote:

>
> ... or, to put a crazy idea out there, we need to ask for extension of
> switch statement to support (v, err) tuples for a case argument...


That's not a particularly crazy idea. It's just one that's unlikely to make
it through with one use-case like this since the bar for language changes
is so much higher than standard library changes. (for good reason)

On Sunday, September 19, 2021 at 3:43:36 PM UTC-6 david@gmail.com wrote:
>
>> On Sun, Sep 19, 2021 at 5:19 PM roger peppe  wrote:
>>
>>> In some ways, the existing API is arguably more ergonomic than the
>>> originally proposed generic version, as it's possible to use `errors.As` in
>>> a switch statement (eg to test several possible types of error) which isn't
>>> possible with the multi-return `As` variant.
>>>
>>
>> Hmm, that's a good point.
>> However, the main reason I like the two-return-value version more is that
>> you can use it like a normal type-assertion in an if-statement's init
>> section.
>>
>>
>>> A minor variant of the existing API could be:
>>>
>>> ```
>>> func As[E error](err error, asErr *E) bool
>>> ```
>>> which makes the API a little clearer without changing the usage. Sadly
>>> we can't make that change without breaking compatibility.
>>>
>>> Unfortunately, in order to use this proposed version, you still need to
>> pre-declare the variables for each type before the switch/case.
>> I've honestly found it more ergonomic to use a if/else if/ block rather
>> than a switch/case because it lets me contain the scope of these variables
>> anyway.
>>
>> I suppose a simple wrapper that can be used with type-assertions inside a
>> switch/case block would be:
>> ```
>> func AsBool[E error](err error, asErr error) bool {
>> ae, ok := As[E](err)
>> if ok {
>>  asErr = ae
>> }
>> return ok
>> }
>> ```
>> (this would definitely need a better name)
>>
>> Then you'd be able to almost treat your switch/case like a type-switch
>> without needing to pre-declare a variable for every case.
>>
>> ```
>> var asErr error
>> switch {
>>case errors.AsBool[*os.PathError](err, ):
>>fmt.Printf("Path Error! ae: %v", asErr.(*os.PathError))
>>case errors.AsBool[syscall.Errno](err, ):
>>fmt.Printf("ae: %d", asErr.(syscall.Errno))
>> }
>> ```
>>
>> However, I think it would be nicer to use the (originally proposed)
>> two-return errors.As with if/else if.
>>
>> ```
>> if pe, ok := errors.As[*os.PathError](err); ok {
>> fmt.Printf("Path Error: %v", pe)
>> } else if en, ok := errors.As[syscall.Errno](err); ok {
>>     fmt.Printf("errno %[1]d: %[1]s", en)
>> }
>> ```
>>
>> Since it looks like the dev.typeparams branch has been merged into
>> master, I was just thinking about how we'd add the two-return-value/generic
>> version of As to the errors package (for go 1.18).
>> Given that the original proposal's code works pretty much as-is, I think
>> the biggest barrier would be a good name. (given that As is already taken)
>>
>>>
>>> On Sun, 19 Sep 2021, 21:15 David Finkel,  wrote:
>>>
>>>>
>>>>
>>>>
>>>> On Sun, Sep 19, 2021 at 4:02 PM David Finkel 
>>>> wrote:
>>>>
>>>>> You might be interested in the original draft proposal for errors.As:
>>>>>
>>>>> https://go.googlesource.com/proposal/+/master/design/go2draft-error-inspection.md#the-is-and-as-functions
>>>>>
>>>>> In particular, it originally specified that errors.As would take a
>>>>> type-parameter. (the version of generics that was proposed concurrently
>>>>> with that proposal was not accepted so they had to go with the current
>>>>> (clunkier) interface).
>>>>>
>>>>
>>>> Hmm, actually, the code in that proposal for the generic version of
>>>> errors.As works almost unchanged:
>>>> https://go2goplay.golang.org/p/ddPDlk00Cbl (I just had to change the
>>>> type-parameter syntax)
>>>>
>>>>
>>>>> On Sun, Sep 19, 2021 at 5:33 AM Haddock  wrote:
>>>>>
>>>>>>
>>>>>> I like the way error handling is done in the xerror package. Things
>>>>>> become more concise, but remain very easy to read and understa

Re: [go-nuts] Idea extending xerror.As

2021-09-19 Thread David Finkel
On Sun, Sep 19, 2021 at 5:19 PM roger peppe  wrote:

> In some ways, the existing API is arguably more ergonomic than the
> originally proposed generic version, as it's possible to use `errors.As` in
> a switch statement (eg to test several possible types of error) which isn't
> possible with the multi-return `As` variant.
>

Hmm, that's a good point.
However, the main reason I like the two-return-value version more is that
you can use it like a normal type-assertion in an if-statement's init
section.


> A minor variant of the existing API could be:
>
> ```
> func As[E error](err error, asErr *E) bool
> ```
> which makes the API a little clearer without changing the usage. Sadly we
> can't make that change without breaking compatibility.
>
> Unfortunately, in order to use this proposed version, you still need to
pre-declare the variables for each type before the switch/case.
I've honestly found it more ergonomic to use a if/else if/ block rather
than a switch/case because it lets me contain the scope of these variables
anyway.

I suppose a simple wrapper that can be used with type-assertions inside a
switch/case block would be:
```
func AsBool[E error](err error, asErr error) bool {
ae, ok := As[E](err)
if ok {
 asErr = ae
}
return ok
}
```
(this would definitely need a better name)

Then you'd be able to almost treat your switch/case like a type-switch
without needing to pre-declare a variable for every case.

```
var asErr error
switch {
   case errors.AsBool[*os.PathError](err, ):
   fmt.Printf("Path Error! ae: %v", asErr.(*os.PathError))
   case errors.AsBool[syscall.Errno](err, ):
   fmt.Printf("ae: %d", asErr.(syscall.Errno))
}
```

However, I think it would be nicer to use the (originally proposed)
two-return errors.As with if/else if.

```
if pe, ok := errors.As[*os.PathError](err); ok {
fmt.Printf("Path Error: %v", pe)
} else if en, ok := errors.As[syscall.Errno](err); ok {
fmt.Printf("errno %[1]d: %[1]s", en)
}
```

Since it looks like the dev.typeparams branch has been merged into master,
I was just thinking about how we'd add the two-return-value/generic version
of As to the errors package (for go 1.18).
Given that the original proposal's code works pretty much as-is, I think
the biggest barrier would be a good name. (given that As is already taken)

>
> On Sun, 19 Sep 2021, 21:15 David Finkel,  wrote:
>
>>
>>
>>
>> On Sun, Sep 19, 2021 at 4:02 PM David Finkel 
>> wrote:
>>
>>> You might be interested in the original draft proposal for errors.As:
>>>
>>> https://go.googlesource.com/proposal/+/master/design/go2draft-error-inspection.md#the-is-and-as-functions
>>>
>>> In particular, it originally specified that errors.As would take a
>>> type-parameter. (the version of generics that was proposed concurrently
>>> with that proposal was not accepted so they had to go with the current
>>> (clunkier) interface).
>>>
>>
>> Hmm, actually, the code in that proposal for the generic version of
>> errors.As works almost unchanged:
>> https://go2goplay.golang.org/p/ddPDlk00Cbl (I just had to change the
>> type-parameter syntax)
>>
>>
>>> On Sun, Sep 19, 2021 at 5:33 AM Haddock  wrote:
>>>
>>>>
>>>> I like the way error handling is done in the xerror package. Things
>>>> become more concise, but remain very easy to read and understand as in
>>>> plain Go errorhandling.
>>>>
>>>> Here is the example of how to use xerror.As:
>>>>
>>>> _, err := os.Open("non-existing")
>>>> if err != nil {
>>>> var pathError *os.PathError
>>>> if xerrors.As(err, ) {
>>>> fmt.Println("Failed at path:", pathError.Path)
>>>> }
>>>> }
>>>>
>>>> My idea is to make this even shorter like this:
>>>>
>>>> _, err := os.Open("non-existing")
>>>> myerrors.As(err, os.PathError) {
>>>>  pathError -> fmt.Println("Failed at path:", pathError.Path)
>>>> }
>>>>
>>>> Think something like that has so far not been suggested. That's why I
>>>> thought it is justified to drop comment.
>>>>
>>>> myerrors.As would also do the check if err is nil. The code in my
>>>> sample is not valid Go code, I know. It is only pseudo code to show the
>>>> idea.
>>>>
>>>> --
>>>> You received this message because you are subscribed to the Google
>>>> Groups "golang-nuts" group.
&g

Re: [go-nuts] Idea extending xerror.As

2021-09-19 Thread David Finkel
On Sun, Sep 19, 2021 at 4:02 PM David Finkel  wrote:

> You might be interested in the original draft proposal for errors.As:
>
> https://go.googlesource.com/proposal/+/master/design/go2draft-error-inspection.md#the-is-and-as-functions
>
> In particular, it originally specified that errors.As would take a
> type-parameter. (the version of generics that was proposed concurrently
> with that proposal was not accepted so they had to go with the current
> (clunkier) interface).
>

Hmm, actually, the code in that proposal for the generic version of
errors.As works almost unchanged: https://go2goplay.golang.org/p/ddPDlk00Cbl (I
just had to change the type-parameter syntax)


> On Sun, Sep 19, 2021 at 5:33 AM Haddock  wrote:
>
>>
>> I like the way error handling is done in the xerror package. Things
>> become more concise, but remain very easy to read and understand as in
>> plain Go errorhandling.
>>
>> Here is the example of how to use xerror.As:
>>
>> _, err := os.Open("non-existing")
>> if err != nil {
>> var pathError *os.PathError
>> if xerrors.As(err, ) {
>> fmt.Println("Failed at path:", pathError.Path)
>> }
>> }
>>
>> My idea is to make this even shorter like this:
>>
>> _, err := os.Open("non-existing")
>> myerrors.As(err, os.PathError) {
>>  pathError -> fmt.Println("Failed at path:", pathError.Path)
>> }
>>
>> Think something like that has so far not been suggested. That's why I
>> thought it is justified to drop comment.
>>
>> myerrors.As would also do the check if err is nil. The code in my sample
>> is not valid Go code, I know. It is only pseudo code to show the idea.
>>
>> --
>> You received this message because you are subscribed to the Google Groups
>> "golang-nuts" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to golang-nuts+unsubscr...@googlegroups.com.
>> To view this discussion on the web visit
>> https://groups.google.com/d/msgid/golang-nuts/629e6763-36a9-4d7d-991c-fd71dd384d0en%40googlegroups.com
>> <https://groups.google.com/d/msgid/golang-nuts/629e6763-36a9-4d7d-991c-fd71dd384d0en%40googlegroups.com?utm_medium=email_source=footer>
>> .
>>
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CANrC0BgsVSo0hv5UtTi%3DVXZYZODys1H-kvB63o2B3UThBMnfxQ%40mail.gmail.com.


Re: [go-nuts] Idea extending xerror.As

2021-09-19 Thread David Finkel
You might be interested in the original draft proposal for errors.As:
https://go.googlesource.com/proposal/+/master/design/go2draft-error-inspection.md#the-is-and-as-functions

In particular, it originally specified that errors.As would take a
type-parameter. (the version of generics that was proposed concurrently
with that proposal was not accepted so they had to go with the current
(clunkier) interface).

On Sun, Sep 19, 2021 at 5:33 AM Haddock  wrote:

>
> I like the way error handling is done in the xerror package. Things become
> more concise, but remain very easy to read and understand as in plain Go
> errorhandling.
>
> Here is the example of how to use xerror.As:
>
> _, err := os.Open("non-existing")
> if err != nil {
> var pathError *os.PathError
> if xerrors.As(err, ) {
> fmt.Println("Failed at path:", pathError.Path)
> }
> }
>
> My idea is to make this even shorter like this:
>
> _, err := os.Open("non-existing")
> myerrors.As(err, os.PathError) {
>  pathError -> fmt.Println("Failed at path:", pathError.Path)
> }
>
> Think something like that has so far not been suggested. That's why I
> thought it is justified to drop comment.
>
> myerrors.As would also do the check if err is nil. The code in my sample
> is not valid Go code, I know. It is only pseudo code to show the idea.
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/629e6763-36a9-4d7d-991c-fd71dd384d0en%40googlegroups.com
> 
> .
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CANrC0Bi2azNEa33sAk2S4vYCzQEkQJovqOUWeWBDg%3DKokvQL6w%40mail.gmail.com.


Re: [go-nuts] Changing wall clock in unit test

2021-07-30 Thread David Finkel
On Fri, Jul 30, 2021 at 12:13 AM Carl  wrote:

> Hi,
>
> Is there a way to write a unit test that simulates a change in the wall
> clock for a time.Time value?
>

I use a combination of two approaches to simulate the passage of time
(often both work together):

   - have functions a `now` argument so the caller supplies the timestamp
   (this avoids timestamp-skew for cases where the timestamps should be close
   together anyway)
   - Use a package like https://github.com/vimeo/go-clocks (
   https://pkg.go.dev/github.com/vimeo/go-clocks) to use a real clock in
   production, but have a fake clock you can advance/set however you want
   without impinging on the main code

Full disclosure: I wrote github.com/vimeo/go-clocks, so I might be a bit
biased -- it is based on one of Google's internal packages for C++, though.

One additional benefit of using a fake clock is that it allows for
fine-grained synchronization between tests and code if you're sleeping in
goroutines, as the fake clock in go-clocks has methods for awaiting a
certain number of sleepers, etc.


>
> Cheers,
> Carl
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/f306417d-46f9-4ccd-8e7c-69a1dbd14969n%40googlegroups.com
> 
> .
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CANrC0Bj6KMLQ-erdAB0dfJC1XSNw%2BgWfx43pqSAZ8W4efpnZQQ%40mail.gmail.com.


Re: [go-nuts] Recomended GOPROXY (or not) for Open Source projects?

2021-06-25 Thread David Finkel
On Fri, Jun 25, 2021 at 1:23 PM josvazg  wrote:

> When working on internal company projects, it makes sense to use a company
> wide GO Proxy assuring that all go dependency code is available and
> immutable. But when you move to an Open Source project, you cannot longer
> use such private proxy.
>
> I wonder what is the best practice recommendation for Open Source projects.
>
> I can't comment about whether anything specifically is a "best practice",
but here are my thoughts:


> For instance, reading about https://proxy.golang.org/ is says:
> > Why did a previously available module become unavailable in the mirror?
>
> > proxy.golang.org  does not save all modules
> forever.
>
> Which means, your project may *not compile* anymore if someone pulls one
> of your dependencies and proxy.golang.org decides to drop it.
>
The next line in that FAQ section mentions specific reasons why
proxy.golang.org wouldn't persist a module version in its cache. (e.g.
licences it doesn't recognize as letting it keep/distribute copies of the
code)

This seems like a non-issue if you are careful about your dependencies (and
specifically, their licenses (which seems to be easy to tell now that
pkg.go.dev will flag unrecognized licenses)).

> When you read that, you may decide to just track the vendor/ folder in
> your repo and forget about proxies for OSS projects.
>
> What is the recommendation from the Go community about this?
>
> - Are there public go proxies can be used for OSS projects ensuring you
> will never lose any dependency?
>
> - Is https://goproxy.io/ giving such guarantee maybe?
>
> - Should we just vendor and forget about Go-Proxies for Open Source?
>
Now that Go Modules is relatively mature, please don't use vendoring in
open source projects unless you have a really good reason.
Vendoring makes it impossible for the rest of us to tell whether there are
modifications to those dependencies and blows up your repo's size at the
same time. (at least without some really complicated diffing)

> Thanks,
>
> Jose
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/47c445ca-884d-49b5-8357-aeae8802e937n%40googlegroups.com
> 
> .
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CANrC0BizsWRjdZSKXBqCKikhHcNbyWpP9d_pnr7odK3YQq_xgA%40mail.gmail.com.


Re: [go-nuts] how to get unsigned url (not signed url)

2020-12-24 Thread David Finkel
On Mon, Dec 21, 2020 at 5:54 PM Alexander Mills 
wrote:

> this is a little irritating lol, i can get a signed url via:
>
> bucket := "bnk-photos"
> filename := "mypic3.json"
> method := "PUT"
> expires := time.Now().Add(time.Minute * 10)
>
> url, err := storage.SignedURL(bucket, filename, {
> GoogleAccessID: cfg.Email,
> PrivateKey: cfg.PrivateKey,
> Method: method,
> Expires: expires,
> ContentType: "binary/octet-stream",
> })
>
>
> but I just want an *unsigned* url?
> how?
>

If it's an object that already exists that you want to provide access to
the current version, you want: ObjectAttrs.MediaLink
, so
you'd do something like:

gcsClient, clientErr := storage.NewClient(ctx)
// if clientErr != nil {
obj := gcsClient.Bucket(bucket).Object(filename)
objattr, attrErr := obj.Attrs(ctx)
// if attrErr != nil { ...
fmt.Println(objattr.MediaLink) // this

On the other hand, your example uses the PUT method for signing the URL, in
which case I think you'd need to construct the URL directly as either
XML (S3-compatible)

:
fmt.Sprintf("%s.storage.googleapis.com/%s", bucket, filename)

or JSON (GCS)

:
fmt.Sprintf("https://storage.googleapis.com/storage/v1/b/%s/o/%s;, bucket,
filename)
>
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/f00bd659-dbed-4161-8b6c-456f41ccbb22n%40googlegroups.com
> 
> .
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CANrC0BgayVQagGkDXzL8kZeH1UZrMa_8nYy3FVss1smuSu7_MQ%40mail.gmail.com.


Re: [go-nuts] Proposal: auto return String instead of []byte if requested

2020-09-12 Thread David Finkel
On Sat, Sep 12, 2020 at 4:25 AM 'Axel Wagner' via golang-nuts <
golang-nuts@googlegroups.com> wrote:

> Hi y'all,
>
> given that the concern here seems to be performance (though, TBH, I doubt
> this particular case is much of a bottleneck), this seems to be far simpler
> to address as a compiler optimization - if the compiler can prove there are
> no other references to a `[]byte`, it can do the conversion cheaply. You
> need to implement that check anyway, and optimizations are transparent to
> the user, so the hurdle for them is lower.
>
> The only problem with that is that it would need to happen cross-package.
> That's where the type-system might help. AFAICT however, if you're willing
> to change the API anyway, the simpler fix here would be to take an
> `io.Writer` instead of returning a `[]byte`. The user is then free to pass
> a `*bytes.Buffer` or a `*strings.Builder`, depending on which of the two
> they need. And if the wins of this optimization are large enough to justify
> changing the language (which, again, remains to be proven) they certainly
> are large enough to justify this slightly less user-friendly API.
>
> So, really, IMO the case for language changes here is pretty weak.
>

I agree that this is more of a missing compiler optimization. The compiler
already has the ability to elide copies for a subset of []byte -> string
conversions.

As an example, here's the implementation of bytes.Equal

:

func Equal(a, b []byte) bool {
// Neither cmd/compile nor gccgo allocates for these string conversions.
return string(a) == string(b)
}

Compiler explorer shows that this actually gets compiled directly down to the
appropriate runtime.memequal  at a
callsite.

In contrast, a very trivial package with two functions
 doesn't appears to not inline a trivial
function doing a string->bytes conversion, but ends up calling both
runtime.slicebytetostring
and runtime.stringtoslicebyte.In this contrived example simple escape
analysis would be enough to elide the copies.

My general impression is that the GC compiler's inliner works rather well
across packages, in many cases, so if this does end up being a bottleneck
for someone, this may not be an expensive optimization to add over the
current infrastructure. (disclaimer: I haven't delved deeply into the inner
workings of the GC compiler's optimization passes)


>
> On Sat, Sep 12, 2020 at 9:46 AM tapi...@gmail.com 
> wrote:
>
>> There is a prerequisite to transfer ownership: it must be proved that
>> no other values share ownership of the byte slice returned by
>> ioutil.ReadFile.
>>
>> On Saturday, September 12, 2020 at 3:42:14 AM UTC-4 tapi...@gmail.com
>> wrote:
>>
>>> Is it good to introduce owner transfer based string<->[]byte conversions?
>>> After the conversion, the being converted string/[]byte values mustn't
>>> be used any more.
>>> Such as
>>>
>>> tlsCertData, _ = ioutil.ReadFile("/etc/ssl/mycert")
>>> var tlsCert string = bultin.ByteSlice2String(tlsCertData)
>>>
>>> // forbid using tlsCertData any more
>>> _ = tlsCertData // error: tlsCertData can only used after a
>>> re-assignment.
>>>
>>> On Friday, September 11, 2020 at 3:09:57 PM UTC-4 Ian Lance Taylor wrote:
>>>
 On Fri, Sep 11, 2020 at 9:45 AM Kevin Chadwick 
 wrote:
 >
 > I apologise if this has already been discussed. Google didn't turn up
 anything
 > directly related.
 >
 > If you read a file using the following that returns a byte slice.
 >
 > tlsCertb, err := ioutil.ReadFile("/etc/ssl/mycert")
 > if err != nil {
 > log.Fatal(err)
 > }
 > tlsCert = string(tlsCertb)
 >
 > Is there a way to get a string without the cast.
 >
 > Otherwise couldn't the language automatically return a string rather
 than a byte
 > slice in these cases if the receiving var is already a string?
 >
 > e.g.
 >
 > var string tlsCert
 > tlsCert, err = ioutil.ReadFile("/etc/ssl/mycert")
 > if err != nil {
 > log.Fatal(err)
 > }

 The way Go works, ioutil.ReadFile is compiled with the io/ioutil
 package. It can't change based on how it is called. So it is always
 going to return []byte.

 The only way to implement what you suggest would be to add an implicit
 conversion from []byte to string. But that seems problematic. In
 general Go avoids implicit conversions except to interface types. And
 a conversion to string does require a copy, so it doesn't seem like a
 great idea to do that implicitly.

 If this happens a lot in your code, it seems easy enough to use a tiny
 helper function.

 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 

Re: [go-nuts] How to read (and write) the ECN bits?

2020-08-06 Thread David Finkel
On Thu, Aug 6, 2020 at 10:02 AM Uli Kunitz  wrote:

> Reading is possible with IP_RECVTOS on Linux but requires the use of
> recvmsg, because the TOS field is provided as ancillary data. This wouldn't
> be very portable though. Raw sockets with IP_HDRINCL are a better option if
> portability is a concern.

Keep in mind that raw sockets are privileged under Linux. (the process must
have CAP_NET_RAW either by being root, or some other mechanism)
That vastly limits the usefulness of a QUIC implementation.

>
> On Wednesday, August 5, 2020 at 11:33:41 PM UTC+2 ma...@acln.ro wrote:
>
>> ECN bits are represented in the TOS field. I think you can use setsockopt
>> with the IP_TOS option to set the TOS field on a socket. See ip(7). On the
>> Go side, use the SyscallConn method on your UDPConn, then call setsockopt
>> using the Control method. Something like this (untested):
>> https://play.golang.org/p/6_R-zlBSibv
>>
>> On Wed, Aug 5, 2020 at 9:30 PM  wrote:
>>
>>> I'm working on a Go implementation of the QUIC protocol (
>>> https://github.com/lucas-clemente/quic-go). QUIC specifies how to use
>>> ECN (Explicit Congestion Notification) to detect and respond to congestion
>>> in the network (see
>>> https://tools.ietf.org/html/draft-ietf-quic-transport-29#section-13.4 for
>>> details on that).
>>>
>>> As far as I can see, there's no way to read (and write) the ECN bits
>>> from the IP header, unless I use a raw socket, which would be a suboptimal
>>> solution for many reasons.
>>> The closest I could get to extracting information from the IP header was
>>> by using *UDPConn.ReadFromUDP* and then using *golang.org/x/net/ipv4
>>> * to parse the *oob* bytes into an
>>> *ipv4.ControlMessage* (or equivalently for IPv6). This at least gives
>>> me access to the TTL field. It seems like this approach is insufficient to
>>> get access to the ECN bits though.
>>>
>>> Can anyone help me with this?
>>>
>>> --
>>> You received this message because you are subscribed to the Google
>>> Groups "golang-nuts" group.
>>> To unsubscribe from this group and stop receiving emails from it, send
>>> an email to golang-nuts...@googlegroups.com.
>>> To view this discussion on the web visit
>>> https://groups.google.com/d/msgid/golang-nuts/3c96ecc4-e507-48d1-a912-9e3caf6ecd11o%40googlegroups.com
>>> 
>>> .
>>>
>>
>>
>> --
>> Andrei Călin
>>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/fe7cd943-cbb2-4530-a71a-d0b72100fb67n%40googlegroups.com
> 
> .
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CANrC0BhU3hRRAw4ghAh-4zs18tW-pBfqMZ69f-xiNFHUHFaZZw%40mail.gmail.com.


Re: [go-nuts] Why does html.UnescapeString not look for the trailing semicolon when finding HTML entities?

2020-07-05 Thread David Finkel
On Thu, Jul 2, 2020 at 1:18 PM Akash  wrote:

> html.UnescapeString("Should this word, , be unescaped?")
>
> https://play.golang.org/p/vN5bvfooq8H
>
> Aren't HTML entities supposed to end with a semicolon? See
> https://developer.mozilla.org/en-US/docs/Glossary/Entity
>
I think the answer is "yes"
, when
sending, but "don't count on it" when parsing. (or unescaping in this case)

This comes under the heading of "Be conservative in what you do, be liberal
in what you accept from others"
 (also, backwards
compatibility

The html standard's HTML parsing section for HTML entities says

:

> If the character reference was consumed as part of an attribute
> ,
> and the last character matched is not a U+003B SEMICOLON character (;), and
> the next input character
>  is
> either a U+003D EQUALS SIGN character (=) or an ASCII alphanumeric
> , then, for historical
> reasons, flush code points consumed as a character reference
> 
>  and
> switch to the return state
> .
>

It looks like it wasn't required in HTML 4.01 as the section on entity
references includes 
this note:

> *Note. In SGML, it is possible to eliminate the final ";" after a
> character reference in some cases (e.g., at a line break or immediately
> before a tag). In other circumstances it may not be eliminated (e.g., in
> the middle of a word). We strongly suggest using the ";" in all cases to
> avoid problems with user agents that require this character to be present.*
>

(which, fortunately, aligns with my feeling from the late-90s that the
trailing semicolon was suggested but optional in HTML 4)

>
> I couldn't see any edge cases mentioned in the source
>  .
>
> Thanks.
>
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/baea05b9-6634-495b-a45f-78f02ec7a20bn%40googlegroups.com
> 
> .
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CANrC0BjHUf-GNU%3DT5J-Vi%3DqqREAJdjLHHg2nmUJNKwpnJXrcjg%40mail.gmail.com.


Re: [go-nuts] Block-based data structures and the Type Parameters - Draft Design

2020-06-21 Thread David Finkel
On Sat, Jun 20, 2020 at 1:22 AM Andrew Werner  wrote:

> [The body of this email is a duplication of the README in 
> https://github.com/ajwerner/go2dequeue/
> which also contains the sample implementation]
>
> Exercise building a dequeue with the go2 Type Parameter Draft
>
> This project is an exploration with the go2go / Type Parameters - Design
> Draft
> 
> with an eye towards block-based data structures which promote access
> locality.
>
> Such data structures traditionally utilize blocks of objects laid out
> contiguously in memory. In go, today, one generally specializes such data
> structures which are performance critical. This is especially important in
> the case of reducing allocations which occur on critical paths. Using a
> sync.Pool can help with allocations in some cases but can be clunky to use
> and, well, do create more pointers for GC to worry about and don't have the
> access locality.
>
> Whether it's really important to have data structures which include arrays
> of other data structures laid out contiguously in RAM is really important
> is sort of orthogonal. Let's just assume that it is for now and look at how
> we'd do it. We only need to consider rejecting the importance of this case
> if we can't find a good solution or idiom to support it. The google/btree
>  library README links this Google Open
> Source Blog Post on block-based container
> 
> performance indicating it does matter. The interesting thing about that
> library is it hardly gets the access locality of the C++ library in the
> blog post it references.
>
> The challenge this library explores is to layout blocks in structures
> contiguously in RAM while allowing the user to have some control over that
> block size.
> This example
>
> The approach this experiment takes is to allow the users to specify the
> block size by providing a function to map an array type to a slice. The
> allows the blocks to contain a slice which references the array. The
> overhead to maintain the slice header is 3 words but the cost is probably
> less in memory and more in the optimizations the compiler will be less able
> to perform. In particular, it probably will need to do bounds checking on
> that slice and there are probably some opportunities to avoid the pointer
> interactions. The interface ends up being pretty reasonable though a little
> bit ... opaque?
>
> What this looked like in this demo is*
>
> // Say we want to create a dequeue of things.type Thing struct { Foo int64, 
> Bar int64, ID [16]byte }// The below incantation will create one with blocks 
> of 37 elements.d := NewWithArray(func(a *[37]Thing) []Thing { return (*a)[:] 
> })// The nodes in the linked list of this structure are 1240 bytes, not 
> that// that's a great number or anything like that, just saying it's pretty 
> big.// Maybe there'd be something good to get out of aligning things are 
> cache line// sizes. See TestNodeSize.
>
> Other things you could do Use a slice for the buffer
>
> A different approach would be to just have the array in the node, take a
> buffer size and then keep a sync.Pool or freelist of slices. Today's
> github.com/google/btree does this but way worse in that it just keeps a
> slice of btree.Item. So fine, it's be two objects, the nodes and their item
> buffers. Maybe that is the answer but it's pretty lame. My feeling is once
> somebody is optimizing a data structure for access locality they are trying
> to optimize as far as they can go.
> Ignore or augment the language generics with manual or automatic
> specialization
>
> Today, in performance critical cases, people use a variety of automatic or
> manual specialization. There are tools like
> https://github.com/cheekybits/genny or
> https://github.com/mmatczuk/go_generics. Note that the latter has been
> used to good effect in CockroachDB for building specialized copy-on-write,
> interval B-trees.
>
> One answer to this problem might just be that go's generics solution
> doesn't solve for the problem of specializing block-based data structures.
> That's not a particularly satisfying answer.
> What I might have expected / guess I'm proposing
>
> Type lists are a thing for utilizing language features which only apply to
> certain kinds of types. There should be a way to create a type list for
> arrays of types.
>
As a first pass I would have anticipated that there would be a way to
> inform this package of a buffer size maybe drawn from a fixed number of
> sizes. For example:
>
> type BlockSize int
> const (
> _ BlockSize = 1 << (4*iota)
> Block16
> Block256
> )
> // Array here allowstype Array(type T) interface {
> type [Block16]T, [Block256]T
> }
> func New(type T)(blockSize BlockSize) Dequeue(T) {
>
> Hmm, this function signature would require being able 

Re: [go-nuts] Re: [generics] how to constraint a type must be a map or a slice?

2020-06-20 Thread David Finkel
On Sat, Jun 20, 2020 at 4:53 PM Ian Lance Taylor  wrote:

> On Sat, Jun 20, 2020 at 12:08 PM David Finkel 
> wrote:
> >
> > Here's an almost working example:
> > https://go2goplay.golang.org/p/qcdfl0tuHlb
> >
> > It looks like there's a bug in the type-parameter constraint checking
> because in the above example code, I get:
> >
> > type checking failed for main
> >
> > prog.go2:11:39: K does not satisfy comparable
> >
> > This, despite the type parameter definition literally requiring that K
> be comparable:
> > func genLen(type T MapSliceConstraint(K, V), K comparable, V
> interface{})(collection T) int {
> > return len(collection)
> > }
> > (example without a main() to reduce clutter:
> https://go2goplay.golang.org/p/1gqiYuDELuI)
>
> Yes, that looks like a bug.  Would you mind filing it in the issue
> tracker?  Thanks.
>
Sure, https://github.com/golang/go/issues/39733

>
> Ian
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CANrC0Bh5fM4DHNxmgvqnsoVWAP7k1mX_O5_yHaaELDqOodun6A%40mail.gmail.com.


Re: [go-nuts] Re: [generics] how to constraint a type must be a map or a slice?

2020-06-20 Thread David Finkel
On Sat, Jun 20, 2020 at 11:03 AM T L  wrote:

>
>
> On Saturday, June 20, 2020 at 10:21:56 AM UTC-4, Axel Wagner wrote:
>>
>> I would assume it's
>>
>> type MapConstraint(type K comparable, V interface{}) interface {
>> type map[K]V
>> }
>>
>> func F(type M MapConstraint(K, V), K comparable, V interface{}) (m M) {
>> }
>>
>> Note that you are under no obligation to make use of a type-parameter if
>> you don't need it.
>>
>
> I don't very understand this. Can a slice value be used as the argument of
> the F function?
>
For that, I think you'd need the interface to be:
type MapSliceConstraint(type K comparable, V interface{}) interface {
type map[K]V, []V
}

I'm not quite sure how to eliminate the useless K type-param for slices,
though.

Note: the relevant draft design section is:
https://go.googlesource.com/proposal/+/refs/heads/master/design/go2draft-type-parameters.md#type-parameters-in-type-lists

Here's an almost working example:
https://go2goplay.golang.org/p/qcdfl0tuHlb

It looks like there's a bug in the type-parameter constraint checking
because in the above example code, I get:

type checking failed for main

prog.go2:11:39: K does not satisfy comparable

This, despite the type parameter definition literally requiring that K be
comparable:
func genLen(type T MapSliceConstraint(K, V), K *comparable*, V
interface{})(collection T) int {
return len(collection)
}
(example without a main() to reduce clutter:
https://go2goplay.golang.org/p/1gqiYuDELuI)

>
>
>>
>> On Sat, Jun 20, 2020 at 4:14 PM T L  wrote:
>>
>>> I mean I don't care about the element and key types of the parameter
>>> type.
>>>
>>> For a simple example, I want to define a generic function which prints
>>> the length of a container (do do some other things):
>>>
>>> func Print(type T Container) (v T) {
>>>// ... do some things
>>>
>>>fmt.Println(len(v))
>>>
>>>// ... do some things
>>> }
>>>
>>> On Saturday, June 20, 2020 at 9:16:39 AM UTC-4, T L wrote:

 .

>>> --
>>> You received this message because you are subscribed to the Google
>>> Groups "golang-nuts" group.
>>> To unsubscribe from this group and stop receiving emails from it, send
>>> an email to golan...@googlegroups.com.
>>> To view this discussion on the web visit
>>> https://groups.google.com/d/msgid/golang-nuts/4f42e5e9-f991-4ee7-a043-5350a62f787fo%40googlegroups.com
>>> 
>>> .
>>>
>> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/f841c497-8c29-4f16-a027-2c446f1a94b6o%40googlegroups.com
> 
> .
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CANrC0BjPALDX6%2BT-tCpH3aaLSLQqQb7LExCzCuzL5uPGFxgxJw%40mail.gmail.com.


Re: [go-nuts] pprof samples

2020-04-22 Thread David Finkel
On Mon, Apr 20, 2020 at 8:35 PM asaxena via golang-nuts <
golang-nuts@googlegroups.com> wrote:

> Hi,
>
> I am trying CPU profiling a program that runs for an hour. However when I
> start pprof it says Total samples are only for 1.32 min. Why are the
> samples not collected for the whole duration of the program ? Is there a
> missing setting I need to enable ?
>
It sounds like it was collected fro the duration of the program (see
below), no additional configuration needed.

>
> Duration: 1.14hrs, Total samples = 1.32mins ( 1.94%)
>
This generally means that your process only used (roughly) 1.32 minutes of
CPU-time over the 1.14hrs of the profile. Equivalent to an average
CPU-usage of the 1.94% it listed.
My usual inference from this kind of profile is that this program is not
CPU-bound and instead I/O or network-bound.

CPU-profiling is only useful for debugging cpu-bound operations, it doesn't
tell you where operations were blocked, contending, etc.
Diego's suggestion of instrumenting your code with some sort of metrics
library (I'm a fan of opencensus's stats
 + prometheus
) is rather useful for tracking aggregate stats.

In general, though, if you have a specific request/process you want to find
the bottleneck in, it's hard to get away from tracing. I've used opentracing
with Zipkin
,
but most recently I use opencensus tracing
 with stackdriver
. For
a single process, though I just use opencensus's zpages
 to get a view of the current trace-spans
on that process.

>
> Thanks.
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/a13db751-0f65-4b0b-aaf3-f39bc29e21cf%40googlegroups.com
> 
> .
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CANrC0BizHrEy73JWJZHPrVx2Wb91z0vPj87HgLcg6nu1ydg0Mg%40mail.gmail.com.


Re: [go-nuts] Re: OAuth2 token expiry logic

2020-04-20 Thread David Finkel
On Mon, Apr 20, 2020 at 11:02 AM  wrote:

> Whoops, you're right. I got my Time and Duration mixed up. Your question
> still stands, though. The section on Monotonic Clocks at
> https://pkg.go.dev/time?tab=doc is a bit dense, but my best guess is that
> stripping the monotonic clock reading from the Expiry ensures that the
> comparison is made against the actual wall clock time (in the past) vs some
> unknown adjusted time, which might be earlier or later than the intended
> time and thus give incorrect results.
>
>
(from the peanut gallery)

My guess is that it wouldn't be that the monotonic time is incorrect, (in
fact it's probably more correct), it's just that it never gets serialized,
so you get inconsistent results whether you check the expiration of the
unserialized original struct, vs one you parsed if you compare using the
monotonic clock.


> s
>
>
> On Monday, April 20, 2020 at 7:16:30 AM UTC-7, ISE Development wrote:
>>
>> On Monday, 20 April 2020 15:04:54 UTC+1, crate...@gmail.com wrote:
>>>
>>> According to https://golang.org/pkg/time/#Duration.Round "If m <= 0,
>>> Round returns d unchanged". So now I'm really curious, why do the
>>> Round() at all?
>>>
>>
>> But in this case, it's a time.Time value, so this applies (
>> https://pkg.go.dev/time?tab=doc#Time.Round):
>>
>> Round returns the result of rounding t to the nearest multiple of d
>>> (since the zero time). The rounding behavior for halfway values is to round
>>> up. If d <= 0, Round returns t stripped of any monotonic clock reading but
>>> otherwise unchanged.
>>
>> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/f871298a-f06d-4e9f-ad20-ee145cdd8004%40googlegroups.com
> 
> .
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CANrC0Bjj_-M_q%2BuF30JsNGWq4M8OQO7rnwdktrtyAHj4g3FzNw%40mail.gmail.com.


Re: [go-nuts] Re: Why isn't there strings.reverse("str") function?

2020-02-27 Thread David Finkel
On Thu, Feb 27, 2020 at 1:52 PM roger peppe  wrote:

> If you really just want to reverse rune-by-rune, it's pretty
> straightforward:
>
> func Reverse(s string) string {
> r := make([]byte, 0, len(s))
> for len(s) > 0 {
> _, n := utf8.DecodeLastRuneInString(s)
> i := len(s) - n
> r = append(r, s[i:]...)
> s = s[:i]
> }
> return string(r)
> }
>
> That will also deal correctly with invalid utf8 encoding - all the bytes
> of the original string will be present in the result.
>

Another option with slightly less bookkeeping (but slightly more magic
indices):
https://play.golang.org/p/sfMLimbcHSj

func reverse(str string) string {

if len(str) == 0 {

return ""

}

out := make([]byte, len(str))
lastoffset := len(str)
for offset, r := range str {

rl := utf8.RuneLen(r)

copy(out[lastoffset-rl:lastoffset], str[offset:offset+rl])

lastoffset -= rl

}
return string(out)

}

>
>
> On Wed, 26 Feb 2020 at 14:20,  wrote:
>
>> Maybe the implementation in Java is something you could steal to save
>> time. Have a look into class StringBuilder where there is a reverse()
>> method. It does the reversion differently depending on whether dealing with
>> UTF16 or not.
>>
>> Am Samstag, 15. Februar 2020 17:37:15 UTC+1 schrieb Amarjeet Anand:
>>>
>>> Hi
>>>
>>> I was wondering why isn't there built-in string reverse function. Is it
>>> left intentionally because of some reason?
>>>
>>> Although strings are immutable in go, there are multiple ways to achieve
>>> this pretty easily. But having this function inbuilt will save our time
>>> because we need it quite often.
>>>
>>>
>>> --
>> You received this message because you are subscribed to the Google Groups
>> "golang-nuts" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to golang-nuts+unsubscr...@googlegroups.com.
>> To view this discussion on the web visit
>> https://groups.google.com/d/msgid/golang-nuts/934265f6-666b-446b-aa5e-73f0b2bdcd78%40googlegroups.com
>> 
>> .
>>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/CAJhgacjhm5TxaTgN3zwrKuD7YYBoXcpCitCuWeipqV_thhtYFQ%40mail.gmail.com
> 
> .
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CANrC0BjVdtMuPoOiyfUrW4yTO-kfqsMFhp-bsDXLqOL1yQwwmw%40mail.gmail.com.


Re: [go-nuts] Re: stringer command and generated String() function

2020-02-19 Thread David Finkel
On Tue, Feb 18, 2020 at 8:57 AM Vincent Blanchon 
wrote:

> Yes, definitely, good point.
> Both are them are good depending on the case actually.
>
>
> Le mardi 18 février 2020 16:55:02 UTC+4, Jan Mercl a écrit :
>>
>> On Tue, Feb 18, 2020 at 1:47 PM Vincent Blanchon
>>  wrote:
>>
>> > However, in real code, I guess we will have that many constants, so it
>> does not make really sense to increase the number.
>>
>> Design decisions may be driven by the desire to maximize the
>> performance in the average case or in the worst case scenario.
>>
>> That's why Go has a regexp package that's slower in the average case
>> wrt PCRE, but it guarantees linear, not exponential, performance of
>> the worst case.
>>
>
 In this case there's a blog post explaining the decision.  Mostly focusing
on memory savings. https://blog.golang.org/generate

There's no question the generated method is ugly. That's OK, though,
> because humans don't need to work on it; machine-generated code is often
> ugly. It's working hard to be efficient. All the names are smashed together
> into a single string, which saves memory (only one string header for all
> the names, even if there are zillions of them). Then an array, _Pill_index,
> maps from value to name by a simple, efficient technique. Note too that
> _Pill_index is an array (not a slice; one more header eliminated) of uint8,
> the smallest integer sufficient to span the space of values. If there were
> more values, or there were negatives ones, the generated type of
> _Pill_index might change to uint16 or int8: whatever works best.


(the blog then discusses decisions for bitfield enums as well)

> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/69db18c0-31a4-4d52-94c6-a168ef815e0a%40googlegroups.com
> 
> .
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CANrC0Bh5OdQG_Lg0R8jRybwQ9S9HgNRUfELFZ7%2BtfaGP%2BcCsMw%40mail.gmail.com.


Re: [go-nuts] How to print an AST without formatting?

2020-01-10 Thread David Finkel
On Thu, Jan 9, 2020 at 10:22 AM  wrote:

> Hello,
>
> I am looking for a way to keep to original token positioning but I cannot
> find how to avoid it when using `go/printer` or `go/format`.
> Basically, how to make this example print the same string that was parsed:
> https://play.golang.org/p/dI7WcevQJAZ
>
In the general case, this is not possible because the `go/ast
` package types drop the positions of some
tokens. (e.g. the `range` token in a `for := range` loop
)
I'm reasonably certain code is only likely to round-trip (via `
go/format.Node `) if it was
previously formatted with the same version's `gofmt` (or `go/format.Source
`).

Based on the documentation on `go/printer
`'s `Fprint
` function, it doesn't seem to
make any guarantees about matching the parsed format. From that doc:

> Fprint "pretty-prints" an AST node to output. It calls Config.Fprint with
> default settings. Note that gofmt uses tabs for indentation but spaces for
> alignment; use format.Node (package go/format) for output that matches
> gofmt.
>

I wish I had more helpful advice.

>
> Thanks for your help!
> Julio
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/fbf8e5b6-f237-470c-9267-246132a2e0bc%40googlegroups.com
> 
> .
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CANrC0Bhf%2B0kN%3DpP7_fT%2BGFGfykS4G%3DawZSHufmGHQCw-y8B4FQ%40mail.gmail.com.


Re: [go-nuts] encoding/json character escaping question

2019-10-05 Thread David Finkel
On Thu, Oct 3, 2019 at 11:11 AM Poussier William 
wrote:

> Hello
>
> The encoding/json package escapes 0xA (line feed), 0xD (carriage return)
> and 0x9 (horizontal tab) using the escape character '\'. However, when it
> comes to 0x8 (backspace) and 0xc (form feed), it uses the Unicode escape
> sequence staring with '\u'.
>
> Reproducer: https://play.golang.org/p/jihv9sZUjvY
>
> I can't really grasp the reason behind this difference for characters <
> 0x20, even tho it is perfectly valid JSON, I expected to see \f and \b.
>
> Does anyone know the reason, if there is one that lead to this?
>

It looks like only a few of the RFC 8259 sec 7 special two-byte escapes are
supported:
https://github.com/golang/go/blob/go1.13.1/src/encoding/json/encode.go#L975-L994


Digging around the CLs linked from blame entries in that code-block, I
found this comment from rsc@  on
the CL that added handling for \r and \n:

> \r and \n is good.
> let's leave \b and \f out.
> no one cares about \f
> and more people know \b as
> word boundary than as backspace.
>
>


Note that using two-letter substitutions are optional according to the RFC
. (the relevant section):

> Alternatively, there are two-character sequence escape
>representations of some popular characters.  So, for example, a
>string containing only a single reverse solidus character *may be*
>represented more compactly as "\\".
>
>  To escape an extended character that is not in the Basic Multilingual
>Plane, the character is represented as a 12-character sequence,
>encoding the UTF-16 surrogate pair.  So, for example, a string
>containing only the G clef character (U+1D11E) may be represented as
>"\uD834\uDD1E".
>
>   string = quotation-mark *char quotation-mark
>
>   char = unescaped /
>   escape (
>   %x22 /  ; "quotation mark  U+0022
>   %x5C /  ; \reverse solidus U+005C
>   %x2F /  ; /solidus U+002F
>   %x62 /  ; bbackspace   U+0008
>   %x66 /  ; fform feed   U+000C
>   %x6E /  ; nline feed   U+000A
>   %x72 /  ; rcarriage return U+000D
>   %x74 /  ; ttab U+0009
>   %x75 4HEXDIG )  ; uU+
>
>   escape = %x5C  ; \
>
>   quotation-mark = %x22  ; "
>
>   unescaped = %x20-21 / %x23-5B / %x5D-10
>
>
On the other hand, it looks like on the decoding-side, the full complement
are supported:
https://github.com/golang/go/blob/b17fd8e49d24eb298c53de5cd0a8923f1e0270ba/src/encoding/json/decode.go#L1284-L1316



>
> Thanks
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/f3c65b8c-c612-4b75-852a-fda7b246a77e%40googlegroups.com
> 
> .
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CANrC0BgfkvkZJ-wxBtxWz%3DmvdUNh1%3DeQ%3Dq7PPFAxqA5K5m%3DAKQ%40mail.gmail.com.


Re: [go-nuts] Watches / Data breakpoints

2019-09-26 Thread David Finkel
On Thu, Sep 26, 2019 at 3:58 AM Stephen Illingworth <
stephen.t.illingwo...@gmail.com> wrote:

> Hi all,
>
> I have an awkward bug I'm trying to understand and I'm missing something
> in my toolbox. Is there any way of monitoring a variable for changes made
> to it? For example, I have a pointer type and I want a debugger to break
> whenever its value (ie. what it points to) changes.
>
> I call this a "watch" but I believe it's sometimes referred to as a "data
> breakpoint".
>
> I've looked at delve and can't see anything like it. I've had a quick look
> at VSCode and Goland and I can't see anything there either. Is there
> anything I've missed?
>
I don't see anything in Delve's docs either.
I'm pretty sure VSCode and Goland use Delve, so they won't work if Delve
doesn't.

With that said, I think gdb works to some extent with Go, and it supports
"watchpoints":
https://sourceware.org/gdb/current/onlinedocs/gdb/Set-Watchpoints.html#Set-Watchpoints
(Note: I haven't tried debugging a go binary with gdb, so I can't do much
more than point you at the manual)

>
> Help
>
> Stephen Illingworth.
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/CAPmHGLPa0sgU9NkewBmZKhqVV-fZaaAni8Uaq%2BY_aUQstSEeYA%40mail.gmail.com
> 
> .
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CANrC0BiHEFJ78n7UZ6fffPq8FChH9NiFscuz-c_XpuDo%3Dhi6DQ%40mail.gmail.com.


Re: [go-nuts] [Urgency] Error ctim value get from file.Stat().Sys().(*syscall.Stat_t)

2019-06-20 Thread David Finkel
On Thu, Jun 20, 2019 at 12:55 PM GoFreshMan <1on1y4u1...@gmail.com> wrote:

> *linux version: 5.1.9-300.fc30.x86_64*
> *linux dist: fedora 30*
> *go version: go1.12.5 linux/amd64*
>
>
> [ ~/Rhizobium]$ stat README.md
>  文件:README.md
>  大小:461块:8  IO 块:4096   普通文件
> 设备:805h/2053d  Inode:4199368 硬链接:1
> 权限:(0664/-rw-rw-r--)  Uid:( 1000/ dba)   Gid:( 1000/ dba)
> 环境:unconfined_u:object_r:user_home_t:s0
> 最近访问:2019-06-17 16:39:21.0 +0800 (last access)
> 最近更改:2019-06-18 10:40:27.0 +0800 (last change)
> 最近改动:2019-06-18 14:05:06.950815138 +0800 (last modified)
> 创建时间:2019-06-17 16:39:21.343782864 +0800 (create time)
>
>
>
>
> In my go program:
> package common
>
> import (
> "fmt"
> "os"
> "os/user"
> "syscall"
> "testing"
> "time"
> )
>
> func TestGetFileState(t *testing.T) {
> f, _ := os.Stat("/home/dba/Rhizobium/README.md")
> x := GetFileState1(f)
> fmt.Printf("%+v\n", f)
> fmt.Printf("%+v", x)
> }
>
> func GetFileState1(info os.FileInfo) FileStat1 {
> stat := info.Sys().(*syscall.Stat_t)
> fileState := FileStat1{
> Inode:   uint64(stat.Ino),
> Device:  uint64(stat.Dev),
> Name:info.Name(),
> Size:info.Size(),
> Mode:info.Mode(),
> CrtTime: time.Unix(int64(stat.Ctim.Sec), int64(stat.Ctim.Nsec)),
> ModTime: time.Unix(stat.Mtim.Sec, stat.Mtim.Nsec),
> AcsTime: time.Unix(stat.Atim.Sec, stat.Atim.Nsec),
> isDir:   info.IsDir(),
> }
> groupPointer, _ := user.LookupGroupId(fmt.Sprintf("%d", stat.Gid))
> fileState.userGroup = *groupPointer
>
> userPointer, _ := user.LookupId(fmt.Sprintf("%d", stat.Uid))
> fileState.user = *userPointer
> return fileState
> }
>
> type FileStat1 struct {
> Inode uint64
> Deviceuint64
> Name  string
> Size  int64 // bytes
> Mode  os.FileMode
> CrtTime   time.Time // 创建时间
> AcsTime   time.Time // 上次读取时间
> ModTime   time.Time // 上次修改时间
> isDir bool
> user  user.User
> userGroup user.Group
> }
>
> output:
>
> === RUN   TestGetFileState
> &{name:README.md size:461 mode:436 modTime:{wall:0 ext:63696422427
> loc:0x638c00} sys:{Dev:2053 Ino:4199368 Nlink:1 Mode:33204 Uid:1000
> Gid:1000 X__pad0:0 Rdev:0 Size:461 Blksize:4096 Blocks:8 Atim:{
> *Sec:1560760761* Nsec:0} Mtim:{Sec:1560825627 Nsec:0} Ctim:{Sec:
> *1560837906* Nsec:950815138} X__unused:[0 0 0]}}
> {Inode:4199368 Device:2053 Name:README.md Size:461 Mode:-rw-rw-r-- 
> CrtTime:*2019-06-18
> 14:05:06.950815138 +0800 CST* AcsTime:2019-06-17 16:39:21 +0800 CST
> ModTime:2019-06-18 10:40:27 +0800 CST isDir:false user:{Uid:1000 Gid:1000
> Username:dba Name:dba HomeDir:/home/dba} userGroup:{Gid:1000 Name:dba}}---
> PASS: TestGetFileState (0.00s)
> PASS
> ok  command-line-arguments 0.002s
>
>
> *Question:*
>
> why  file.Stat().Sys().(*syscall.Stat_t) get file create time is :
>
>  Ctim:{Sec:*1560837906* Nsec:950815138} === *2019-06-18
> 14:05:06.950815138 +0800 CST*
>
> access time is
>
> {*Sec:1560760761* Nsec:0}  2019-06-17 16:39:21 +0800
>
> It seems the ctim and atime just on the contray
>

We'd have to know more about the history of that particular file on your
system in order to provide more detailed information, but a couple things
to note that probably help explaining your confusion:

   - ctime is not the create time, it's the inode change time, so it gets
   updated whenever you change permissions, update the link-count (via a
   rename or  hardlink), or file-size change (among other things)
   - atime may not be reliable. E.G. filesystems mounted with the "noatime"
   option won't ever generate a write to the inode on its own to update the
   atime of a file; and "relatime" will limit how often it updates the atime
   timestamp.



>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/298e7dc4-1817-4933-a7d1-e9be00e9fa13%40googlegroups.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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CANrC0BgO_PTpjN3iq7NrUjE1B9JNimVS37H2khr0yiZ8JFeDhw%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.


Re: [go-nuts] Re: How to constant ?!

2019-05-28 Thread David Finkel
On Tue, May 28, 2019 at 11:04 AM Trig  wrote:

> Whoops... forgot to add the top line to the code syntax.  I really wish
> you could edit existing posts in this group.
>
> On Tuesday, May 28, 2019 at 10:03:05 AM UTC-5, Trig wrote:
>>
>> package main
>>
>> import "fmt"
>>
>> const (
>>  ExposedConstant  = "1"  // exposed outside of package
>>  internalConstant = "2"  // for use anywhere in package only
>> )
>>
>> func main() {
>>  const functionConstant = "3"  // usable anywhere in main func
>>
>>  fmt.Println(ExposedConstant, internalConstant, functionConstant)
>> }
>>
>>
>>
https://golang.org/ref/spec#Constants
Note that the const keyword can only be used with primitive types.
For more complicated values, I tend to use functions/methods. (the GC
compiler's inliner is smart enough to inline a function call to a function
with exactly one return statement containing a small struct literal)

e.g. https://play.golang.org/p/AaLXcZ-CYEY

package main
> import "fmt"
> // Foo is a structtype Foo struct {
>   A int
>   B string
> }
> // DefaultFoo returns a useful default structfunc DefaultFoo() Foo {
>   return Foo{
>   A: 1,
>   B: "abcd",
>   }
> }
> // Bim does somethingfunc Bim() {
>   fmt.Printf("%+v\n", DefaultFoo())
> }
>
>


>> On Tuesday, May 28, 2019 at 7:12:06 AM UTC-5, Ashutosh Baghel wrote:
>>>
>>> Hello folks,
>>>
>>> I want to declare a few variables constant. But I guess there is nothing
>>> as "Constant" type in GoLang. How do I achieve this in GoLang?
>>>
>> For those with an interest in the inlining behavior, Matt Godbolt's
Compiler Explorer supports Go. Here's a small modification of the example
above (mostly just moved it out of the main package and removed the imports
to reduce the amount of code generated): https://go.godbolt.org/z/izOJVU

-- 
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/c9b3b7df-b2da-42ce-bd9e-44ee1eb589ba%40googlegroups.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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CANrC0Bj_iiNPTxVzXF%2By4r-H4DXa7_HU%2BjF9%3D1jk7juvZ34zSA%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.


Re: [go-nuts] How is a for loop preempted in Go?

2019-02-23 Thread David Finkel
[The other responses have been excellent, but I wanted to point one thing
out.]

On Fri, Feb 22, 2019 at 3:17 AM Jingguo Yao  wrote:

> Consider the following code which launches two goroutines. Each
> goroutine uses a for loop to print messages.
>
> package main
>
> import (
> "fmt"
> "runtime"
> "time"
> )
>
> func main() {
>   count := runtime.GOMAXPROCS(1)
>   fmt.Printf("GOMAXPROCS: %d\n", count)
>
>   // goroutine 1
>   go func() {
> for {
>   fmt.Printf("1")
> }
>   }()
>
>   // goroutine 2
>   go func() {
> for {
>   fmt.Printf("2")
> }
>   }()
>
>   time.Sleep(20 * time.Second)
> }
>
> The code uses runtime.GOMAXPROCS(1) to make the Go runtime has only
> one processor (P). So there is only one OS thread (M) to run
> goroutines.  Without preemption, the M will run goroutine 1 or
> goroutine 2 continuously. The messages sent to the terminal should be
> all 1s or all 2s. But running the code prints interleaved 1s and 2s to
> the terminal, which means that some preemption happens. But
>
> https://www.quora.com/How-does-the-golang-scheduler-work/answer/Ian-Lance-Taylor
> says that:
>
> > A G can only be pre-empted at a safe point, which in the current
> > implementation can only happen when the code makes a function call.
>
> Since both goroutines do not make any function calls, there should be
> some other way to preempt a G. Can anyone give me an explanation of
> such kind of preemption?
>
Not only is fmt.Printf a function call, but it makes a blocking syscall
(write specifically),
which gives the go runtime license to spin up a new OS thread and
immediately schedule the other goroutine.
runtime.GOMAXPROCS(1) only tries to guarantee that one OS thread executing
Go code will be executing at a time.

(this has no bearing on the revised version without a call to fmt.Printf().)

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