Re: [go-nuts] go test cache: include umask as a test input for caching?

2024-09-17 Thread 'Axel Wagner' via golang-nuts
I think you are probably going to get better results by just filing a
proposal. That's the normal process which will end in a definite result one
way or the other, while mailing list threads tend to go in circles,
eventually.

On Tue, 17 Sept 2024 at 13:08, twp...@gmail.com  wrote:

>
> On Tuesday, September 17, 2024 at 12:44:42 PM UTC+2 Stephen Illingworth
> wrote:
>
> If the only problem is that the cache is getting in the way then you can
> run the tests such that test cache is not used. The idiomatic way is to use
> -count=1 on the test command line
>
> I would do this:
>
> go test -count=1 
>
> And then:
>
> go test 
>
>
> I am aware that I can work around go test cache's incorrect behavior by
> disabling the cache. This is annoying for several reasons:
> * I have to manually maintain a list of tests that are affected by the
> umask.
> * I have to run go test twice.
> * I don't get the speed-ups of caching when the caching should work, which
> slows down my development cycle.
>
> Note that all tests that write files are affected by umask, even if many
> people don't realize this. To demonstrate this, find a project that calls
> testing.T.TempDir() and run:
>
> $ umask 777
> $ go test ./... -count=1
>
> The odds are that the tests will fail.
>
> However, I want to make go test cache's behavior more correct for a case
> where it is currently incorrect for no measurable performance penalty. What
> are the reasons for *not* doing this?
>
>
> On Tuesday 17 September 2024 at 11:25:40 UTC+1 twp...@gmail.com wrote:
>
> > Should work, AIUI, even with the issues you mention. Or is there
> something else going on that I'm unaware of?
>
> The problem is not running the tests. The problem is that the test cache
> is not invalidated correctly.
>
> On Tuesday, September 17, 2024 at 11:52:35 AM UTC+2 Axel Wagner wrote:
>
> On Tue, 17 Sept 2024 at 10:33, twp...@gmail.com  wrote:
>
> umask cannot be set in subtests for two reasons:
> 1. It is a process-wide global variable stored by the operating system.
> Changing the umask in a test changes the umask for the entire process, i.e.
> it changes the umask for all tests.
> 2. It is not possible to set and restore the umask atomically. This makes
> it inherently racy for concurrent programs.
>
>
> I might be misunderstanding something, but neither of these seems to
> actually be a problem. Tests are not run concurrently, unless explicitly
> requested by calling `t.Parallel()`. The same goes for sub tests, I
> believe. So, simply doing
>
> func TestOne(t *testing.T) {
> defer syscall.Umask(syscall.Umask(0))
> // test goes here
> }
> func TestTwo(t *testing.T) {
> defer syscall.Umask(syscall.Umask(0777))
> // test goes here
> }
>
>
> To learn more about umask, and why it is special, please read the man page
> .
> On Monday, September 16, 2024 at 5:34:29 PM UTC+2 Jason Phillips wrote:
>
> Why can't it be set within subtests? Note that subtests (like regular
> tests) aren't run in parallel unless you explicitly call t.Parallel().
>
> On Friday, September 13, 2024 at 6:35:15 PM UTC-4 twp...@gmail.com wrote:
>
> > Personally, I would approach this kind of thing by writing a test that
> sets the umask to various different values and invokes subtests with
> each umask value.
>
> I would love to do this but umask is a process global (as far as I
> understand it) and so can't be set within subtests.
>
> On Saturday, September 14, 2024 at 12:33:19 AM UTC+2 Ian Lance Taylor
> wrote:
>
> On Fri, Sep 13, 2024 at 3:03 PM twp...@gmail.com 
> wrote:
> >
> > tl;dr: umask is a system-wide global that affects go tests and should be
> considered when validating go test's cache.
> >
> >
> > Motivation:
> >
> > I'm the author of a popular open source project that writes files to the
> user's home directory and cares about getting exact file permissions
> correct. The file permissions depend on the the current umask setting. As
> umask is a process global variable, it cannot be set for individual tests,
> and so separate tests are needed for different umasks.
> >
> > Currently changing the umask does not invalidate go test's cache, so I
> get incorrect test results if I change the umask and re-run go test.
> >
> >
> > Suggested solution:
> >
> > Include umask as an op in go test's id calculation.
> >
> >
> > Next steps:
> >
> > * Is this something that the Go project would consider?
> > * If so, I would be happy to submit a CL.
>
> Personally, I would approach this kind of thing by writing a test that
> sets the umask to various different values and invokes subtests with
> each umask value. That way the test is independent of the external
> environment.
>
> In general our approach has been that if your test intrinsically
> depends on the external environment, then you should run it with
> -test.run=1 to disable the test cache.
>
> Ian
>
> --
>
> You received this message because you are subscribed to the Google Groups
> "golang-n

Re: [go-nuts] go test cache: include umask as a test input for caching?

2024-09-17 Thread 'Axel Wagner' via golang-nuts
On Tue, 17 Sept 2024 at 10:33, twp...@gmail.com  wrote:

> umask cannot be set in subtests for two reasons:
> 1. It is a process-wide global variable stored by the operating system.
> Changing the umask in a test changes the umask for the entire process, i.e.
> it changes the umask for all tests.
> 2. It is not possible to set and restore the umask atomically. This makes
> it inherently racy for concurrent programs.
>

I might be misunderstanding something, but neither of these seems to
actually be a problem. Tests are not run concurrently, unless explicitly
requested by calling `t.Parallel()`. The same goes for sub tests, I
believe. So, simply doing

func TestOne(t *testing.T) {
defer syscall.Umask(syscall.Umask(0))
// test goes here
}
func TestTwo(t *testing.T) {
defer syscall.Umask(syscall.Umask(0777))
// test goes here
}

Should work, AIUI, even with the issues you mention. Or is there something
else going on that I'm unaware of?


> To learn more about umask, and why it is special, please read the man page
> .
> On Monday, September 16, 2024 at 5:34:29 PM UTC+2 Jason Phillips wrote:
>
>> Why can't it be set within subtests? Note that subtests (like regular
>> tests) aren't run in parallel unless you explicitly call t.Parallel().
>>
>> On Friday, September 13, 2024 at 6:35:15 PM UTC-4 twp...@gmail.com wrote:
>>
>>> > Personally, I would approach this kind of thing by writing a test that
>>> sets the umask to various different values and invokes subtests with
>>> each umask value.
>>>
>>> I would love to do this but umask is a process global (as far as I
>>> understand it) and so can't be set within subtests.
>>>
>>> On Saturday, September 14, 2024 at 12:33:19 AM UTC+2 Ian Lance Taylor
>>> wrote:
>>>
 On Fri, Sep 13, 2024 at 3:03 PM twp...@gmail.com 
 wrote:
 >
 > tl;dr: umask is a system-wide global that affects go tests and should
 be considered when validating go test's cache.
 >
 >
 > Motivation:
 >
 > I'm the author of a popular open source project that writes files to
 the user's home directory and cares about getting exact file permissions
 correct. The file permissions depend on the the current umask setting. As
 umask is a process global variable, it cannot be set for individual tests,
 and so separate tests are needed for different umasks.
 >
 > Currently changing the umask does not invalidate go test's cache, so
 I get incorrect test results if I change the umask and re-run go test.
 >
 >
 > Suggested solution:
 >
 > Include umask as an op in go test's id calculation.
 >
 >
 > Next steps:
 >
 > * Is this something that the Go project would consider?
 > * If so, I would be happy to submit a CL.

 Personally, I would approach this kind of thing by writing a test that
 sets the umask to various different values and invokes subtests with
 each umask value. That way the test is independent of the external
 environment.

 In general our approach has been that if your test intrinsically
 depends on the external environment, then you should run it with
 -test.run=1 to disable the test cache.

 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/c9dcf1bb-25ae-4e58-8714-66325077c2d1n%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/CAEkBMfFuM-1-k4XjcEG%3D16GV%2B3Ub_SNvmORyTUgih1piZNKqiA%40mail.gmail.com.


Re: [go-nuts] Suppress GoFmt-generated error with/tools.go?

2024-08-31 Thread 'Axel Wagner' via golang-nuts
On Sat, 31 Aug 2024 at 14:22, Mike Schinkel  wrote:

> Hi Alex & Peter,
>
> Thank you both for your replies.
>
> On Aug 30, 2024, at 2:43 AM, Axel Wagner 
> wrote:
> I don't think that error message comes from gofmt. As far as I am aware,
> gofmt only parses source code, it does not even do type-checking.
>
>
> As you sure about that?  Running this:
>
> go fmt ./tools.go
>
> Generates this error for me using go1.23.0 (vs. go1.22.x):
>
> tools.go:9:2: import "
> github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen" is a program,
> not an importable package
>

You are right, I can reproduce that. As Jan, I was using `gofmt`, not `go
fmt`. That's interesting.
It seems the main difference is that `go fmt` accepts packages (and so it
actually does have to look at import paths to a degree at least) while
`gofmt` accepts files.
Good to know. I think it probably shouldn't actually check the imports
beyond finding the package you want to format. Perhaps that can be fixed.


>
> FWIW you might be interested in https://github.com/golang/go/issues/48429,
> which gives a less hacky way to track tool dependencies and which (as far
> as I know) has been accepted and is being implemented, with some delays due
> to team changes. So, for the concrete issue, a solution is already being
> worked on.
>
>
> Thank you for that link. I will look into that for longer term.
>
> Shorter term, though it would be nice to find a way to resolve this.
>

Perhaps you can get your editor to run `gofmt` instead of `go fmt`?

I'm sceptical that there will be a shorter-term way to change anything on
the Go side - if this ends up being considered an issue to fix, it would
only get fixed in Go 1.24 at the earliest. And I would kind of hope that,
until then, #48429 is merged.


>
> On Aug 30, 2024, at 9:14 AM, peterGo  wrote:
> Let's use official Go sources.
>
> go/src/cmd/tools/tools.go:
>
> Indent the tools.go import statement by a tab to force a reformat.
>
> $ go fmt
> tools.go
> $
>
> Attempt to build package tools.
>
> $ go build
> package cmd/tools: build constraints exclude all Go files in
> /home/peter/go/src/cmd/tools
> $ go build -tags=tools
> tools.go:11:8: import "golang.org/x/tools/cmd/bisect" is a program, not
> an importable package
> $
>
> Looks like a go build generated error.
>
>
> Have you tried `go fmt` on `tools.go` with go1.23?
>
> I tried with go1.22.6 just now and it did not generate an error, but it
> does with go1.23.0.
>
> -Mke
>
>

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


Re: [go-nuts] Suppress GoFmt-generated error with/tools.go?

2024-08-29 Thread 'Axel Wagner' via golang-nuts
Hi,

I don't think that error message comes from gofmt. As far as I am aware,
gofmt only parses source code, it does not even do type-checking.
That is intentional - in general, Go tools tend to avoid relying on
stronger assumptions than they need. So I would assume that this error
message is produced by the editor running `go build` or something similar,
which does need to check imports for correctness. And because it requires
that, it seems unlikely that the error would be able to go away. Of course,
the editor could stop running that command in that context or suppress that
error message itself.

FWIW you might be interested in https://github.com/golang/go/issues/48429,
which gives a less hacky way to track tool dependencies and which (as far
as I know) has been accepted and is being implemented, with some delays due
to team changes. So, for the concrete issue, a solution is already being
worked on.

On Fri, 30 Aug 2024 at 03:54, Mike Schinkel  wrote:

> Hi all,
>
> I think I already know the answer, but hoping there is a way I am missing
> to get gofmt to stop generating the "import in a program, not an importable
> package" error when parsing a `tools.go` file with the `tools` build tag.
>
> If you are not familiar, there is an approach several people have written
> about to store references to your project's required Go-based CLI tools in
> a `tools.go` file:
>
> https://play-with-go.dev/tools-as-dependencies_go119_en/
> https://www.jvt.me/posts/2022/06/15/go-tools-dependency-management/
>
> I am using it because oapi-codegen recommends it for maintaining enabling
> others who may clone your repo to easily get the proper tools then need
> installed:
>
> https://github.com/oapi-codegen/oapi-codegen/?tab=readme-ov-file#install
>
> And grpc-gateway evidently recommends it too:
>
> https://github.com/grpc-ecosystem/grpc-gateway#installation
>
> When I run gofmt — which GoLand does prior to a commit — it generates that
> as an error.  People have said just to ignore it:
>
> https://github.com/grpc-ecosystem/grpc-gateway/issues/3515
>
> https://stackoverflow.com/questions/77664121/import-is-a-program-not-an-importable-package
>
> However — call me anal —I really want to ensure no errors are generated
> unless they are errors I really need to fix. Otherwise I will likely get
> complacent and accidentally commit a real error.
>
> Is there any way to get gofmt to ignore code based on build tags, e.g.
> `tools` in this case?
>
> -Mike
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/31160B8D-8DBC-43C7-8396-F74B2B8AFD92%40newclarity.net
> .
>

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


Re: [go-nuts] Add yield types for range over function

2024-08-22 Thread 'Axel Wagner' via golang-nuts
I don't really understand the question. What I'm saying is
1. we don't want them to be defined types, because of the issue I
described, so
2. it probably needs to be possible to have generic type aliases first and
3. once that is possible, we might add `Yield` and `Yield2` as type-aliases
to the `iter` package.
And if that happens, then yes, you could use them, of course.

On Thu, 22 Aug 2024 at 11:03, lijh8  wrote:

> Hi,
>
> Do you mean that if the new Yield types are in the iter package,
> it can be used after that?
>
> ```
>
> type Yield[V any] func(V) bool
> type Yield2[K comparable, V any] func(K, V) bool
> type Seq[E any] func(Yield[E])
> type Seq2[K comparable, V any] func(Yield2[K, V])
>
> // not importing iter, so can't use the named types
> func All2[E any](s []E) func(func(E) bool) {
> return func(yield func(E) bool) {
> for _, v := range s {
> if !yield(v) {
> return
> }
> }
> }
> }
>
> func All2_b[E any](s []E) Seq[E] {
> return func(yield Yield[E]) {
> for _, v := range s {
> if !yield(v) {
> return
> }
> }
> }
> }
>
> ```
>
>

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


Re: [go-nuts] Add yield types for range over function

2024-08-21 Thread 'Axel Wagner' via golang-nuts
The plan is, to introduce type-aliases in the `iter` package:
type Yield[E any] = func(E) bool
type Yield2[K, V any] = func(K, V) bool
The reason to make these type-aliases instead of defined types is that it
should be possible to define iterators without needing to import the `iter`
package. But we still need to be assignable to `iter.Seq`. With defined
types, that wouldn't be possible .

However, making them type-aliases, is blocked on #46477
. But it should happen for Go
1.124

On Wed, 21 Aug 2024 at 22:48, 'lijh8' via golang-nuts <
golang-nuts@googlegroups.com> wrote:

> Hi community,
>
> The type of yield occurs twice in the function declaration and
> at the return statement.
>
> ```
>
> func (s *Set[E]) All() iter.Seq[E] {
> return func(yield func(E) bool) {
> for v := range s.m {
> if !yield(v) {
> return
> }
> }
> }
> }
>
> ```
>
> How about add yield types like this?
> I think it can simplify the code a bit.
>
> ```
>
> type Yield[V any] func(V) bool
> type Yield2[K, V any] func(K, V) bool
>
> func sliceDemo[K int, V any](s []V) func(Yield2[K, V]) {
> return func(yield Yield2[K, V]) {
> for i, v := range s {
> if !yield(K(i), v) {
> break
> }
> }
> }
> }
>
> func mapDemo[K comparable, V any](s map[K]V) func(Yield2[K, V]) {
> return func(yield Yield2[K, V]) {
> for i, v := range s {
> if !yield(i, v) {
> break
> }
> }
> }
> }
>
> ```
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/tencent_7983E02A0C5363ABC9B43CD458E0A1B7FC07%40qq.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/CAEkBMfGf5ANEkQQgrgGiAt7tN0GapaOGJS3eSPupq0aNwkdmww%40mail.gmail.com.


Re: [go-nuts] first class iterator values?

2024-08-16 Thread &#x27;Axel Wagner&#x27; via golang-nuts
Or with half the allocations: https://go.dev/play/p/LmtNdR-hfWY
I can't get it down to 1 allocation, which should be the theoretical
minimum, as I can't get the compiler to move the closure and the state
being closed over into one allocation.

On Fri, 16 Aug 2024 at 11:43, Axel Wagner 
wrote:

> You can also use reflect to get non-restartable map-iterators. It has some
> additional setup cost, but I don't think it's *a lot* and after that it
> should be relatively cheap.
> https://go.dev/play/p/vUec8AYhFPa
>
> On Fri, 16 Aug 2024 at 09:34, Costanza, Pascal 
> wrote:
>
>> I haven’t double-checked, but according to the documentation of the
>> standard library, this should be possible: You can get an iterator over a
>> map from the maps package, and then convert it into a pull-style iterator
>> using the iter package.
>>
>> > On 16 Aug 2024, at 00:47, 'Dan Kortschak' via golang-nuts <
>> golang-nuts@googlegroups.com> wrote:
>> >
>> > On Thu, 2024-08-15 at 22:32 +, Costanza, Pascal wrote:
>> >> I believe the indices in your examples are updated in the wrong
>> >> place. The following seems to do what I believe you
>> >> expect: https://go.dev/play/p/U2YQM3fOz98
>> >
>> > Thanks for clearing that up; that's very useful to know. This means the
>> > issue is only whether map iterators will ever be exposed. I'm (sadly)
>> > guessing that this will not happen.
>> >
>> > Dan
>> >
>> > --
>> > You received this message because you are subscribed to the Google
>> Groups "golang-nuts" group.
>> > To unsubscribe from this group and stop receiving emails from it, send
>> an email to golang-nuts+unsubscr...@googlegroups.com.
>> > To view this discussion on the web visit
>> https://groups.google.com/d/msgid/golang-nuts/75d4b45c94122309c011f60e37903ad86eb6238e.camel%40kortschak.io
>> .
>>
>> Intel Corporation nv/sa
>> Froissartstraat 95
>> 1040 Etterbeek
>> RPR (Brussel) 0415.497.718.
>> Citibank, Brussels, account BE52 5701 0312 5509
>>
>> This e-mail and any attachments may contain confidential material for the
>> sole use of the intended recipient(s). Any review or distribution by others
>> is strictly prohibited. If you are not the intended recipient, please
>> contact the sender and delete all copies.
>>
>> --
>> You received this message because you are subscribed to the Google Groups
>> "golang-nuts" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to golang-nuts+unsubscr...@googlegroups.com.
>> To view this discussion on the web visit
>> https://groups.google.com/d/msgid/golang-nuts/9894AABA-166B-4A9F-A04A-5C394A1F524A%40intel.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/CAEkBMfEbHZKwuHX%3DxzLKJYPpuPGQKZYsJ0xbR%2BdWypREODQWyw%40mail.gmail.com.


Re: [go-nuts] first class iterator values?

2024-08-16 Thread &#x27;Axel Wagner&#x27; via golang-nuts
You can also use reflect to get non-restartable map-iterators. It has some
additional setup cost, but I don't think it's *a lot* and after that it
should be relatively cheap.
https://go.dev/play/p/vUec8AYhFPa

On Fri, 16 Aug 2024 at 09:34, Costanza, Pascal 
wrote:

> I haven’t double-checked, but according to the documentation of the
> standard library, this should be possible: You can get an iterator over a
> map from the maps package, and then convert it into a pull-style iterator
> using the iter package.
>
> > On 16 Aug 2024, at 00:47, 'Dan Kortschak' via golang-nuts <
> golang-nuts@googlegroups.com> wrote:
> >
> > On Thu, 2024-08-15 at 22:32 +, Costanza, Pascal wrote:
> >> I believe the indices in your examples are updated in the wrong
> >> place. The following seems to do what I believe you
> >> expect: https://go.dev/play/p/U2YQM3fOz98
> >
> > Thanks for clearing that up; that's very useful to know. This means the
> > issue is only whether map iterators will ever be exposed. I'm (sadly)
> > guessing that this will not happen.
> >
> > Dan
> >
> > --
> > You received this message because you are subscribed to the Google
> Groups "golang-nuts" group.
> > To unsubscribe from this group and stop receiving emails from it, send
> an email to golang-nuts+unsubscr...@googlegroups.com.
> > To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/75d4b45c94122309c011f60e37903ad86eb6238e.camel%40kortschak.io
> .
>
> Intel Corporation nv/sa
> Froissartstraat 95
> 1040 Etterbeek
> RPR (Brussel) 0415.497.718.
> Citibank, Brussels, account BE52 5701 0312 5509
>
> This e-mail and any attachments may contain confidential material for the
> sole use of the intended recipient(s). Any review or distribution by others
> is strictly prohibited. If you are not the intended recipient, please
> contact the sender and delete all copies.
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/9894AABA-166B-4A9F-A04A-5C394A1F524A%40intel.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/CAEkBMfEecPJLgcqCCDX8D1q7g8Ve4L56BGp5S1MXXawVdyWRDg%40mail.gmail.com.


Re: [go-nuts] After Disbanding the Python Team, Google’s Go Team Faces Turmoil: Technical Lead and 12-Year Project Leader Steps Down

2024-08-15 Thread &#x27;Axel Wagner&#x27; via golang-nuts
The facts of the title are correct. See here:
https://techcrunch.com/2024/05/01/google-lays-off-staff-from-flutter-dart-python-weeks-before-its-developer-conference/
https://groups.google.com/g/golang-dev/c/0OqBkS2RzWw
However, mentioning these in the same sentences seems to drum up a storm in
a water glass to me. They have very little in common.

On Thu, 15 Aug 2024 at 08:51, Amnon  wrote:

>
> https://blog.stackademic.com/after-disbanding-the-python-team-googles-go-team-faces-turmoil-12-year-project-leader-steps-down-29c4248ceb85
>
> I could not read this article as it is behind a pay-wall.
> But the title looks interesting, (and worrying if correct).
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/0255e670-86e5-4c37-845f-d64aba29608en%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/CAEkBMfE-8d3HCZ-uNKj%3DjPJbphX6ykO%2BjQ9S%3DNBJg%3DPt1zMXLg%40mail.gmail.com.


Re: [go-nuts] generic multitype inference, some but not others

2024-08-10 Thread &#x27;Axel Wagner&#x27; via golang-nuts
That is not possible, currently. You can only omit type parameters from the
end of the list, to have them inferred. So, in your case, you are going to
have to specify all type parameters.

On Sat, 10 Aug 2024 at 19:26, 'simon place' via golang-nuts <
golang-nuts@googlegroups.com> wrote:

> any support for partial inference? (can't find/hit on syntax)
>
> like...
>
> ```
> func X[T Integer,U Integer](t T,u U){}
> ```
>
> when, say, t can be inferred but not u.
>
> looking for something like...
>
> ```
> var a uint
>  X[_,uint8]X(a,5)]()
> ```
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/334a47a1-6eb7-43b0-9bd8-444efdd86d2an%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/CAEkBMfF%3Dzy9KVLBTzgOA0-EZXKaiMF_C36fDh4Ro6E%3DgsE_uwg%40mail.gmail.com.


Re: [go-nuts] Request for Removal of Problematic Version: github.com/alibabacloud-go/ecs-20140526/v4 v4.24.17

2024-08-01 Thread &#x27;Axel Wagner&#x27; via golang-nuts
Hi,

I believe module retraction 
was designed for this specific use case. It allows you to mark a specific
version as defective, without breaking any builds or anything - and without
requiring manual intervention by any module proxies. Note, in particular,
that there are more module proxies than just the default, public one. Even
if a version gets removed from that, people might still get the defective
version from a private or third-party proxy they use. Retraction doesn't
have that issue.

On Fri, 2 Aug 2024 at 06:23, papaya du  wrote:

> Dear Go Package Management Team,
>
> We have identified critical issues in the `v4.24.17` version of our
> package `github.com/alibabacloud-go/ecs-20140526/v4`
>  that severely affect
> its usability. To prevent any disruptions for users who rely on this
> package, we kindly request the removal of this specific version from the
> repository.
>
> Details:
> - Package: github.com/alibabacloud-go/ecs-20140526/v4
> - Version to be removed: v4.24.17
>
> Please note that we have already deleted the corresponding release and tag
> from our GitHub repository. The issues have been resolved in later
> versions, and we recommend users to update to the latest stable release.
>
> We understand the importance of maintaining a coherent and reliable
> package ecosystem and are committed to ensuring the quality and stability
> of our offerings. We apologize for any inconvenience caused and appreciate
> your assistance in this matter.
>
> Thank you for your attention and support. Should you require any
> additional information, please do not hesitate to contact us.
>
> Best regards.
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/a202c46f-1545-4863-8f62-dc67bbcd2e8en%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/CAEkBMfFY50pHByzr_3HrViCh4--vJyf3tVEJSO_f%2BhVBu_eJvQ%40mail.gmail.com.


Re: [go-nuts] might be a hole in Golang specification regarding the definition of "addressable"

2024-07-16 Thread &#x27;Axel Wagner&#x27; via golang-nuts
Hi,

> However, I would like to point out that selector rule 3 states:
>
> As an exception, if the type of x is a defined pointer type and (*x).f is
> a valid selector expression denoting a field (but not a method), then x.f
> is shorthand for (**x).f.*
>
> The emphasis here is on "defined pointer type." In the code, *s is a
> composite pointer literal type, not a defined pointer type. Therefore, I
> believe this rule does not apply in this case.
>
As I mentioned on slack, the fact that this is not a defined pointer type
means that is not the right rule to look at. Instead, you need to look at
the first rule in the list.

> Furthermore, in selector rule 1, it only states that "x.f denotes the
> field or method." The term "denotes" is somewhat ambiguous and does not
> imply implicit pointer indirection.
>
I don't think this particular level of language-lawyering is useful. The
spec is not a legal document or anything like that and should be read for
intent.
Writing `f().i` is allowed and well-defined, so the goal should be to
justify *that* it is correct, not to come up with readings making it
incorrect. A gracious reading of the spec here seems pretty clear.


> 在2024年7月17日星期三 UTC+8 12:51:48 写道:
>
>> On Tue, Jul 16, 2024 at 9:29 PM 王旭东  wrote:
>> >
>> > Hi, I have a question about "addressable."
>> >
>> > The following code illustrates my question (see the comments):
>> > https://go.dev/play/p/xpiPXuEqh0O?v=gotip
>> >
>> >
>> >
>> > I also posted question in the Gopher Slack channel, and @Axel Wagner
>> provided a detailed explanation, suggesting that this might be a gap in the
>> Go specification.
>> > @Jason Phillips recommended that I ask this question in the GitHub
>> issues and the golang-nuts mailing list.
>> >
>> > I really appreciate everyone’s help mentioned, but I still don’t have a
>> clear conclusion.
>> >
>> > To simplify: my question is why the result of myfunReturnPointer() is
>> addressable if we strictly follow the specification.
>>
>>
>> In https://go.dev/ref/spec#Selectors the spec explains that if the
>> type of x is a pointer, then the selector expression x.f is shorthand
>> for (*x).f. That is the case in your playground example: the
>> expression myfunReturnPointer().i is short for
>> (*myfunReturnPointer()).i. The pointer indirection
>> *myfunReturnPointer() is addressable according to
>> https://go.dev/ref/spec#Address_operators. So this is a field
>> selector of an addressable struct operand.
>>
>> 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/0fb5aa3e-4568-4520-bd42-ff01c1a2bd54n%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/CAEkBMfH5K%2BKC7toieX30nWO8Umt7OnoYGwfd6h4FsTsW9uP3qQ%40mail.gmail.com.


Re: [go-nuts] might be a hole in Golang specification regarding the definition of "addressable"

2024-07-16 Thread &#x27;Axel Wagner&#x27; via golang-nuts
Oh, I only just realized that "pointer indirection" is literally in that
list of addressable things. For some reason I have overlooked that, even
after re-reading the section of the spec several times. That really makes
this clear.

On Wed, 17 Jul 2024 at 06:51, Ian Lance Taylor  wrote:

> On Tue, Jul 16, 2024 at 9:29 PM 王旭东  wrote:
> >
> > Hi, I have a question about "addressable."
> >
> > The following code illustrates my question (see the comments):
> > https://go.dev/play/p/xpiPXuEqh0O?v=gotip
> >
> >
> >
> > I also posted question in the Gopher Slack channel, and @Axel Wagner
> provided a detailed explanation, suggesting that this might be a gap in the
> Go specification.
> > @Jason Phillips recommended that I ask this question in the GitHub
> issues and the golang-nuts mailing list.
> >
> > I really appreciate everyone’s help mentioned, but I still don’t have a
> clear conclusion.
> >
> > To simplify: my question is why the result of myfunReturnPointer() is
> addressable if we strictly follow the specification.
>
>
> In https://go.dev/ref/spec#Selectors the spec explains that if the
> type of x is a pointer, then the selector expression x.f is shorthand
> for (*x).f.  That is the case in your playground example: the
> expression myfunReturnPointer().i is short for
> (*myfunReturnPointer()).i.  The pointer indirection
> *myfunReturnPointer() is addressable according to
> https://go.dev/ref/spec#Address_operators.  So this is a field
> selector of an addressable struct operand.
>
> 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/CAOyqgcUL0D9a0nmXP%2BNJTPrax-ixWFUvRwuUAK5m1G-LtjzH7w%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/CAEkBMfFB8YNo2V%2BkDXwbDGMCzPyp8tEXHmTt0OBE%3DiSY1%2Bjf6g%40mail.gmail.com.


Re: [go-nuts] Potential Issue in errgroup

2024-07-02 Thread &#x27;Axel Wagner&#x27; via golang-nuts
(sorry, didn't hit "Reply All", apparently)

Hi,

I don't believe the semaphore has anything to do with the wait group
counter. So I don't believe it is relevant to this question. Note that a
goroutine can be interrupted at any time anyways, so whether or not that
code is there doesn't matter for correctness.

At that point, the issue comes down to "if you call Go and Wait
concurrently, may Wait return before the function passed to Go finishes"
and the answer to that is yes. That is analogous to calling wg.Add and
wg.Wait concurrently for a sync.WaitGroup and it is valid for that to
execute as if the Wait has been called, returned and then Add is called.

The way to avoid that is to only call Wait after all the Go calls have
returned. That is, to not call Wait and Go concurrently.

On Tue, 2 Jul 2024 at 14:43, Icey  wrote:

> In errgroup, the step to increment the WaitGroup counter (wg.Add) is
> written after acquiring a token from the semaphore (sem). Is it possible
> that if all goroutines finish execution and call wg.Done at nearly the same
> time, the currently blocked goroutines do not immediately call wg.Add due
> to scheduling issues, resulting in the WaitGroup counter dropping to zero
> and causing wg.Wait() to return prematurely, leading to errors in the
> program?
>
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/22ceece2-843c-47d6-ab5b-b5ddc5e51176n%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/CAEkBMfFWRaGQqWyqcOBs34dOpCWPRf4EbfWVJGes6K%3DC4MH%2B0A%40mail.gmail.com.


Re: [go-nuts] How does bytealg.MakeNoZero() work?

2024-06-25 Thread &#x27;Axel Wagner&#x27; via golang-nuts
And in terms of practical advice:

You might be able to use go:linkname yourself to get access to that
functionality from the runtime. But note that go:linkname is being locked
down in Go 1.23 , so that is not
a future-proof plan.

Your best bet is probably to file a proposal to get the functionality you
want for strings.Builder. Or to get an exported API (say in the runtime
package) to allocate non-zeroed memory.

Otherwise, you might be able to use `unsafe` to access the unexported
fields of `strings.Builder`. That is, you can define your type as
type MyBuilder struct {
strings.Builder
}
and then add methods to that which use `unsafe` to do what you want. Though
that will, of course, also be dangerous and should be guarded with build
tags for the used Go version, at the least.

On Wed, 26 Jun 2024 at 08:46, Axel Wagner 
wrote:

> It is defined in the runtime and go:linkname'd into the bytealg package:
>
> https://github.com/golang/go/blob/90bcc552c0347948166817a602f612f219bc980c/src/runtime/slice.go#L394
>
> From the spec :
>
>> A function declaration without type parameters may omit the body. Such a
>> declaration provides the signature for a function implemented outside Go,
>> such as an assembly routine
>
>
> How that works is, of course, implementation defined. It may be using
> assembly or, as in this case, with the body being provided by the linker
> later.
>
> On Wed, 26 Jun 2024 at 08:38, Mike Schinkel  wrote:
>
>> Can someone help me understand how `bytealg.MakeNoZero()` in the Go
>> standard library works, please?
>>
>>
>> https://github.com/golang/go/blob/master/src/internal/bytealg/bytealg.go#L118
>>
>> In the source it is a `func` without a body, and in my own code that
>> won't compile in Go; I get "missing function body."  Where is its
>> implementation and how does the Go compiler handle it?
>>
>> I discovered `bytealg.MakeNoZero()` looking into the source for
>> `strings.Builder`:
>>
>> https://github.com/golang/go/blob/master/src/strings/builder.go#L61
>>
>> I was considering following the advice in Go Proverbs that "A little
>> copying is better than a little dependency" but I obviously found that I
>> cannot copy it to my own package and compile it, at least not as-is.
>>
>> I wanted to create my own version of `strings.Builder` that has a
>> `Rewind()` method to allow slicing one or more characters from the internal
>> `buf` buffer, e.g.:
>>
>> https://github.com/golang/go/blob/master/src/strings/builder.go#L23
>>
>> func (b *StringBuilder) Rewind(n int) {
>>if n > len(b.buf) {
>>  n = len(b.buf)
>>}
>>b.buf = b.buf[:len(b.buf)-n]
>> }
>>
>> I could of course modify the code of `strings.Builder` to replace
>> `bytealg.MakeNoZero()` but then I would have a less performant string
>> builder, especially for larger strings:
>>
>>
>> https://github.com/golang/go/commit/132fae93b789ce512068ff4300c665b40635b74e
>>
>> Any insight into `bytealg.MakeNoZero()` would be appreciated.
>>
>> -Mike
>>
>> --
>> You received this message because you are subscribed to the Google Groups
>> "golang-nuts" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to golang-nuts+unsubscr...@googlegroups.com.
>> To view this discussion on the web visit
>> https://groups.google.com/d/msgid/golang-nuts/FEC2DD8C-7664-425E-8905-A21D49257975%40newclarity.net
>> 
>> .
>>
>

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


Re: [go-nuts] How does bytealg.MakeNoZero() work?

2024-06-25 Thread &#x27;Axel Wagner&#x27; via golang-nuts
It is defined in the runtime and go:linkname'd into the bytealg package:
https://github.com/golang/go/blob/90bcc552c0347948166817a602f612f219bc980c/src/runtime/slice.go#L394

>From the spec :

> A function declaration without type parameters may omit the body. Such a
> declaration provides the signature for a function implemented outside Go,
> such as an assembly routine


How that works is, of course, implementation defined. It may be using
assembly or, as in this case, with the body being provided by the linker
later.

On Wed, 26 Jun 2024 at 08:38, Mike Schinkel  wrote:

> Can someone help me understand how `bytealg.MakeNoZero()` in the Go
> standard library works, please?
>
>
> https://github.com/golang/go/blob/master/src/internal/bytealg/bytealg.go#L118
>
> In the source it is a `func` without a body, and in my own code that won't
> compile in Go; I get "missing function body."  Where is its implementation
> and how does the Go compiler handle it?
>
> I discovered `bytealg.MakeNoZero()` looking into the source for
> `strings.Builder`:
>
> https://github.com/golang/go/blob/master/src/strings/builder.go#L61
>
> I was considering following the advice in Go Proverbs that "A little
> copying is better than a little dependency" but I obviously found that I
> cannot copy it to my own package and compile it, at least not as-is.
>
> I wanted to create my own version of `strings.Builder` that has a
> `Rewind()` method to allow slicing one or more characters from the internal
> `buf` buffer, e.g.:
>
> https://github.com/golang/go/blob/master/src/strings/builder.go#L23
>
> func (b *StringBuilder) Rewind(n int) {
>if n > len(b.buf) {
>  n = len(b.buf)
>}
>b.buf = b.buf[:len(b.buf)-n]
> }
>
> I could of course modify the code of `strings.Builder` to replace
> `bytealg.MakeNoZero()` but then I would have a less performant string
> builder, especially for larger strings:
>
>
> https://github.com/golang/go/commit/132fae93b789ce512068ff4300c665b40635b74e
>
> Any insight into `bytealg.MakeNoZero()` would be appreciated.
>
> -Mike
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/FEC2DD8C-7664-425E-8905-A21D49257975%40newclarity.net
> 
> .
>

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


Re: [go-nuts] Comparison of pointers to distinct zero-sized variables

2024-06-25 Thread &#x27;Axel Wagner&#x27; via golang-nuts
Hi,

you might be interested to learn that Ian has filed a CL adding an FAQ entry
.

On Thu, 20 Jun 2024 at 16:18, Oliver Eikemeier 
wrote:

> Thanks for that example.
>
> The issue is that you and I have constructed aliased variables that the
> optimizer assumes are not aliased. Therefore the “false” on comparison,
> which also happens with pointers to zero-sized variables, but is much more
> common in the latter case.
>
> This is interesting. I’m not enough of a compiler buff to say that this
> assumption is reasonable - Go is 14 years old, so it seems to work - but
> obviously one can write code where it is false, the “zero-sized pointers”
> being the most prominent example. Anyone has a pointer to the alias
> analysis design of the Go compiler?
>
> Am 20.06.2024 um 15:57 schrieb Axel Wagner  >:
>
> I don't believe the issue in this case really is to do with zero-sized
> variables. Here is an example with the same output, not involving any
> zero-sized variables:
> https://go.dev/play/p/JzbwbVqBR0k
> The issue is that you treat a `*struct{}` as an `*int` - that is, you
> explicitly obtain a pointer to invalid memory - and then expect that to
> have any reasonable behaviour.
>
>
>

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


Re: [go-nuts] Go import redirect docs are unclear

2024-06-23 Thread &#x27;Axel Wagner&#x27; via golang-nuts
The meta tag I gave differs from the meta tag the documentation gave.

On Mon, 24 Jun 2024 at 02:50, will@gmail.com 
wrote:

> >Most web servers automatically serve an `index.html` for a request to a
> directory. The intent is to use something like that. Though note that you
> can also use a fuller path: That is, if your git-repo is at `
> https://code.org/r/exproj`  and has import
> path `example.com/exproj` , you can host a
> single HTML file at `example.com/exproj` 
> containing
> `https://code.org/r/p/exproj";>` (I believe).
>
> The linked-to documentation
>  seems to conflict
> with that (emphasis mine):
>
> >For example,
> >
> >import "example.org/pkg/foo"
> >
> >will result in the following requests:
> >
> >https://example.org/pkg/foo?go-get=1 (preferred)
> >http://example.org/pkg/foo?go-get=1  (fallback, only with use of
> correctly set GOINSECURE)
> >
> >If that page contains the meta tag
> >
> >https://code.org/r/p/exproj";>
> >
> >*the go tool will verify that https://example.org/?go-get=1
>  contains the same meta tag* and then git
> clone https://code.org/r/p/exproj into GOPATH/src/example.org.
>
> There's a proposal for removing this requirement:
> https://github.com/golang/go/issues/54530
> On Sunday, June 23, 2024 at 7:43:54 AM UTC-7 Axel Wagner wrote:
>
>> On Sun, 23 Jun 2024 at 16:17, Tobias Klausmann 
>> wrote:
>>
>>> Hi!
>>>
>>> On https://pkg.go.dev/cmd/go#hdr-Remote_import_paths, in the section
>>> about using meta tags to redirect from some domain to a known forge, it
>>> says:
>>>
>>> > For example,
>>> >
>>> > `import "example.org/pkg/foo"`
>>> >
>>> > will result in the following requests:
>>> >
>>> > `https://example.org/pkg/foo?go-get=1`
>>> 
>>> >
>>> > If that page contains the meta tag
>>> >
>>> > `https://code.org/r/p/exproj";>`
>>> >
>>> > the go tool will verify that https://example.org/?go-get=1 contains
>>> > the same meta tag and then git clone https://code.org/r/p/exproj into
>>> > GOPATH/src/example.org.
>>>
>>> This is confusing me. I get that https://example.org/pkg/foo?go-get=1
>>> should have a meta tag of this form:
>>>
>>> ```
>>> https://code.org/r/p/exproj";>
>>> ```
>>>
>>> But what meta tag should the / page have? The same? Then just doing this
>>> with static files (which I vastly prefer) is not possible.
>>
>>
>> Most web servers automatically serve an `index.html` for a request to a
>> directory. The intent is to use something like that. Though note that you
>> can also use a fuller path: That is, if your git-repo is at `
>> https://code.org/r/exproj`  and has import
>> path `example.com/exproj` , you can host a
>> single HTML file at `example.com/exproj` 
>> containing
>> `https://code.org/r/p/exproj";>`
>> (I believe).
>>
>> It's also unclear what purpose this has (or why the request to /pkg/foo
>>> is made).
>>>
>>
>> The Request to `/pkg/foo` is made, because the Go tool does not know
>> whether the repository root (today probably the module path) is at the
>> import path referred to as `example.com/pkg/foo`
>> , `example.com/pkg` 
>> (and the wanted package is in the folder `foo` of that repo) or `
>> example.com` (and the wanted package is in the folder `pkg/foo` of that
>> repo). Making the deepest request first is intended to answer that question.
>>
>> I'm not entirely certain what the purpose of the second request is. My
>> guess is, that it is to prevent some form of hijacking, but how exactly
>> that would work, I'm not sure off the top of my hat.
>>
>>
>>>
>>> Can anybody shed some light?
>>>
>>> Best,
>>> Tobias
>>>
>>> --
>>> You received this message because you are subscribed 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/a0a7d30f-8e83-4769-8e03-dd57a76a8a88%40skade.local
>>> .
>>>
>> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/80214469-3211-4799-a67f-867f57adcbcen%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-nut

Re: [go-nuts] Go import redirect docs are unclear

2024-06-23 Thread &#x27;Axel Wagner&#x27; via golang-nuts
On Sun, 23 Jun 2024 at 16:17, Tobias Klausmann 
wrote:

> Hi!
>
> On https://pkg.go.dev/cmd/go#hdr-Remote_import_paths, in the section
> about using meta tags to redirect from some domain to a known forge, it
> says:
>
> > For example,
> >
> > `import "example.org/pkg/foo"`
> >
> > will result in the following requests:
> >
> > `https://example.org/pkg/foo?go-get=1`
> 
> >
> > If that page contains the meta tag
> >
> > `https://code.org/r/p/exproj";>`
> >
> > the go tool will verify that https://example.org/?go-get=1 contains
> > the same meta tag and then git clone https://code.org/r/p/exproj into
> > GOPATH/src/example.org.
>
> This is confusing me. I get that https://example.org/pkg/foo?go-get=1
> should have a meta tag of this form:
>
> ```
> https://code.org/r/p/exproj";>
> ```
>
> But what meta tag should the / page have? The same? Then just doing this
> with static files (which I vastly prefer) is not possible.


Most web servers automatically serve an `index.html` for a request to a
directory. The intent is to use something like that. Though note that you
can also use a fuller path: That is, if your git-repo is at `
https://code.org/r/exproj` and has import path `example.com/exproj`, you
can host a single HTML file at `example.com/exproj` containing
`https://code.org/r/p/exproj";>`
(I believe).

It's also unclear what purpose this has (or why the request to /pkg/foo is
> made).
>

The Request to `/pkg/foo` is made, because the Go tool does not know
whether the repository root (today probably the module path) is at the
import path referred to as `example.com/pkg/foo`, `example.com/pkg` (and
the wanted package is in the folder `foo` of that repo) or `example.com`
(and the wanted package is in the folder `pkg/foo` of that repo). Making
the deepest request first is intended to answer that question.

I'm not entirely certain what the purpose of the second request is. My
guess is, that it is to prevent some form of hijacking, but how exactly
that would work, I'm not sure off the top of my hat.


>
> Can anybody shed some light?
>
> Best,
> Tobias
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/a0a7d30f-8e83-4769-8e03-dd57a76a8a88%40skade.local
> .
>

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


Re: [go-nuts] Comparison of pointers to distinct zero-sized variables

2024-06-20 Thread &#x27;Axel Wagner&#x27; via golang-nuts
I want to re-emphasise that both of these examples violate the allowed
usages of unsafe.Pointer defined by gc. So I would argue that, yes, its
expectation is reasonable, because it explicitly told you not to create
this situation.

If you can construct a program that does not violate the unsafe.Pointer
rules and yet behaves unexpectedly, the question might be more ambiguous.

On Thu 20. Jun 2024 at 16:18, Oliver Eikemeier 
wrote:

> Thanks for that example.
>
> The issue is that you and I have constructed aliased variables that the
> optimizer assumes are not aliased. Therefore the “false” on comparison,
> which also happens with pointers to zero-sized variables, but is much more
> common in the latter case.
>
> This is interesting. I’m not enough of a compiler buff to say that this
> assumption is reasonable - Go is 14 years old, so it seems to work - but
> obviously one can write code where it is false, the “zero-sized pointers”
> being the most prominent example. Anyone has a pointer to the alias
> analysis design of the Go compiler?
>
> Am 20.06.2024 um 15:57 schrieb Axel Wagner  >:
>
> I don't believe the issue in this case really is to do with zero-sized
> variables. Here is an example with the same output, not involving any
> zero-sized variables:
> https://go.dev/play/p/JzbwbVqBR0k
> The issue is that you treat a `*struct{}` as an `*int` - that is, you
> explicitly obtain a pointer to invalid memory - and then expect that to
> have any reasonable behaviour.
>
>
>

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


Re: [go-nuts] Comparison of pointers to distinct zero-sized variables

2024-06-20 Thread &#x27;Axel Wagner&#x27; via golang-nuts
FYI, filed https://github.com/golang/go/issues/68086 for the spec-hole that
conversions between unsafe.Pointer and other pointer types are not
implementation defined.

On Thu, 20 Jun 2024 at 14:12, Axel Wagner 
wrote:

>
>
> On Thu, 20 Jun 2024 at 13:48, Oliver Eikemeier <
> eikeme...@fillmore-labs.com> wrote:
>
>>
>> Am 20.06.2024 um 13:24 schrieb Axel Wagner > >:
>>
>> We can see that 1. `unsafe.Pointer` is definitionally a pointer type, 2.
>> in your example, the two `unsafe.Pointers` do not point to the same
>> variable and do not have the value `nil` and 3. are not pointing at
>> distinct zero-sized variables. So their comparison should be `false`, which
>> is what your example observes.
>>
>>
>> Does it (Go Playground )?
>>
>> func f5() {
>> var (
>> a  struct{}
>> b  int
>> aa = (*int)(unsafe.Pointer(&a))
>> ba = (*int)(unsafe.Pointer(&b))
>> eq = aa == ba
>> )
>>
>> println("&a:", aa, reflect.TypeOf(aa).String())
>> println("&b:", ba, reflect.TypeOf(ba).String())
>> println("&a == &b:", eq)
>> cmpIntPtr(aa, ba)
>> }
>>
>> func cmpIntPtr(p1 *int, p2 *int) {
>> fmt.Println("p1 == p2:", p1 == p2)
>> }
>>
>> &a: 0xc466f8 *int
>> &b: 0xc466f8 *int
>> &a == &b: falsep1 == p2: true
>>
>>
> Interestingly, the spec does not forbid that (or specifies it as
> implementation-defined), though the (implementation-defined)
> unsafe.Pointer rules  do, as using
> `unsafe.Pointer` to convert between pointers of different base types is
> only allowed if the target variable is at least as large as the source
> variable and both share an equivalent memory layout.
>
> I think the fact that the spec does not put any limits on the allowed
> behaviour of converting between `unsafe.Pointer` and other pointer types is
> a clear oversight that should be corrected (perhaps it should really be
> "The effect of converting between Pointer and uintptr is
> implementation-defined" should really say "and other types"). But I don't
> think it's a surprising fact that you can make a program behave in almost
> arbitrary ways by doing that.
>
>
>> I’m advocating for at least a FAQ article,
>>
>>
>> I tend to agree, though I'm not sure how to phrase that, beyond saying
>> "do not make any assumptions about the identity pointers to zero-sized
>> variables or with zero-sized base types or that where derived from one of
>> those" and I'm not sure how helpful that is.
>>
>>
>> It seems like a frequently asked question to me ;)
>>
>
> It is. But note that every time it is asked, it leads to considerable
> discussion, which seems to strongly suggest that it is hard to give a
> simple, unambiguous answer that people find satisfying.
>
> I think you should acknowledge that the spec *is* already trying to be
> very clear about this. The fact that you can poke holes in it is because
> writing a spec unambiguously is hard. But the two quoted phrases are there
> in the best attempt to clearly state that you can not rely on any
> assumptions about pointers to zero-sized variables - within the somewhat
> abstract framework of the spec. Feel free to propose a better one, I'm not
> actually arguing against that.
>
> And I'm also not arguing against an FAQ entry. Ideally, someone would
> suggest a phrasing that is sufficiently broad and unambiguous and clear to
> cover any version of this question people might ask, while also not
> contradicting the spec.
>
>
>> but also think the specification should be adapted, for clarity but also
>>> for the fact that only one pointer pointing to a zero-sized variable can
>>> compare differently to anything over time, even things having the same
>>> address value.
>>>
>>
>> Note that "address value" is not something that exists within the spec.
>> As for clarifying the spec here, maybe. I do think the behavior is covered,
>> as I outlined above. And as above, I'm not sure how to clarify it further,
>> while still leaving up the space we want to left open.
>>
>>
>> I vote for making this openness explicit, meaning that even the optimizer
>> is free to make assumptions that do not hold during runtime. So if you have
>> a pointer derived from something pointing to a zero-size type it can
>> compare with different results over time, even false when having the same
>> value. I do not believe that is what’s currently in the spec.
>>
>
>> Cheers
>> Oliver
>>
>>

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


Re: [go-nuts] Comparison of pointers to distinct zero-sized variables

2024-06-20 Thread &#x27;Axel Wagner&#x27; via golang-nuts
On Thu, 20 Jun 2024 at 13:48, Oliver Eikemeier 
wrote:

>
> Am 20.06.2024 um 13:24 schrieb Axel Wagner  >:
>
> We can see that 1. `unsafe.Pointer` is definitionally a pointer type, 2.
> in your example, the two `unsafe.Pointers` do not point to the same
> variable and do not have the value `nil` and 3. are not pointing at
> distinct zero-sized variables. So their comparison should be `false`, which
> is what your example observes.
>
>
> Does it (Go Playground )?
>
> func f5() {
> var (
> a  struct{}
> b  int
> aa = (*int)(unsafe.Pointer(&a))
> ba = (*int)(unsafe.Pointer(&b))
> eq = aa == ba
> )
>
> println("&a:", aa, reflect.TypeOf(aa).String())
> println("&b:", ba, reflect.TypeOf(ba).String())
> println("&a == &b:", eq)
> cmpIntPtr(aa, ba)
> }
>
> func cmpIntPtr(p1 *int, p2 *int) {
> fmt.Println("p1 == p2:", p1 == p2)
> }
>
> &a: 0xc466f8 *int
> &b: 0xc466f8 *int
> &a == &b: falsep1 == p2: true
>
>
Interestingly, the spec does not forbid that (or specifies it as
implementation-defined), though the (implementation-defined) unsafe.Pointer
rules  do, as using `unsafe.Pointer` to
convert between pointers of different base types is only allowed if the
target variable is at least as large as the source variable and both share
an equivalent memory layout.

I think the fact that the spec does not put any limits on the allowed
behaviour of converting between `unsafe.Pointer` and other pointer types is
a clear oversight that should be corrected (perhaps it should really be
"The effect of converting between Pointer and uintptr is
implementation-defined" should really say "and other types"). But I don't
think it's a surprising fact that you can make a program behave in almost
arbitrary ways by doing that.


> I’m advocating for at least a FAQ article,
>
>
> I tend to agree, though I'm not sure how to phrase that, beyond saying "do
> not make any assumptions about the identity pointers to zero-sized
> variables or with zero-sized base types or that where derived from one of
> those" and I'm not sure how helpful that is.
>
>
> It seems like a frequently asked question to me ;)
>

It is. But note that every time it is asked, it leads to considerable
discussion, which seems to strongly suggest that it is hard to give a
simple, unambiguous answer that people find satisfying.

I think you should acknowledge that the spec *is* already trying to be very
clear about this. The fact that you can poke holes in it is because writing
a spec unambiguously is hard. But the two quoted phrases are there in the
best attempt to clearly state that you can not rely on any assumptions
about pointers to zero-sized variables - within the somewhat abstract
framework of the spec. Feel free to propose a better one, I'm not actually
arguing against that.

And I'm also not arguing against an FAQ entry. Ideally, someone would
suggest a phrasing that is sufficiently broad and unambiguous and clear to
cover any version of this question people might ask, while also not
contradicting the spec.


> but also think the specification should be adapted, for clarity but also
>> for the fact that only one pointer pointing to a zero-sized variable can
>> compare differently to anything over time, even things having the same
>> address value.
>>
>
> Note that "address value" is not something that exists within the spec. As
> for clarifying the spec here, maybe. I do think the behavior is covered, as
> I outlined above. And as above, I'm not sure how to clarify it further,
> while still leaving up the space we want to left open.
>
>
> I vote for making this openness explicit, meaning that even the optimizer
> is free to make assumptions that do not hold during runtime. So if you have
> a pointer derived from something pointing to a zero-size type it can
> compare with different results over time, even false when having the same
> value. I do not believe that is what’s currently in the spec.
>

> Cheers
> Oliver
>
>

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


Re: [go-nuts] Comparison of pointers to distinct zero-sized variables

2024-06-20 Thread &#x27;Axel Wagner&#x27; via golang-nuts
advocating for at least a FAQ article,
>>
>
> I tend to agree, though I'm not sure how to phrase that, beyond saying "do
> not make any assumptions about the identity pointers to zero-sized
> variables or with zero-sized base types or that where derived from one of
> those" and I'm not sure how helpful that is.
>
>
>> but also think the specification should be adapted, for clarity but also
>> for the fact that only one pointer pointing to a zero-sized variable can
>> compare differently to anything over time, even things having the same
>> address value.
>>
>
> Note that "address value" is not something that exists within the spec. As
> for clarifying the spec here, maybe. I do think the behavior is covered, as
> I outlined above. And as above, I'm not sure how to clarify it further,
> while still leaving up the space we want to left open.
>
>
>>
>> I do not believe the specification is clear on this. Otherwise I don’t
>> think this is urgent. But it seems to pop up repeatedly.
>>
>> Cheers
>> Oliver
>>
>> Am 19.06.2024 um 23:16 schrieb 'Axel Wagner' via golang-nuts <
>> golang-nuts@googlegroups.com>:
>>
>> The spec says both. It says
>>
>>> Two distinct zero-size variables may have the same address in memory.
>>
>> And it says
>>
>>> Pointers to distinct zero-size variables may or may not be equal.
>>
>>
>> The former means what you say. The latter means what Ian says.
>>
>> Then I have two pointers. Where in the spec is “the result of comparison
>>> of pointers may change over time”?
>>>
>>
>>> For example (Go Playground <https://go.dev/play/p/acknRHBvi0P>):
>>>
>>> func f3() {
>>> var (
>>> a  struct{}
>>> b  int
>>> aa = unsafe.Pointer(&a)
>>> ba = unsafe.Pointer(&b)
>>> eq = aa == ba
>>> )
>>>
>>> println("&a:", aa)
>>> println("&b:", ba)
>>> println("&a == &b:", eq)
>>> }
>>>
>>> gives
>>>
>>> &a: 0xc46738
>>> &b: 0xc46738
>>> &a == &b: false
>>>
>>> and &b is not even a pointer to a zero-sized variable.
>>>
>>
>>

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


Re: [go-nuts] Comparison of pointers to distinct zero-sized variables

2024-06-20 Thread &#x27;Axel Wagner&#x27; via golang-nuts
he spec. As
for clarifying the spec here, maybe. I do think the behavior is covered, as
I outlined above. And as above, I'm not sure how to clarify it further,
while still leaving up the space we want to left open.


>
> I do not believe the specification is clear on this. Otherwise I don’t
> think this is urgent. But it seems to pop up repeatedly.
>
> Cheers
> Oliver
>
> Am 19.06.2024 um 23:16 schrieb 'Axel Wagner' via golang-nuts <
> golang-nuts@googlegroups.com>:
>
> The spec says both. It says
>
>> Two distinct zero-size variables may have the same address in memory.
>
> And it says
>
>> Pointers to distinct zero-size variables may or may not be equal.
>
>
> The former means what you say. The latter means what Ian says.
>
> Then I have two pointers. Where in the spec is “the result of comparison
>> of pointers may change over time”?
>>
>
>> For example (Go Playground <https://go.dev/play/p/acknRHBvi0P>):
>>
>> func f3() {
>> var (
>> a  struct{}
>> b  int
>> aa = unsafe.Pointer(&a)
>> ba = unsafe.Pointer(&b)
>> eq = aa == ba
>> )
>>
>> println("&a:", aa)
>> println("&b:", ba)
>> println("&a == &b:", eq)
>> }
>>
>> gives
>>
>> &a: 0xc46738
>> &b: 0xc46738
>> &a == &b: false
>>
>> and &b is not even a pointer to a zero-sized variable.
>>
>
>

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


Re: [go-nuts] Comparison of pointers to distinct zero-sized variables

2024-06-19 Thread &#x27;Axel Wagner&#x27; via golang-nuts
On Wed, 19 Jun 2024 at 22:43, Oliver Eikemeier  wrote:

> The specs says, as you say above, "Pointers to distinct zero-size
> variables may or may not be equal.” That means that you can't predict
> the result of any given comparison of addresses of zero-sized
> variables.
>
>
> I'm not sure I read it that way. I would interpret it as *“taking pointer
> to distinct zero-size variables may or may not result in equal pointers”*.
>
> But not being able to have a *repeatable* result of a pointer comparison
> seems strange to me. The specification says “you'll get *some* pointers”.
> Fine.
>

The spec says both. It says

> Two distinct zero-size variables may have the same address in memory.

And it says

> Pointers to distinct zero-size variables may or may not be equal.


The former means what you say. The latter means what Ian says.

Then I have two pointers. Where in the spec is “the result of comparison of
> pointers may change over time”?
>

> For example (Go Playground ):
>
> func f3() {
> var (
> a  struct{}
> b  int
> aa = unsafe.Pointer(&a)
> ba = unsafe.Pointer(&b)
> eq = aa == ba
> )
>
> println("&a:", aa)
> println("&b:", ba)
> println("&a == &b:", eq)
> }
>
> gives
>
> &a: 0xc46738
> &b: 0xc46738
> &a == &b: false
>
> and &b is not even a pointer to a zero-sized variable.
>
> Could be true, could be false, could change each time you
> do the comparison. So this behavior is permitted by the spec.
>
>
> I'm not sure about the “undefined behavior *over time*”. I get that the
> compiler lays out the memory however it sees fit, but then I should have
> unchanging values in my variables.
>
>
> > The interesting part here is that I can create two pointers (which may
> or may not be equal per specification), but depending on how I compare them
> I get different results.
>
> Yes, as the spec permits.
>
>
>  I assume this has little relevance in practice, but it is surprising.
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/64e58302-59a6-4cbf-859e-aa6b8a2b6068n%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/CAEkBMfE6bzYQJ7s_GHEN7%3Dp3s2p0pSWNMgcw8t4tTiSy04ucFg%40mail.gmail.com.


Re: [go-nuts] variable set in a loop but unused not failing compilation

2024-05-06 Thread &#x27;Axel Wagner&#x27; via golang-nuts
Hi,

I'll note that this has nothing, really, to do with the loop, but with the
fact that you are assigning a struct field.
For a simpler example, compare this: https://go.dev/play/p/MmR-AhOUQH3 with
this: https://go.dev/play/p/Y1uoI8thYuV
If you only write to the entire variable, the compiler complains about that
variable not being used. But if you set a field, the failure goes away.

This compilation error is based on this sentence from the spec
:
> Implementation restriction: A compiler may make it illegal to declare a
variable inside a function body
 if the variable is never
used.
Note that it says "may" make it illegal. It's also not really defined what
it means for a variable to be "never used".

TBH I don't really like these implementation-defined compilation failures.
But it would be difficult to make them more strict. Perhaps this case could
be a vet warning.

On Mon, May 6, 2024 at 4:20 PM Tiago de Bem Natel de Moura <
t.nateldemo...@gmail.com> wrote:

> Hello,
>
> We had the bug below in production:
> https://go.dev/play/p/-jewy7e7UcZ
>
> Look at the `opt` variable inside `listGithubPullReviews`, it's set
> multiple times (inside the loop) but never used... it was supposed to be
> passed as the last argument of `ListReviews()`.
>
> Why Go compiler is not giving an error for this case? AFAICS all of those
> `opt.Page = resp.NextPage` inside the loop cannot make any side effects,
> then it looks safe to assume the variable is only set and never used?
>
> So, simplifying the problem, this is the non-failing case:
> https://go.dev/play/p/FLAIlVx_sSG
>
> But if you change from a struct to a plain int, then the compiler gives: 
> `./prog.go:6:2:
> a declared and not used`
>
> Luckily, we were using a `ctx` with timeout otherwise it would be an
> infinite loop. The thing was tested but only for cases where all results
> came in a single page, then the loop aborted in the first iteration. I
> think this could be detected by the compiler, no?
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/9a2b5179-f083-4365-b0c6-e876f3fe6950n%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/CAEkBMfECnnFQkdwSn3gqzRxHL7MnkfoUvABFg8xr0B-9jTkSjQ%40mail.gmail.com.


Re: [go-nuts] problem with generic type switch

2024-04-08 Thread &#x27;Axel Wagner&#x27; via golang-nuts
Yes, the *underlying type* of Class is `byte`, but the type-switch checks
if the dynamic type is *exactly* `byte`.
The only way, currently, to implement the kind of check you want is to use
reflect:

switch rv := reflect.ValueOf(v); rv.Kind() {
case reflect.Uint8: // byte
v := uint8(rv.Uint())
// ...
}

Though you might be interested in #45380
, which would be able to solve
this without reflect.

On Mon, Apr 8, 2024 at 11:04 AM Xiangrong Fang  wrote:

> I wrote a TLV handling package: go.xrfang.cn/tlv
> , and encountered problem with type
> checking.  Problematic code below:
>
> 1.  The "Set" function in side tlv package:
>
> package tlv
>
> type (
> ValueType interface {
> string | []byte | ~float32 | ~float64 |
> ~int8 | ~int16 | ~int32 | ~int64 |
> ~uint8 | ~uint16 | ~uint32 | ~uint64
> }
> Prop map[byte][]byte
> )
>
> func Set[T ValueType](p Prop, tag byte, val T) Prop {
> ... ...
> switch v := any(val).(type) {
> case string:
> ... ...
> default:
> fmt.Printf("tlv.Set: '%T' not supported!\n", val)
> }
> ...
> }
>
> 2. event.go, which uses tlv:
>
> package event
>
> import (
> "go.xrfang.cn/tlv"
> )
>
> type (
> Class byte
> Event struct {
> tlv.Prop
> }
> )
>
> const (
> TagClass  = 3
> )
>
> func (e *Event) WithClass(cls Class) *Event {
> (*e).Prop = tlv.Set((*e).Prop, TagClass, cls)
> return e
> }
>
> The problem is, while the Class type is based on "byte", it should be
> accepted by tlv.Set(), which is the case (there is no compiler error).  But
> when the code is running, it printed error message: tlv.Set: 'event.Class'
> not supported!
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/b4786988-b9da-44c3-9070-ba718f3be5ban%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/CAEkBMfHg007as7h5NNf-EPCTy8ZSv1sX%3D0pWO2dFjszswnvEwQ%40mail.gmail.com.


Re: [go-nuts] [generics] type constraint for structs

2024-04-03 Thread &#x27;Axel Wagner&#x27; via golang-nuts
How does `interface{ AsElement() *Element }` not do exactly what you want?

On Thu, Apr 4, 2024 at 4:14 AM atd...@gmail.com  wrote:

> Might have come across this today as I was trying to simplify some code.
>
> Basically, I have a base type called *Element that has a method
> AsElement() *Element that returns itself.
>
> And this base element is used as a base for many others, for isntance:
>
> type Div struct{ *Element}
> type Span struct{*Element}
> type Anchor {*Element}
> ...
>
> Somehow, I need a function Ref that can take a pointer to any of these
> elements and modify them (basically modifying the inner *Element pointer).
>
> Currently, I don't think I can abstract over these types which share in
> common the *Element field and the AsEleemnt method promoted from it.
> I don't want to have to implement a specific method to do that mutation
> operation for each and every one of these types either.
>
> Basically, trying to make generic this function:
>
> func Ref(vref **Element) func(*Element) *Element{
> return func(e *Element)*Element{
> *vref = e
> return e
> }
> }
>
>
> Or does anyone see something that I missed?
>
> On Thursday, April 4, 2024 at 2:52:16 AM UTC+2 Adam Manwaring wrote:
>
>> While this would make some things much easier for me, it seems this would
>> be a pretty fundamental change. Constraints are essentially interfaces and
>> interfaces in Go are defined by behaviors. Structs, on the other hand, are
>> defined by properties. There is no behavior that all structs have that
>> every other type couldn't also have. Thus having a struct constraint would
>> be a one-off exception which for the most part seems anathema to Go. In a
>> similar vein, there are many times I'd like an interface to require certain
>> exported properties in addition to behaviors, but this isn't going to
>> happen.
>>
>> On Wednesday, March 27, 2024 at 6:28:19 PM UTC-6 Makis Maropoulos wrote:
>>
>>> Same here @Abraham,
>>>
>>> ResponseType interface {
>>> ~struct{}
>>> }
>>>
>>> Obviously this doesn't work, I would love to see it working though.
>>> On Wednesday 14 September 2022 at 17:48:19 UTC+3 Abraham wrote:
>>>
 I am glad I found this thread because I was just now breaking my head
 figuring out why my  was not working

 On Wednesday, May 18, 2022 at 10:41:29 PM UTC-4 Ian Lance Taylor wrote:

> On Wed, May 18, 2022 at 7:36 PM Jeremy Kassis 
> wrote:
> >
> > Where exactly did this land? Seems like an important conversation...
>
> To date there is no way to write a constraint that requires that a
> type argument be a struct type.
>
>
> > ```
> > // RPCHandler passes RPCReq and RPCRes as fn args
> > func RPCHandler[T RPCReq, S RPCRes](fn func(T, S)) http.HandlerFunc
> {
> > return func(w http.ResponseWriter, r *http.Request) {
> > req := T{}
> > if err := reqBodyReadAll(w, r, &req); err != nil {
> > resWriteErr(w, err)
> > return
> > }
> > res := S{}
> > fn(req, res)
> > resWriteAll(w, r, res)
> > }
> > }
> > ```
>
> I would write simply "var req T" and "var res S".
>
> 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/f2150cf5-75d9-4cb3-9a29-d5a8c8e655a5n%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/CAEkBMfHmvPxbTqh0BhV9Ubd8ZM3XhaABHD9TXmWOP-wYKwO4rw%40mail.gmail.com.


Re: [go-nuts] Module vs Package

2024-03-31 Thread &#x27;Axel Wagner&#x27; via golang-nuts
A package is the unit of compilation - the entire package is compiled in a
step and it's also where unexported names are scoped to.
A module is the unit of versioning - it's a bunch of packages versioned and
distributed together.

On Mon, Apr 1, 2024 at 8:43 AM Nikhilesh Susarla 
wrote:

> Packages are inside modules.
> Package is nothing but collection of go files under a folder of that
> package name
>
> But without modules also we can import packages.
>
> Can someone point out the exact and main difference between package vs
> modules in golang.
>
> 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/e2f07639-d2a2-4a72-bec5-8cbcb2927200n%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/CAEkBMfG%3DFbXAr_-SC17F%3DZa-n8cYG8yEmNQDwWOo5hjmz4ua9A%40mail.gmail.com.


Re: [go-nuts] Nil pointer panic that should be impossible

2024-03-25 Thread &#x27;Axel Wagner&#x27; via golang-nuts
Or to be perhaps more precise: This view can be useful to understand the
observed behaviour: A string is two words which are updated non-atomically,
hence one read might observe the write of the length separately from the
write of the data.

But to determine the *correctness* of the program, any concurrent
read/write of a variable must be synchronised, regardless of type or size.

On Mon 25. Mar 2024 at 15:53, Axel Wagner 
wrote:

> On Mon, Mar 25, 2024 at 3:47 PM 'Brian Candler' via golang-nuts <
> golang-nuts@googlegroups.com> wrote:
>
>> And as Axel's own reproducer shows, even having two threads reading and
>> writing the same *variable* which points to a string can result in
>> indeterminate behaviour, since a string is really a struct containing two
>> parts (a pointer and a len).
>
>
> I want to caution against this reasoning. The size of a variable is
> irrelevant. A data race on an `int` is still a data race.
> It's the concurrent modification of a variable (in the sense of the spec
> <https://go.dev/ref/spec#Variables>, i.e. every field or array element is
> its own variable) that is the problem - not its type.
>
>
>>   You're not mutating the string itself, but you are updating a variable
>> at the same time as it's being read.
>>
>> In this regard, Go is no more thread-safe than C or C++, unless you make
>> use of the concurrency features it provides (i.e. channels) instead of
>> concurrently reading and writing the same variables.
>>
>> On Monday 25 March 2024 at 13:18:15 UTC Axel Wagner wrote:
>>
>>> TBQH the word "mutable" doesn't make a lot of sense in Go (even though
>>> the spec also calls strings "immutable").
>>> Arguably, *all* values in Go are immutable. It's just that all
>>> *pointers* in Go allow to modify the referenced variables - and some types
>>> allow you to get a pointer to a shared variable, which strings don't.
>>>
>>> That is, a `[]byte` is immutable - you have to write `x = append(x, v)`
>>> specifically because `append` creates a new slice value and overwrites the
>>> variable `x` with it.
>>> However, a `[]byte` refers to an underlying array and `&b[0]` allows you
>>> to obtain a pointer to that underlying array. So a `[]byte` represents a
>>> reference and that reference allows to mutate the referenced storage
>>> location. The same goes for a `*T`, a `map[K]V`, or a `type S struct{ X
>>> int; P *int }` - `S` itself is immutable, but `S.X` is a reference to some
>>> potentially shared variable.
>>>
>>> A `string` meanwhile, does not allow you to obtain a pointer to the
>>> underlying storage and that's what makes it "immutable". And that does
>>> indeed mean that if you pass a `string` value around, that can't lead to
>>> data races, while passing a `[]byte` around *might*.
>>>
>>> But for this case, it doesn't really matter whether or not the field is
>>> a `string` or a `[]byte` or an `int`: Because the "mutable" type is the
>>> `*URL`. Which represents a reference to some underlying `URL` variable,
>>> that you can then mutate. The race happens because you have a method on a
>>> pointer that mutates a field - *regardless* of the type of that field.
>>>
>>> I don't know if that helps, it's a bit subtle.
>>>
>>> On Mon, Mar 25, 2024 at 1:35 PM 'Lirong Wang' via golang-nuts <
>>> golan...@googlegroups.com> wrote:
>>>
>>>> Wow, i am from other language and i thought `string` is immutable or
>>>> something like that, so thread-safe for this operation. learned
>>>> something new!!! Thanks
>>>> On Thursday, March 21, 2024 at 11:42:24 PM UTC+8 Ethan Reesor wrote:
>>>>
>>>>> I hadn't used the race detector before. I do see a race warning for
>>>>> (*URL).String() among an embarrassing number of other results. I'm going 
>>>>> to
>>>>> update (*URL).String() to use atomic.Pointer to remove the race.
>>>>>
>>>>> Thanks,
>>>>> Ethan
>>>>>
>>>>> On Thu, Mar 21, 2024 at 8:59 AM 'Axel Wagner' via golang-nuts <
>>>>> golan...@googlegroups.com> wrote:
>>>>>
>>>>>> On Thu, Mar 21, 2024 at 2:48 PM 王李荣  wrote:
>>>>>>
>>>>>>> hi Axel,
>>>>>>>
>>>>>>> is not modifying `u.memoize.str` thread-safe?  

Re: [go-nuts] Nil pointer panic that should be impossible

2024-03-25 Thread &#x27;Axel Wagner&#x27; via golang-nuts
On Mon, Mar 25, 2024 at 3:47 PM 'Brian Candler' via golang-nuts <
golang-nuts@googlegroups.com> wrote:

> And as Axel's own reproducer shows, even having two threads reading and
> writing the same *variable* which points to a string can result in
> indeterminate behaviour, since a string is really a struct containing two
> parts (a pointer and a len).


I want to caution against this reasoning. The size of a variable is
irrelevant. A data race on an `int` is still a data race.
It's the concurrent modification of a variable (in the sense of the spec
<https://go.dev/ref/spec#Variables>, i.e. every field or array element is
its own variable) that is the problem - not its type.


>   You're not mutating the string itself, but you are updating a variable
> at the same time as it's being read.
>
> In this regard, Go is no more thread-safe than C or C++, unless you make
> use of the concurrency features it provides (i.e. channels) instead of
> concurrently reading and writing the same variables.
>
> On Monday 25 March 2024 at 13:18:15 UTC Axel Wagner wrote:
>
>> TBQH the word "mutable" doesn't make a lot of sense in Go (even though
>> the spec also calls strings "immutable").
>> Arguably, *all* values in Go are immutable. It's just that all *pointers*
>> in Go allow to modify the referenced variables - and some types allow you
>> to get a pointer to a shared variable, which strings don't.
>>
>> That is, a `[]byte` is immutable - you have to write `x = append(x, v)`
>> specifically because `append` creates a new slice value and overwrites the
>> variable `x` with it.
>> However, a `[]byte` refers to an underlying array and `&b[0]` allows you
>> to obtain a pointer to that underlying array. So a `[]byte` represents a
>> reference and that reference allows to mutate the referenced storage
>> location. The same goes for a `*T`, a `map[K]V`, or a `type S struct{ X
>> int; P *int }` - `S` itself is immutable, but `S.X` is a reference to some
>> potentially shared variable.
>>
>> A `string` meanwhile, does not allow you to obtain a pointer to the
>> underlying storage and that's what makes it "immutable". And that does
>> indeed mean that if you pass a `string` value around, that can't lead to
>> data races, while passing a `[]byte` around *might*.
>>
>> But for this case, it doesn't really matter whether or not the field is a
>> `string` or a `[]byte` or an `int`: Because the "mutable" type is the
>> `*URL`. Which represents a reference to some underlying `URL` variable,
>> that you can then mutate. The race happens because you have a method on a
>> pointer that mutates a field - *regardless* of the type of that field.
>>
>> I don't know if that helps, it's a bit subtle.
>>
>> On Mon, Mar 25, 2024 at 1:35 PM 'Lirong Wang' via golang-nuts <
>> golan...@googlegroups.com> wrote:
>>
>>> Wow, i am from other language and i thought `string` is immutable or
>>> something like that, so thread-safe for this operation. learned
>>> something new!!! Thanks
>>> On Thursday, March 21, 2024 at 11:42:24 PM UTC+8 Ethan Reesor wrote:
>>>
>>>> I hadn't used the race detector before. I do see a race warning for
>>>> (*URL).String() among an embarrassing number of other results. I'm going to
>>>> update (*URL).String() to use atomic.Pointer to remove the race.
>>>>
>>>> Thanks,
>>>> Ethan
>>>>
>>>> On Thu, Mar 21, 2024 at 8:59 AM 'Axel Wagner' via golang-nuts <
>>>> golan...@googlegroups.com> wrote:
>>>>
>>>>> On Thu, Mar 21, 2024 at 2:48 PM 王李荣  wrote:
>>>>>
>>>>>> hi Axel,
>>>>>>
>>>>>> is not modifying `u.memoize.str` thread-safe?  the len and the data
>>>>>> point should become visible at same time?
>>>>>>
>>>>>
>>>>> What makes you think that? To be clear, there are no benign data
>>>>> races. Even a data-race on a variable smaller than a word is still a
>>>>> data-race, unless you do it holding a lock or using atomic instructions.
>>>>> But strings are *larger* than single words.
>>>>>
>>>>> To demonstrate that the effect I am talking about is real, look at
>>>>> this code: https://go.dev/play/p/LzRq9-OH-Xb
>>>>>
>>>>>
>>>>>>
>>>>>> 在2024年3月16日星期六 UTC+8 06:29:

Re: [go-nuts] Nil pointer panic that should be impossible

2024-03-25 Thread &#x27;Axel Wagner&#x27; via golang-nuts
TBQH the word "mutable" doesn't make a lot of sense in Go (even though the
spec also calls strings "immutable").
Arguably, *all* values in Go are immutable. It's just that all *pointers*
in Go allow to modify the referenced variables - and some types allow you
to get a pointer to a shared variable, which strings don't.

That is, a `[]byte` is immutable - you have to write `x = append(x, v)`
specifically because `append` creates a new slice value and overwrites the
variable `x` with it.
However, a `[]byte` refers to an underlying array and `&b[0]` allows you to
obtain a pointer to that underlying array. So a `[]byte` represents a
reference and that reference allows to mutate the referenced storage
location. The same goes for a `*T`, a `map[K]V`, or a `type S struct{ X
int; P *int }` - `S` itself is immutable, but `S.X` is a reference to some
potentially shared variable.

A `string` meanwhile, does not allow you to obtain a pointer to the
underlying storage and that's what makes it "immutable". And that does
indeed mean that if you pass a `string` value around, that can't lead to
data races, while passing a `[]byte` around *might*.

But for this case, it doesn't really matter whether or not the field is a
`string` or a `[]byte` or an `int`: Because the "mutable" type is the
`*URL`. Which represents a reference to some underlying `URL` variable,
that you can then mutate. The race happens because you have a method on a
pointer that mutates a field - *regardless* of the type of that field.

I don't know if that helps, it's a bit subtle.

On Mon, Mar 25, 2024 at 1:35 PM 'Lirong Wang' via golang-nuts <
golang-nuts@googlegroups.com> wrote:

> Wow, i am from other language and i thought `string` is immutable or
> something like that, so thread-safe for this operation. learned something
> new!!! Thanks
> On Thursday, March 21, 2024 at 11:42:24 PM UTC+8 Ethan Reesor wrote:
>
>> I hadn't used the race detector before. I do see a race warning for
>> (*URL).String() among an embarrassing number of other results. I'm going to
>> update (*URL).String() to use atomic.Pointer to remove the race.
>>
>> Thanks,
>> Ethan
>>
>> On Thu, Mar 21, 2024 at 8:59 AM 'Axel Wagner' via golang-nuts <
>> golan...@googlegroups.com> wrote:
>>
>>> On Thu, Mar 21, 2024 at 2:48 PM 王李荣  wrote:
>>>
>>>> hi Axel,
>>>>
>>>> is not modifying `u.memoize.str` thread-safe?  the len and the data
>>>> point should become visible at same time?
>>>>
>>>
>>> What makes you think that? To be clear, there are no benign data races.
>>> Even a data-race on a variable smaller than a word is still a data-race,
>>> unless you do it holding a lock or using atomic instructions. But strings
>>> are *larger* than single words.
>>>
>>> To demonstrate that the effect I am talking about is real, look at this
>>> code: https://go.dev/play/p/LzRq9-OH-Xb
>>>
>>>
>>>>
>>>> 在2024年3月16日星期六 UTC+8 06:29:06 写道:
>>>>
>>>>> Have you tried running the code with the race detector enabled? I
>>>>> suspect that you are concurrently modifying `u.memoize.str` by calling
>>>>> `u.String()` from multiple goroutines. And the non-zero length of the
>>>>> string header written by one goroutine becomes visible to the other one,
>>>>> before the modification to the data pointer.
>>>>>
>>>>> On Fri, Mar 15, 2024 at 11:15 PM Ethan Reesor 
>>>>> wrote:
>>>>>
>>>>>> From this CI job
>>>>>> <https://gitlab.com/accumulatenetwork/accumulate/-/jobs/6398114923>:
>>>>>>
>>>>>> panic: runtime error: invalid memory address or nil pointer
>>>>>> dereference
>>>>>> [signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x51d8b7]
>>>>>> goroutine 1589381 [running]:
>>>>>> strings.EqualFold({0xc000beec20?, 0x0?}, {0x0?, 0xacace7?})
>>>>>>  /usr/local/go/src/strings/strings.go: +0x37
>>>>>>
>>>>>> gitlab.com/accumulatenetwork/accumulate/pkg/url.(*URL).Equal(0xc000a74e40?,
>>>>>> 0xc00094c540)
>>>>>>  /builds/accumulatenetwork/accumulate/pkg/url/url.go:472 +0x10c
>>>>>>
>>>>>> This is in a docker container based on the go:1.22 image, so the
>>>>>> panic appears to be happening here:
>>>>>>
>>>>>> func EqualFold(s, t string) bool {
>&g

Re: [go-nuts] Nil pointer panic that should be impossible

2024-03-21 Thread &#x27;Axel Wagner&#x27; via golang-nuts
On Thu, Mar 21, 2024 at 2:48 PM 王李荣  wrote:

> hi Axel,
>
> is not modifying `u.memoize.str` thread-safe?  the len and the data point
> should become visible at same time?
>

What makes you think that? To be clear, there are no benign data races.
Even a data-race on a variable smaller than a word is still a data-race,
unless you do it holding a lock or using atomic instructions. But strings
are *larger* than single words.

To demonstrate that the effect I am talking about is real, look at this
code: https://go.dev/play/p/LzRq9-OH-Xb


>
> 在2024年3月16日星期六 UTC+8 06:29:06 写道:
>
>> Have you tried running the code with the race detector enabled? I suspect
>> that you are concurrently modifying `u.memoize.str` by calling `u.String()`
>> from multiple goroutines. And the non-zero length of the string header
>> written by one goroutine becomes visible to the other one, before the
>> modification to the data pointer.
>>
>> On Fri, Mar 15, 2024 at 11:15 PM Ethan Reesor 
>> wrote:
>>
>>> From this CI job
>>> :
>>>
>>> panic: runtime error: invalid memory address or nil pointer dereference
>>> [signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x51d8b7]
>>> goroutine 1589381 [running]:
>>> strings.EqualFold({0xc000beec20?, 0x0?}, {0x0?, 0xacace7?})
>>>  /usr/local/go/src/strings/strings.go: +0x37
>>> gitlab.com/accumulatenetwork/accumulate/pkg/url.(*URL).Equal(0xc000a74e40?,
>>> 0xc00094c540)
>>>  /builds/accumulatenetwork/accumulate/pkg/url/url.go:472 +0x10c
>>>
>>> This is in a docker container based on the go:1.22 image, so the panic
>>> appears to be happening here:
>>>
>>> func EqualFold(s, t string) bool {
>>> // ASCII fast path
>>> i := 0
>>> for ; i < len(s) && i < len(t); i++ {
>>> sr := s[i]
>>> tr := t[i] // <-- line 
>>>
>>> (*URL).Equal
>>> 
>>> :
>>>
>>> func (u *URL) Equal(v *URL) bool {
>>> if u == v {
>>> return true
>>> }
>>> if u == nil || v == nil {
>>> return false
>>> }
>>> return strings.EqualFold(u.String(), v.String())
>>> }
>>>
>>> (*URL).String
>>> 
>>> :
>>>
>>> func (u *URL) String() string {
>>> if u.memoize.str != "" {
>>> return u.memoize.str
>>> }
>>>
>>> u.memoize.str = u.format(nil, true)
>>> return u.memoize.str
>>> }
>>>
>>> (*URL).format
>>> 
>>> :
>>>
>>> func (u *URL) format(txid []byte, encode bool) string {
>>> var buf strings.Builder
>>> // ... write to the builder
>>> return buf.String()
>>> }
>>>
>>> How is this possible? Based on `addr=0x0` in the panic I think this is a
>>> nil pointer panic, as opposed to some other kind of segfault. The only way
>>> I can reproduce panic-on-string-index is with 
>>> `(*reflect.StringHeader)(unsafe.Pointer(&s)).Data
>>> = 0`, but I don't see how that can be happening here. I'm saving the string
>>> but I'm not doing anything weird with it. And the string header is a value
>>> type so code that manipulates the returned string shouldn't modify the
>>> original. And I'm definitely not doing any kind of unsafe string
>>> manipulation like that in my code, anywhere. The only reference to unsafe
>>> anywhere in my code is for parameters for calling GetDiskFreeSpaceExW
>>> (Windows kernel32.dll call).
>>>
>>> --
>>> You received this message because you are subscribed 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/d6f6bb75-45e9-4a38-9bbd-d332e7f3e57cn%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/31f77ff2-cf11-4b3e-9b14-874b6cc41da3n%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/CAEkBMfG8v0qO_NP4PipEBL%3Dd_Ase9ntWi4EL1dQE_6ub

Re: [go-nuts] Nillable basic types?

2024-03-20 Thread &#x27;Axel Wagner&#x27; via golang-nuts
FWIW I believe (as Brian sort of points out) this proposal is fully
subsumed under #57644 . Under
that proposal, the proposed type `int | nil` would be spelled `interface{
int }`. The other syntactical constructs are, as far as I can tell,
identical - you'd have to use a type-assertion to use an `interface{ int }`
as an integer (e.g. to do arithmetic), you can use it with type-switches,
and any `int` as well as `nil` would be assignable to it.

I think the one difference would be that `x == 42` would work on
`interface{ int }`, but would (presumably) not work on `int | nil`. I
personally doubt that this difference would justify an extra construction,
but I'm mentioning it for completeness sake.

The "nice to have" of type guards is, I think, an easy idea to mention, but
not an easy idea to add to Go. Note that the other languages mentioned,
that do that, use a function-scoped type-inference (as far as I know) -
that is, they look at an identifiers use over the entire function and then
infer the most general type it would have.
Go has so far tried to avoid doing anything like that, limiting any
inference to the statement (or expression) a value appears in. And this
idea effectively means an identifier would change its type over its
lifetime (from `interface{ int }` - does not allow arithmetic - to `int` -
does allow arithmetic), which would create numerous problems for existing
tooling, as it violates assumptions made by the `go/*` packages.

On Wed, Mar 20, 2024 at 11:26 AM Mike Schinkel  wrote:

> On Wednesday, March 20, 2024 at 5:47:00 AM UTC-4 Brian Candler wrote:
>
> If you change fundamental things like this in the language, then you'll
> suggesting turning Go into something that looks like Rust. In which case,
> you may as well just use Rust.
>
>
> Agreed.  Which is why I was asking if using interfaces as type constraints
> would address the concern.
>
> And as discussed, probably not.
>
> But it is an interesting thought exercise. If an interface-based solution
> could be found, it would address the concern without turning us effectively
> into Rust programmers. ¯\_(ツ)_/¯
>
> -Mike
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/b3cf8686-b0fb-4cdd-938e-deee4a6af273n%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/CAEkBMfHkUwS_XyNAkwM79Hy4F_%2BQxy%3DcaZRvmYkCc-MDi3O9Ww%40mail.gmail.com.


Re: [go-nuts] Nil pointer panic that should be impossible

2024-03-15 Thread &#x27;Axel Wagner&#x27; via golang-nuts
Have you tried running the code with the race detector enabled? I suspect
that you are concurrently modifying `u.memoize.str` by calling `u.String()`
from multiple goroutines. And the non-zero length of the string header
written by one goroutine becomes visible to the other one, before the
modification to the data pointer.

On Fri, Mar 15, 2024 at 11:15 PM Ethan Reesor 
wrote:

> From this CI job
> :
>
> panic: runtime error: invalid memory address or nil pointer dereference
> [signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x51d8b7]
> goroutine 1589381 [running]:
> strings.EqualFold({0xc000beec20?, 0x0?}, {0x0?, 0xacace7?})
>  /usr/local/go/src/strings/strings.go: +0x37
> gitlab.com/accumulatenetwork/accumulate/pkg/url.(*URL).Equal(0xc000a74e40?,
> 0xc00094c540)
>  /builds/accumulatenetwork/accumulate/pkg/url/url.go:472 +0x10c
>
> This is in a docker container based on the go:1.22 image, so the panic
> appears to be happening here:
>
> func EqualFold(s, t string) bool {
> // ASCII fast path
> i := 0
> for ; i < len(s) && i < len(t); i++ {
> sr := s[i]
> tr := t[i] // <-- line 
>
> (*URL).Equal
> 
> :
>
> func (u *URL) Equal(v *URL) bool {
> if u == v {
> return true
> }
> if u == nil || v == nil {
> return false
> }
> return strings.EqualFold(u.String(), v.String())
> }
>
> (*URL).String
> 
> :
>
> func (u *URL) String() string {
> if u.memoize.str != "" {
> return u.memoize.str
> }
>
> u.memoize.str = u.format(nil, true)
> return u.memoize.str
> }
>
> (*URL).format
> 
> :
>
> func (u *URL) format(txid []byte, encode bool) string {
> var buf strings.Builder
> // ... write to the builder
> return buf.String()
> }
>
> How is this possible? Based on `addr=0x0` in the panic I think this is a
> nil pointer panic, as opposed to some other kind of segfault. The only way
> I can reproduce panic-on-string-index is with 
> `(*reflect.StringHeader)(unsafe.Pointer(&s)).Data
> = 0`, but I don't see how that can be happening here. I'm saving the string
> but I'm not doing anything weird with it. And the string header is a value
> type so code that manipulates the returned string shouldn't modify the
> original. And I'm definitely not doing any kind of unsafe string
> manipulation like that in my code, anywhere. The only reference to unsafe
> anywhere in my code is for parameters for calling GetDiskFreeSpaceExW
> (Windows kernel32.dll call).
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/d6f6bb75-45e9-4a38-9bbd-d332e7f3e57cn%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/CAEkBMfGnvZ1NAAp7U93HqjRu5kpRmD6A2DEwiYtPNN9muuWx9Q%40mail.gmail.com.


Re: [go-nuts] x/pkgsite docs wrongly assume $PATH includes $GOPATH/bin

2024-02-29 Thread &#x27;Axel Wagner&#x27; via golang-nuts
On Thu, Feb 29, 2024 at 9:12 AM kredop...@gmail.com 
wrote:

> Apologies - sent the response only to you, so I'll write it again here.
>
> > Doesn't the `go install` command explicitly instruct you to add
> $GOBIN/$GOPATH/bin to your $PATH?
>
> I did check both golang installation docs and the output of `go help
> install` - it's very possible I'm missing something, but I didn't find any
> mention of adding $GOBIN/$GOPATH to the $PATH. Am I just looking in the
> wrong place?
>

No, I misremembered. I mixed it up with make.bash (the script used to build
Go itself).
Perhaps it would be useful if `go install` would check if $GOBIN is in your
$PATH and print a warning, if not? It's already somewhat verbose (it prints
any dependencies it needs to download), so I feel that the usual "it should
be silent on success" logic doesn't apply and there would be little harm.


>
> > To me, that seems enough - it feels a bit arduous, to expect this piece
> of information at any single point on the web where `go install` is
> mentioned.
>
> I wholeheartedly agree - as long as the information mentioned above is
> visible somewhere else, possibly in at least one of the two places I've
> just listed. I was simply surprised that, possibly due to unskillful
> searches of mine, I didn't find official sources suggesting adding
> $GOBIN/$GOPATH to the $PATH, which may be confusing, especially when
> package docs assume this has been done.
>
> Also, thanks for the quick reply!
>
> On Thursday 29 February 2024 at 06:18:07 UTC+1 Axel Wagner wrote:
>
>> Doesn't the `go install` command explicitly instruct you to add
>> $GOBIN/$GOPATH/bin to your $PATH? To me, that seems enough - it feels a bit
>> arduous, to expect this piece of information at any single point on the web
>> where `go install` is mentioned.
>>
>> On Thu, Feb 29, 2024 at 1:39 AM Robert Sawicki 
>> wrote:
>>
>>> Hey!
>>>
>>> As I was looking through Go docs recently, I've noticed docs for
>>> x/pkgsite wrongly assume that user's $PATH includes $GOPATH/bin, by using
>>> `pkgsite` as a way to launch the command right after installing it.
>>>
>>> Golang installation docs only mention
>>> adding */usr/local/bin/go* to $PATH, so I believe this may be confusing
>>> for new users. At least it was to me.
>>>
>>> Shouldn't these docs explicitly state that they assume that path is
>>> added to $PATH, just for clarity's sake? Or maybe adding $GOPATH/bin (or
>>> $GOBIN) to user's $PATH is a worthy addition to installation docs?
>>>
>>> I decided to ask here, since I don't want to create a whole Github issue
>>> just for something like that. If this gains traction, I'm willing to create
>>> such an issue.
>>>
>>> --
>>> You received this message because you are subscribed 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/53386532-7bd4-421a-9f41-b973dbfa68ean%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/dbc07b3d-4d62-4041-868f-090040322c39n%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/CAEkBMfF2ekq9bxmond00%2B_USccc%2Bew%2BTN%3DvWEyb8XPcpKWny3A%40mail.gmail.com.


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

2024-02-28 Thread &#x27;Axel Wagner&#x27; via golang-nuts
The loop var change *does* break compatibility. And it did so knowingly and
- as clearly explained - was an exception.
Stop arguing in bad faith.

On Thu, Feb 29, 2024 at 7:03 AM tapi...@gmail.com 
wrote:

>
>
> On Wednesday, February 28, 2024 at 3:19:37 PM UTC+8 Axel Wagner wrote:
>
> That would break backwards compatibility, though. And it would be a
> re-definition (i.e. existing code would compile, but behave differently at
> runtime) and is hence not allowed even under the Go 2 transition rules.
>
>
> With Go version specified, nothing can be broken. For example, the loop
> var change in Go 1.22 doesn't break backwards compatibility. (Though this
> is not my opinion, ;D)
>
>
> I'm also not sure you can exclude *all* pointers to zero-sized variables.
> Note that `[0]T` is also zero-sized and you can convert slices (even empty
> ones) into array-pointers. And you can take the address of struct fields.
>
> All of this to solve an honestly pretty small issue. It's a corner, yes.
> But it isn't a particularly sharp corner.
>
> On Wed, Feb 28, 2024 at 8:06 AM 'Brian Candler' via golang-nuts <
> golan...@googlegroups.com> wrote:
>
> > let's consider the two possible definitions:
> >
> > 1. Pointers to distinct zero-size variables are equal: [...]
> > 2. Pointers to distinct zero-size variables are not equal:
>
> Another possibility:
>
> 3. Equality comparisons between pointers to zero-size variables are
> forbidden at compile time.
> 3a. If you wrap two such values in interfaces and try to compare them,
> then you get a runtime panic, same as certain cases today
> <https://go.dev/play/p/MgtUz2em65A>.
>
> Indeed, what if it were forbidden to take a pointer to a zero-sized
> variable in the first place? There is nothing to point at, after all.
>
> On Wednesday 28 February 2024 at 07:17:24 UTC+7 Brien Colwell wrote:
>
> I think the surprising part is that the comparison result can change for
> the same values because of the assumption that pointers never change. This
> is implied by the spec but easy to miss.
>
> "Pointers to distinct zero-size variables may or may not be equal."
> "Pointers to distinct zero-size variables may or may not be equal and the
> results may or may not be repeatable in any context."
>
> Agree once a programmer is aware of the behavior it can be avoided.
>
> Best,
> Brien
>
>
> On Feb 27, 2024, at 3:06 PM, 'Axel Wagner' via golang-nuts <
> golan...@googlegroups.com> wrote:
>
> On Tue, Feb 27, 2024 at 8:19 PM Marvin Renich  wrote:
>
> Prior to generics, the type of the
> arguments to == were easily known to the programmer, and so it was
> obvious when this "undefined" exception would raise its ugly head, and
> you just didn't use it for empty struct types.  But now, with generics,
> this can only be classified as a glaring BUG in the spec.
>
>
> There is pretty much a 0% chance that we'd change the spec in this regard,
> at this point. It would mean that variable declarations like
> `[1<<30]struct{}` would have to allocate huge chunks of heap, to ensure
> that different index-expressions can have different addresses. And while
> there shouldn't be any code relying on that not happening for correctness,
> there is definitely code out there relying on it for performance (e.g.
> there is a pattern of adding struct fields like `_ [0]func()` to ensure a
> type is not comparable - such a struct would now change alignment and size).
>
> The optimization that variables of zero size can re-use the same address
> has been in Go since before Go 1. Given this, it is pretty much implied
> that comparison of those pointers will sometimes have weird results - the
> only question is, *which* results are weird. I agree that this is one of
> the weirder cases. But I don't think we can practically define `==` for
> pointers to zero-sized variables.
>
> I'll also point out that for generics specifically, I'm not sure *any*
> action would have a practical effect. If the type argument is not
> statically known, we also can't special-case it to take into account that
> it's a pointer to a zero-sized variable. Note that the triggered
> optimization isn't necessarily "these are pointers to zero-sized variables,
> hence I can do whatever I want" - it's "these are pointers to distinct
> variables, hence I can assume they are unequal". That is a generally useful
> optimization and it would still be applied to generic code.
>
> How can a programmer count on x == y having any meaning at all in code
> like this:
>
> func IsEqual[T comparable](x, y T

Re: [go-nuts] x/pkgsite docs wrongly assume $PATH includes $GOPATH/bin

2024-02-28 Thread &#x27;Axel Wagner&#x27; via golang-nuts
Doesn't the `go install` command explicitly instruct you to add
$GOBIN/$GOPATH/bin to your $PATH? To me, that seems enough - it feels a bit
arduous, to expect this piece of information at any single point on the web
where `go install` is mentioned.

On Thu, Feb 29, 2024 at 1:39 AM Robert Sawicki 
wrote:

> Hey!
>
> As I was looking through Go docs recently, I've noticed docs for x/pkgsite
> wrongly assume that user's $PATH includes $GOPATH/bin, by using `pkgsite`
> as a way to launch the command right after installing it.
>
> Golang installation docs only mention adding
> */usr/local/bin/go* to $PATH, so I believe this may be confusing for new
> users. At least it was to me.
>
> Shouldn't these docs explicitly state that they assume that path is added
> to $PATH, just for clarity's sake? Or maybe adding $GOPATH/bin (or $GOBIN)
> to user's $PATH is a worthy addition to installation docs?
>
> I decided to ask here, since I don't want to create a whole Github issue
> just for something like that. If this gains traction, I'm willing to create
> such an issue.
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/53386532-7bd4-421a-9f41-b973dbfa68ean%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/CAEkBMfG6Qi5%2BWwAkfH2tx9MVHpLpwe2bQKcFYFbmmJ5thvw6BA%40mail.gmail.com.


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

2024-02-27 Thread &#x27;Axel Wagner&#x27; via golang-nuts
That would break backwards compatibility, though. And it would be a
re-definition (i.e. existing code would compile, but behave differently at
runtime) and is hence not allowed even under the Go 2 transition rules.
I'm also not sure you can exclude *all* pointers to zero-sized variables.
Note that `[0]T` is also zero-sized and you can convert slices (even empty
ones) into array-pointers. And you can take the address of struct fields.

All of this to solve an honestly pretty small issue. It's a corner, yes.
But it isn't a particularly sharp corner.

On Wed, Feb 28, 2024 at 8:06 AM 'Brian Candler' via golang-nuts <
golang-nuts@googlegroups.com> wrote:

> > let's consider the two possible definitions:
> >
> > 1. Pointers to distinct zero-size variables are equal: [...]
> > 2. Pointers to distinct zero-size variables are not equal:
>
> Another possibility:
>
> 3. Equality comparisons between pointers to zero-size variables are
> forbidden at compile time.
> 3a. If you wrap two such values in interfaces and try to compare them,
> then you get a runtime panic, same as certain cases today
> <https://go.dev/play/p/MgtUz2em65A>.
>
> Indeed, what if it were forbidden to take a pointer to a zero-sized
> variable in the first place? There is nothing to point at, after all.
>
> On Wednesday 28 February 2024 at 07:17:24 UTC+7 Brien Colwell wrote:
>
>> I think the surprising part is that the comparison result can change for
>> the same values because of the assumption that pointers never change. This
>> is implied by the spec but easy to miss.
>>
>> "Pointers to distinct zero-size variables may or may not be equal."
>> "Pointers to distinct zero-size variables may or may not be equal and the
>> results may or may not be repeatable in any context."
>>
>> Agree once a programmer is aware of the behavior it can be avoided.
>>
>> Best,
>> Brien
>>
>>
>> On Feb 27, 2024, at 3:06 PM, 'Axel Wagner' via golang-nuts <
>> golan...@googlegroups.com> wrote:
>>
>> On Tue, Feb 27, 2024 at 8:19 PM Marvin Renich  wrote:
>>
>>> Prior to generics, the type of the
>>> arguments to == were easily known to the programmer, and so it was
>>> obvious when this "undefined" exception would raise its ugly head, and
>>> you just didn't use it for empty struct types.  But now, with generics,
>>> this can only be classified as a glaring BUG in the spec.
>>
>>
>> There is pretty much a 0% chance that we'd change the spec in this
>> regard, at this point. It would mean that variable declarations like
>> `[1<<30]struct{}` would have to allocate huge chunks of heap, to ensure
>> that different index-expressions can have different addresses. And while
>> there shouldn't be any code relying on that not happening for correctness,
>> there is definitely code out there relying on it for performance (e.g.
>> there is a pattern of adding struct fields like `_ [0]func()` to ensure a
>> type is not comparable - such a struct would now change alignment and size).
>>
>> The optimization that variables of zero size can re-use the same address
>> has been in Go since before Go 1. Given this, it is pretty much implied
>> that comparison of those pointers will sometimes have weird results - the
>> only question is, *which* results are weird. I agree that this is one of
>> the weirder cases. But I don't think we can practically define `==` for
>> pointers to zero-sized variables.
>>
>> I'll also point out that for generics specifically, I'm not sure *any*
>> action would have a practical effect. If the type argument is not
>> statically known, we also can't special-case it to take into account that
>> it's a pointer to a zero-sized variable. Note that the triggered
>> optimization isn't necessarily "these are pointers to zero-sized variables,
>> hence I can do whatever I want" - it's "these are pointers to distinct
>> variables, hence I can assume they are unequal". That is a generally useful
>> optimization and it would still be applied to generic code.
>>
>> How can a programmer count on x == y having any meaning at all in code
>>> like this:
>>>
>>> func IsEqual[T comparable](x, y T) bool {
>>> return x == y
>>> }
>>>
>>> if the definition of == for empty structs is undefined?
>>
>>
>> The result is defined for empty structs, just not for *pointers* to empty
>> structs.
>> Note that `==` has other edge-cases as well. In p

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

2024-02-27 Thread &#x27;Axel Wagner&#x27; via golang-nuts
On Tue, Feb 27, 2024 at 8:19 PM Marvin Renich  wrote:

> Prior to generics, the type of the
> arguments to == were easily known to the programmer, and so it was
> obvious when this "undefined" exception would raise its ugly head, and
> you just didn't use it for empty struct types.  But now, with generics,
> this can only be classified as a glaring BUG in the spec.


There is pretty much a 0% chance that we'd change the spec in this regard,
at this point. It would mean that variable declarations like
`[1<<30]struct{}` would have to allocate huge chunks of heap, to ensure
that different index-expressions can have different addresses. And while
there shouldn't be any code relying on that not happening for correctness,
there is definitely code out there relying on it for performance (e.g.
there is a pattern of adding struct fields like `_ [0]func()` to ensure a
type is not comparable - such a struct would now change alignment and size).

The optimization that variables of zero size can re-use the same address
has been in Go since before Go 1. Given this, it is pretty much implied
that comparison of those pointers will sometimes have weird results - the
only question is, *which* results are weird. I agree that this is one of
the weirder cases. But I don't think we can practically define `==` for
pointers to zero-sized variables.

I'll also point out that for generics specifically, I'm not sure *any*
action would have a practical effect. If the type argument is not
statically known, we also can't special-case it to take into account that
it's a pointer to a zero-sized variable. Note that the triggered
optimization isn't necessarily "these are pointers to zero-sized variables,
hence I can do whatever I want" - it's "these are pointers to distinct
variables, hence I can assume they are unequal". That is a generally useful
optimization and it would still be applied to generic code.

How can a programmer count on x == y having any meaning at all in code like
> this:
>
> func IsEqual[T comparable](x, y T) bool {
> return x == y
> }
>
> if the definition of == for empty structs is undefined?


The result is defined for empty structs, just not for *pointers* to empty
structs.
Note that `==` has other edge-cases as well. In particular, for floating
point/complex type arguments, `==` is irreflexive (e.g. NaN is unequal to
itself).
I'm not sure that pointers to zero-sized variables make this significantly
worse.


> If we can at least agree that this ambiguity is no longer desirable,
>

I don't think we can agree on that, sorry.


> let's consider the two possible definitions:
>
> 1. Pointers to distinct zero-size variables are equal:
>
> This allows the compiler to easily optimize virtual address usage, but
> is inconsistent with the non-zero-size definition.
>

Please look at the issue I filed for some discussion of edge-cases we are
unlikely to be able to cover satisfactorily. One obvious case is when
converting them to `unsafe.Pointer`, in which case the compiler no longer
knows that they point at zero-sized variables. Potentially, any such
conversion would have to re-assign them the magic "zero-sized variable"
address, which then would potentially lead to other weird comparison
implications, when code assumes that two `unsafe.Pointer` pointing at
distinct variables should have distinct addresses.

We could probably make *more* such comparisons evaluate to `true`, but it's
unlikely that we could ever cover *all* of them. It would potentially have
prohibitive performance-impact on slicing operations, for example.

2. Pointers to distinct zero-size variables are not equal:
>
> This is consistent with the non-zero-size definition, but the
> implementation would likely require distinct virtual addresses for
> distinct variables.  Whether this would require committed memory
> corresponding to those virtual addresses is unclear to me.
>

I believe it would. In effect, `struct{}` would have to take at least one
byte (as would a zero-sized array).


> Definition 1 removes the distinction between empty struct values and
> empty struct instances, and the only way for the programmer to get that
> distinction back is by using a non-empty struct.
>
> On the other hand, definition 2 preserves the distinction.  If a
> programmer wants to have instances compare as equal, it is often very
> easy to use instances of the empty type rather than instances of a
> pointer to the empty type.  Implement the methods on the type with value
> receivers rather than pointer receivers.
>

I think if these arguments hold any water, the argument "the programmer
just shouldn't use pointers to zero-sized variables, if they want defined
semantics for ==" is just as valid. That is, if they have control over the
type and we are willing to force them to make a decision aligning with our
definition, why not force them to make a decision aligning with there not
being a definition?


>
> ...Marvin
>
> --
> You received this message because you are subscr

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

2024-02-26 Thread &#x27;Axel Wagner&#x27; via golang-nuts
On Mon, Feb 26, 2024 at 7:25 PM Brien Colwell  wrote:

> Interesting. That seems to break the comparable spec.
>
> >> Pointer types are comparable. Two pointer values are equal if they
> point to the same variable or if both have value nil. Pointers to distinct
> zero-size variables may or may not be equal.
>

How do you think this is broken? Note that there are two distinct variables
involved (a and b). Pointers to distinct variables are allowed to be equal,
or not to be equal.


> >> it would be valid for `==` on pointers to zero-sized types to always
> evaluate to `true`,
>
> This would be more straightforward behavior.
>
>
>
> On Feb 26, 2024, at 9:24 AM, tapi...@gmail.com 
> wrote:
>
> package main
>
> var a, b [0]int
> var p, q = &a, &b
>
> func main() {
> if (p == q) {
> p, q = &a, &b
> println(p == q) // false
> }
> }
>
> On Thursday, February 22, 2024 at 6:55:49 PM UTC+8 Brien Colwell wrote:
>
>> I'm confused by this output. It appears that the interface of two
>> different pointers to an empty struct are equal. In all other cases,
>> interface equality seems to be the pointer equality. What's going on in the
>> empty struct case?
>>
>> ```
>> package main
>>
>> import "fmt"
>>
>> type Foo struct {
>> }
>>
>> func (self *Foo) Hello() {
>> }
>>
>> type FooWithValue struct {
>> A int
>> }
>>
>> func (self *FooWithValue) Hello() {
>> }
>>
>> type Bar interface {
>> Hello()
>> }
>>
>> func main() {
>> a := &Foo{}
>> b := &Foo{}
>> fmt.Printf("%t\n", *a == *b)
>> fmt.Printf("%t\n", a == b)
>> fmt.Printf("%t\n", Bar(a) == Bar(b))
>>
>> c := &FooWithValue{A: 1}
>> d := &FooWithValue{A: 1}
>> fmt.Printf("%t\n", *c == *d)
>> fmt.Printf("%t\n", c == d)
>> fmt.Printf("%t\n", Bar(c) == Bar(d))
>> }
>> ```
>>
>> Prints (emphasis added on the strange case):
>>
>> ```
>> true
>> false
>> **true**
>> true
>> false
>> false
>> ```
>>
>>
>>
> --
> You received this message because you are subscribed to a topic in the
> Google Groups "golang-nuts" group.
> To unsubscribe from this topic, visit
> https://groups.google.com/d/topic/golang-nuts/JBVqWYFdtC4/unsubscribe.
> To unsubscribe from this group and all its topics, send an email to
> golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/6fc9b600-6707-414c-b19b-e5e14919c5a5n%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/E875D5D3-FFB2-40BA-B930-A10461A2998E%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/CAEkBMfG9WhdUFFxpFR0VhNa0tOG7xi01KuGuCmHkv4o3VfQ-zQ%40mail.gmail.com.


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

2024-02-26 Thread &#x27;Axel Wagner&#x27; via golang-nuts
I think you should still wait for the outcome of that issue.

On Mon, Feb 26, 2024 at 10:39 AM brien colwell  wrote:

> I learned a lot from this thread, thank you.
>
> Intuitively the spec seems to conclude a pointer to an empty struct is a
> different type of pointer? Normally a pointer wouldn't be able to change
> values during execution, so we can do things like key maps by pointers.
>

Note that this is not quite right. It is allowed for addresses to change.
It is possible to implement Go with a moving GC, for example, by design.
Pointers in a map would have to be updated by the GC in that case.


> But if every evaluation of the empty struct pointer can lead to a
> different outcome, isn't that the same as the address of the pointer
> arbitrarily changing?
>

Not *quite*. For example, you should be able to rely on `a == a` to always
be true (the spec says "distinct variables", so two pointers to
non-distinct variables would still have to compare equal). So, if you just
pass around a pointer to a single-variable, that should always have the
same behavior: https://go.dev/play/p/5nmqwnCiq9L

But it means that if you have two distinct variables of zero size, you can
no longer meaningfully talk about whether they are "the same pointer". They
might be, or they might not be.

In a sense, it would be valid for `==` on pointers to zero-sized types to
always evaluate to `true`, but it wouldn't be valid for them to always
evaluate to `false`. There are cases where you can rely on two pointers
being the same, but you can *never* rely on them being *different*.

Genereally, though, I'd argue that it's safest to just not assume anything
about pointers to zero-sized variables.

Otherwise if two pointers are different, then the interface comparison of
> two pointers must be different also since the pointer address does not
> change?
>
>
> On Feb 25, 2024, at 1:02 AM, tapi...@gmail.com 
> wrote:
>
> 
> The behavior of Go 1.9 or 1.10 is even more weird.
> They make the following code print false. ;D
>
> package main
>
> type T struct {}
>
> func main() {
>   var a, b = &T{}, &T{}
>   println(a == b || a != b)
> }
>
>
> On Sunday, February 25, 2024 at 4:30:22 PM UTC+8 tapi...@gmail.com wrote:
>
>> Absolutely a bug.
>>
>> On Thursday, February 22, 2024 at 6:55:49 PM UTC+8 Brien Colwell wrote:
>>
>>> I'm confused by this output. It appears that the interface of two
>>> different pointers to an empty struct are equal. In all other cases,
>>> interface equality seems to be the pointer equality. What's going on in the
>>> empty struct case?
>>>
>>> ```
>>> package main
>>>
>>> import "fmt"
>>>
>>> type Foo struct {
>>> }
>>>
>>> func (self *Foo) Hello() {
>>> }
>>>
>>> type FooWithValue struct {
>>> A int
>>> }
>>>
>>> func (self *FooWithValue) Hello() {
>>> }
>>>
>>> type Bar interface {
>>> Hello()
>>> }
>>>
>>> func main() {
>>> a := &Foo{}
>>> b := &Foo{}
>>> fmt.Printf("%t\n", *a == *b)
>>> fmt.Printf("%t\n", a == b)
>>> fmt.Printf("%t\n", Bar(a) == Bar(b))
>>>
>>> c := &FooWithValue{A: 1}
>>> d := &FooWithValue{A: 1}
>>> fmt.Printf("%t\n", *c == *d)
>>> fmt.Printf("%t\n", c == d)
>>> fmt.Printf("%t\n", Bar(c) == Bar(d))
>>> }
>>> ```
>>>
>>> Prints (emphasis added on the strange case):
>>>
>>> ```
>>> true
>>> false
>>> **true**
>>> true
>>> false
>>> false
>>> ```
>>>
>>>
>>> --
> You received this message because you are subscribed to a topic in the
> Google Groups "golang-nuts" group.
> To unsubscribe from this topic, visit
> https://groups.google.com/d/topic/golang-nuts/JBVqWYFdtC4/unsubscribe.
> To unsubscribe from this group and all its topics, send an email to
> golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/e4429119-5c91-44d1-93c4-dc877efdd7b9n%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/96D5EEE6-5E5B-4064-BAA3-AD8B985FE1F0%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/CAEkBMfF6-KiCDG41NKk0NjKtbOpdUppiiHtiZk1xXT7Vg4urwQ%40mail.gmail.com.


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

2024-02-24 Thread &#x27;Axel Wagner&#x27; via golang-nuts
FWIW I believe there is enough subtlety here (small changes in the code
might trigger different compiler optimizations) that I wouldn't rely too
much on probing the compiler with different programs. Instead, I'd suggest
decompiling the binary and/or running it in a debugger, to check what the
actual pointers are. From looking at godbolt, AIUI the compiler is
optimizing the comparison into a constant:
https://go.godbolt.org/z/x1Ef3PxPb

Though, really, I don't think this is *super* weird. Like, don't get me
wrong, the behavior is counter-intuitive. But once you've accepted that
"comparison of pointers to zero-sized variables is not really defined", the
actual myriads of ways in which it behaves counter-intuitively become less
important.



On Sat, Feb 24, 2024 at 5:28 PM jake...@gmail.com 
wrote:

> What is really fantastical is that a==b prints false, even though the
> pointers are actually the same. I am guessing some sort of optimization
> effect is at play here.
>
> https://go.dev/play/p/Dsqeh_aAXKT
>
> type Foo struct {
> }
>
> func main() {
>
> a := &Foo{}
> b := &Foo{}
> fmt.Printf("%t\n", *a == *b)
> fmt.Printf("%t\n", a == b)
> q := uintptr(unsafe.Pointer(a))
> r := uintptr(unsafe.Pointer(b))
> //fmt.Printf("%p %p\n", a, b)
> fmt.Printf("%t\n", q == r)
> fmt.Printf("%x %x\n", q, r)
> }
>
> prints:
>
> true
> false
> true
> c000104ee0 c000104ee0
>
> wild! (or am I missing something?)
> On Thursday, February 22, 2024 at 1:07:08 PM UTC-5 Axel Wagner wrote:
>
>> On Thu, Feb 22, 2024 at 6:44 PM burak serdar  wrote:
>>
>>> Maybe the spec should be clarified to say "for a compilation of a
>>> program, two pointers to zero-size variables may or may not be equal",
>>> because otherwise it implies that if you have
>>>
>>> x:= a==b
>>> y:= a==b
>>>
>>> x may or may not be true.
>>
>>
>> Well, given that the spec is *not* saying what you say it maybe should -
>> it seems we are in agreement. It is indeed correct for `x` to may or not be
>> equal to `y` here, with the spec as it is right now.
>>
>>
>>> If a==b, then that should hold for every
>>> execution of that program, and throughout the program.
>>>
>>>
>>> >
>>> >>
>>> >> That is, if a==b, then
>>> >> interface{}(a)==interface{}(b), and vice versa. But what we have here
>>> >> is a!=b but interface{}(a)==interface{}(b)
>>> >>
>>> >> On Thu, Feb 22, 2024 at 9:50 AM Axel Wagner
>>> >>  wrote:
>>> >> >
>>> >> > Hm actually, the spec allows for this, technically speaking:
>>> https://go.dev/ref/spec#Comparison_operators
>>> >> >
>>> >> > > Pointers to distinct zero-size variables may or may not be equal.
>>> >> >
>>> >> > Arguably, this genuinely would allow comparison of pointers to
>>> zero-sized variables to have any behavior whatsoever (including being
>>> random). But it certainly is confusing.
>>> >> >
>>> >> >
>>> >> > On Thu, Feb 22, 2024 at 5:46 PM Axel Wagner <
>>> axel.wa...@googlemail.com> wrote:
>>> >> >>
>>> >> >> I see. Sorry, I was jumping to conclusions and didn't quite get
>>> what you mean. That is my fault.
>>> >> >>
>>> >> >> I agree that this looks confusing and is arguably a bug. I filed
>>> https://github.com/golang/go/issues/65878, thanks for pointing it out.
>>> >> >>
>>> >> >> On Thu, Feb 22, 2024 at 5:20 PM burak serdar 
>>> wrote:
>>> >> >>>
>>> >> >>> Creating  an interface is not creating a pointer to a zero sized
>>> variable.
>>> >> >>>
>>> >> >>> a==b  prints false. That means, a and b point to different
>>> locations
>>> >> >>> Bar(a)==Bar(b) prints true. If a!=b, then Bar(a) must be
>>> different from Bar(b)
>>> >> >>>
>>> >> >>> On Thu, Feb 22, 2024 at 9:15 AM Axel Wagner
>>> >> >>>  wrote:
>>> >> >>> >
>>> >> >>> > If you expect that, you are misreading the spec. There is no
>>> guarantee of any behavior here. An implementation is allowed to flip a
>>> coin, every time you create a pointer to a zero-sized variable, and either
>>> return a unique pointer or a singleton. I think you may assume that &a ==
>>> &a, always. But apart from that, who knows.
>>> >> >>> >
>>> >> >>> > Zero-sized variables *may* have the same address. They don't
>>> *have* to.
>>> >> >>> >
>>> >> >>> > On Thu, Feb 22, 2024 at 5:12 PM burak serdar <
>>> bse...@computer.org> wrote:
>>> >> >>> >>
>>> >> >>> >> On Thu, Feb 22, 2024 at 9:00 AM Axel Wagner
>>> >> >>> >>  wrote:
>>> >> >>> >> >
>>> >> >>> >> > Note that in the Spec section I quoted above it says "Two
>>> distinct zero-size variables may have the same address in memory" (emphasis
>>> mine).
>>> >> >>> >> > There is no guarantee, that all zero-sized values have the
>>> same address (otherwise, you'd get into inefficiencies when taking the
>>> address of a zero-sized field in a larger struct, or when converting a
>>> zero-capacity slice into an array-pointer). But it is allowed.
>>> >> >>> >> > If you require two pointers returned from different code
>>> paths to be different, for correctness, then you have to make them point at
>>> something that has non-zero size. Otherwise, all potential c

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

2024-02-22 Thread &#x27;Axel Wagner&#x27; via golang-nuts
>From the spec :

> A struct or array type has size zero if it contains no fields (or
elements, respectively) that have a size greater than zero. Two distinct
zero-size variables may have the same address in memory.

On Thu, Feb 22, 2024 at 11:56 AM Brien Colwell  wrote:

> I'm confused by this output. It appears that the interface of two
> different pointers to an empty struct are equal. In all other cases,
> interface equality seems to be the pointer equality. What's going on in the
> empty struct case?
>
> ```
> package main
>
> import "fmt"
>
> type Foo struct {
> }
>
> func (self *Foo) Hello() {
> }
>
> type FooWithValue struct {
> A int
> }
>
> func (self *FooWithValue) Hello() {
> }
>
> type Bar interface {
> Hello()
> }
>
> func main() {
> a := &Foo{}
> b := &Foo{}
> fmt.Printf("%t\n", *a == *b)
> fmt.Printf("%t\n", a == b)
> fmt.Printf("%t\n", Bar(a) == Bar(b))
>
> c := &FooWithValue{A: 1}
> d := &FooWithValue{A: 1}
> fmt.Printf("%t\n", *c == *d)
> fmt.Printf("%t\n", c == d)
> fmt.Printf("%t\n", Bar(c) == Bar(d))
> }
> ```
>
> Prints (emphasis added on the strange case):
>
> ```
> true
> false
> **true**
> true
> false
> false
> ```
>
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/d93760c9-61a7-4a3c-9b5c-d89f023d2253n%40googlegroups.com
> 
> .
>

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


Re: [go-nuts] Could we trade all the `ctx context.Context` arguments for one pointer in `g`?

2024-02-21 Thread &#x27;Axel Wagner&#x27; via golang-nuts
On Wed, Feb 21, 2024 at 1:36 AM Sam Vilain  wrote:

> I had a brief look on the Golang issues in Github and could not find any
> prior proposals along this line using "context" and "dynamic scope" as
> search terms, so I'll submit this as a "new" proposal for now
>

FWIW some prior discussion on this list:

https://groups.google.com/g/golang-nuts/c/bwJecP42Olk
https://groups.google.com/g/golang-nuts/c/8v1aSKMxIuo
https://groups.google.com/g/golang-nuts/c/eEDlXAVW9vU (we both participated
in it, so I assume you're aware of this one)


> Thanks again, and truly—thanks for responding, >100% better than people
> who just rolled eyes and marked thread as read.
>
> Cheers,
> Sam
> On 2/20/24 3:35 PM, Axel Wagner wrote:
>
> If I may quote myself:
>
> > And no matter which choice you make for the language - it means that if
> the programmers wanted the other, they'd have to jump through annoying
> hoops and get confusing and hard to debug problems.
>
> Having a mechanism to get one or the other semantic doesn't change the
> fact that it's easy to choose wrongly by accident, as long as the effect is
> implicit. In fact, the mechanism you propose (AIUI) seems extra confusing:
> Having a function value sometimes create a new dynamic scope and sometimes
> not, is weird and seems like a recipe for frustration.
>
> But really, convincing me isn't really the point, which is why I'm not
> super invested in litigating this (otherwise I might try to come up with
> realistic examples, for instance. Or explain further why I'm still not sure
> that this can be implemented efficiently). I'm just re-stating what, in the
> past, where the reasons why things like this have been rejected. In order
> to predict what I would consider a likely outcome of a proposal like this.
>
> If you think I am wrong or misunderstanding you, you can always file a
> proposal to get a more official response.
>
> On Tue, Feb 20, 2024 at 8:18 PM Sam Vilain  wrote:
>
>> On 2/17/24 1:32 AM, Axel Wagner wrote:
>>
>> On Sat, Feb 17, 2024 at 2:09 AM Sam Vilain  wrote:
>>
>>> I would argue that the matter can be simply decided by choosing the
>>> *calling* stack, not the destination stack.
>>>
>>
>> I agree that this is *one choice*. But the point is, that *sometimes*
>> you'd want one and *sometimes* the other. And no matter which choice you
>> make for the language - it means that if the programmers wanted the other,
>> they'd have to jump through annoying hoops and get confusing and hard to
>> debug problems. So if you want to justify either choice, you have to make
>> an argument that it is so overwhelmingly more common what people would
>> want, that the cost of running into these problems is small enough to be
>> justified by the benefit.
>>
>> I think that's a hard case to make.
>>
>> Alex, I agree that there are cases where you might prefer one versus the
>> other.  However, you cut out the part of my reply where I pointed out it
>> was possible to choose semantics by either returning a closure (context is
>> the source stack) or a bound method (context is the destination stack).
>> Both of these values can be used interchangeably, as they have the same
>> type, func ..., and so the caller does not need to care whether the
>> function they are calling uses the calling context or the original
>> context.  Were you not convinced by the argument?
>>
>> Sam
>>
> --
> Sam
>
>

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


Re: [go-nuts] Could we trade all the `ctx context.Context` arguments for one pointer in `g`?

2024-02-20 Thread &#x27;Axel Wagner&#x27; via golang-nuts
If I may quote myself:

> And no matter which choice you make for the language - it means that if
the programmers wanted the other, they'd have to jump through annoying
hoops and get confusing and hard to debug problems.

Having a mechanism to get one or the other semantic doesn't change the fact
that it's easy to choose wrongly by accident, as long as the effect is
implicit. In fact, the mechanism you propose (AIUI) seems extra confusing:
Having a function value sometimes create a new dynamic scope and sometimes
not, is weird and seems like a recipe for frustration.

But really, convincing me isn't really the point, which is why I'm not
super invested in litigating this (otherwise I might try to come up with
realistic examples, for instance. Or explain further why I'm still not sure
that this can be implemented efficiently). I'm just re-stating what, in the
past, where the reasons why things like this have been rejected. In order
to predict what I would consider a likely outcome of a proposal like this.

If you think I am wrong or misunderstanding you, you can always file a
proposal to get a more official response.

On Tue, Feb 20, 2024 at 8:18 PM Sam Vilain  wrote:

> On 2/17/24 1:32 AM, Axel Wagner wrote:
>
> On Sat, Feb 17, 2024 at 2:09 AM Sam Vilain  wrote:
>
>> I would argue that the matter can be simply decided by choosing the
>> *calling* stack, not the destination stack.
>>
>
> I agree that this is *one choice*. But the point is, that *sometimes*
> you'd want one and *sometimes* the other. And no matter which choice you
> make for the language - it means that if the programmers wanted the other,
> they'd have to jump through annoying hoops and get confusing and hard to
> debug problems. So if you want to justify either choice, you have to make
> an argument that it is so overwhelmingly more common what people would
> want, that the cost of running into these problems is small enough to be
> justified by the benefit.
>
> I think that's a hard case to make.
>
> Alex, I agree that there are cases where you might prefer one versus the
> other.  However, you cut out the part of my reply where I pointed out it
> was possible to choose semantics by either returning a closure (context is
> the source stack) or a bound method (context is the destination stack).
> Both of these values can be used interchangeably, as they have the same
> type, func ..., and so the caller does not need to care whether the
> function they are calling uses the calling context or the original
> context.  Were you not convinced by the argument?
>
> Sam
>

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


Re: [go-nuts] Could we trade all the `ctx context.Context` arguments for one pointer in `g`?

2024-02-16 Thread &#x27;Axel Wagner&#x27; via golang-nuts
On Sat, Feb 17, 2024 at 2:09 AM Sam Vilain  wrote:

> I would argue that the matter can be simply decided by choosing the
> *calling* stack, not the destination stack.
>

I agree that this is *one choice*. But the point is, that *sometimes* you'd
want one and *sometimes* the other. And no matter which choice you make for
the language - it means that if the programmers wanted the other, they'd
have to jump through annoying hoops and get confusing and hard to debug
problems. So if you want to justify either choice, you have to make an
argument that it is so overwhelmingly more common what people would want,
that the cost of running into these problems is small enough to be
justified by the benefit.

I think that's a hard case to make.

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


Re: [go-nuts] Could we trade all the `ctx context.Context` arguments for one pointer in `g`?

2024-02-16 Thread &#x27;Axel Wagner&#x27; via golang-nuts
FWIW the common name for this is "dynamic scope":
https://en.wikipedia.org/wiki/Scope_(computer_science)#Dynamic_scope

The general reason this has not been accepted for Go, is that passing a
Context explicitly removes ambiguities what is meant, in the presence of
closures and goroutines.
If you pass a closure to a different execution context (e.g. via a
channel), it has two bindings for any dynamically scoped variable: One in
the source stack and one in the destination stack. Neither of these seems
more clearly correct than the other. Note, for example, that a callback
could be called from a different goroutine altogether, yet close over the
lexical scope of the function it's defined in.
Goroutines also open some questions on how to efficiently implement this
without races. To be fair, Context has the same issue, but by being a
library type, it's used more sparingly, so the performance question is less
critical.

Ultimately, I don't think a lot has changed about this question over the
years.

On Fri, Feb 16, 2024 at 10:43 PM Sam Vilain  wrote:

> Hi all,
>
> Many moons ago I wrote a proposal
>  to
> make *execution context* a fundamental concept in Go, effectively moving `
> context.Context` to being part of the language, not just an extension.
>
> The main reason to do this is that then it would not be up to the source
> maintainer to have to do the refactoring it takes to retrofit `ctx
> context.Context` arguments passed to functions as the first position, as
> has become the common boilerplate.  In some places, this is impossible: for
> instance, the io.Reader and related interfaces forbid a `context.Context`
> argument, so a reader cannot know where it is being read from.
>
> Why does that matter, you might ask?  The main reason is for
> observability: tracing, logging, debugging, etc.  Of course, context should
> in general not be used to alter behavior, but for observability, it seems
> like it would be fair game for the append–only map that `Context`
> provides, to be available even when working with less than stellar code.
>
> I'm wondering how people would feel about this now?
>
> A summary of my original proposal would be to add a "soft" keyword ("
> context") which is only meaningful when used before "var", but would not
> be prohibited from being a variable name.  I did some experimentation with
> the go parser and found I could get code with 'context' added to is passing
> the parsing tests, so I'm pretty sure this would work without slowing
> things down.  That's the syntax I'll use in this message, but of course
> this is subject to feedback and taste.
>
> Some basic principles stated as text for discussion; there are code
> examples in the original proposal from August 2017.
>
>- Semantically, creating a new scope creates a new execution context.
>Hopefully that is a tautology.
>- Context Variables can be declared in any execution context, using 
> `context
>var` instead of plain `var`, and assuming the `context var` is in
>scope of the observer, to all execution scopes created from that execution
>context, including goroutines.
>- The reverse is not true: the only way you can see changes to a
>variable declared in a high level context, is if the variable has a
>pointer, and the sub–level context changes it (i.e., there's no "magic
>const effect" of declaring a variable with context var.)
>- Functions that don't declare context variables use the same context
>as their caller for retrieving context variables.
>   - Declaring it without assigning it in a function allows you to
>   read it, without changing the context.  Like other variables declared
>   without an assignment, reading it from a context with no parent context
>   that has assigned it would reveal the zero value.
>   - You can refer to the old value in the rvalue of the declaration,
>   or at any point from when you declare it to when you assign it within a
>   function.  However, having an assignment in the scope should be thought 
> of
>   creating a new context immediately with an implicit assignment at the
>   declaration.  I think this behavior keeps the semantics as unambiguous 
> as
>   possible, and avoids having to do funny stuff when assigning the 
> variable
>   late in a function.
>   - Scope would work differently.  While the *state* of the value
>follows the execution context, the visibility of the variable would be
>defined by (a) the package the variable is declared in, and (b) the Case of
>the variable.
>   - `context var localInfo` can only be read and written in the
>   package it is declared in.
>   - While reading the rest of this, be careful not to think of the
>   Monty Python Spam song, as this is about Spans, which are not the same.
>   - `context var OpenSpan Span` declares an exported context
>   variab

Re: [go-nuts] "yield" is backwards

2024-02-07 Thread &#x27;Axel Wagner&#x27; via golang-nuts
I'm not sure what you mean. The `yield` function does exactly the same as
Python's `yield` statement and in fact, that's part of why the name was
chosen.

Compare Python:

def vals(a):
for v in a:
yield v

for x in vals([1,2,3]):
print(x)

With Go:

func vals[T any](s []T) iter.Seq[T] {
return func(yield func(T) bool) {
for _, v := range s {
if !yield(v) { return }
}
}
}

func main() {
for v := range vals([]int{1,2,3}) {
fmt.Println(v)
}
}

Sure, there is a little bit more ceremony involved, as you need things to
be typed and need to return a closure. But ultimately, the generating
function (in Go, the closure) calls yield to… yield a value.

On Wed, Feb 7, 2024 at 4:43 PM mspre...@gmail.com 
wrote:

> The go language is getting better and better for functional programming,
> and I am here for it. I have enjoyed using APL, Scheme, Python. I was
> excited to see https://go.dev/wiki/RangefuncExperiment . However, I am
> puzzled by the choice to name the function parameter that _receives_ a
> Seq's values "yield". That func does the _complement_ to "yield", it
> _receives_ the value. Compare with Python's "yield" statement, which
> _provides_ the value. Couldn't we call the func parameter that receives a
> Seq's values something like "receive" or "consume"?
>
> Thanks,
> Mike
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/40005721-c187-48bf-b5c4-d66de2263185n%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/CAEkBMfF1mYn%3D1T52CJSnPdfsn8TQNWQKO_NMmnAAxeHXZgD77Q%40mail.gmail.com.


Re: [go-nuts] New type in generics

2024-01-13 Thread &#x27;Axel Wagner&#x27; via golang-nuts
The way to do that is to add another level of indirection (as everything in
Software Engineering):

type Namer[T any] interface {
*T
SetName(name string)
}
func WithName[T any, PT Namer[T]](name string) T {
var v T
PT(&v).SetName(name)
return v
}

I will say, though, that it's not unlikely that you'll be happier if you
don't do this and instead accept a plain interface value and let the caller
allocate the value and pass in a pointer. But if you want to do it, this is
the way.

On Sat, Jan 13, 2024 at 8:10 PM Daniel Theophanes 
wrote:

> I have a situation where I would like to create a type, then set a
> property on it within a container. To set the type, I envisioned using a
> method "SetName" which would need to take a pointer receiver: (goplay share
> is down right now so I'll post inline:
> type Namer interface {
> SetName(name string)
> }
>
> I wish to create a new Namer type as well, ideally without using reflect.
> If I use [*Ob ] as the type parameter, that works, but then `new(T)`
> returns `**Ob`, which I can deference to get `*Ob`, but then the value is
> nil (Ob isn't created).
>
> I'm working around this, but it surprised me, the interaction of a pointer
> receiver interface type constraint and then I can't create the desired type.
>
> ```
> package main
>
> import "fmt"
>
> func main() {
> ar := NewAppResult()
> fmt.Printf("AR: %#v\n", *ar)
> ar.Observation.Get("X1")
> }
>
> type Ob struct {
> Gene  string
> Value string
> }
>
> func (o *Ob) SetName(name string) {
> // o is nil and this will panic.
> o.Gene = name
> }
>
> type Namer interface {
> SetName(name string)
> }
>
> type OrderedLookup[T Namer] struct {
> List   []T
> lookup map[string]T
> }
>
> func (ol *OrderedLookup[T]) Get(name string) T {
> v, ok := ol.lookup[name]
> if !ok {
> var v T // T is a pointer, new(T) creates **Ob, but I cant use generic
> type of [Ob] because then Namer
> v.SetName(name)
> ol.lookup[name] = v
> ol.List = append(ol.List, v)
> }
> return v
> }
>
> type AppResult struct {
> Observation *OrderedLookup[*Ob]
> }
>
> func NewAppResult() *AppResult {
> return &AppResult{
> Observation: &OrderedLookup[*Ob]{},
> }
> }
> ```
>
>
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/8d0c816c-c332-4b44-87e3-9259ad173afcn%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/CAEkBMfH69TQg8LndigToQyPtbmujkQr9w8Q_i80Uix5fkW2m4Q%40mail.gmail.com.


Re: [go-nuts] Does building with an older golang use package sources from that older version?

2024-01-10 Thread &#x27;Axel Wagner&#x27; via golang-nuts
You don't even need to run `go clean`. Go will automatically detect whether
stuff needs to be rebuilt, as the Go version used to build a package is
part of a hash, that is used as a key for the build cache.
And yes, it will use the standard library packages of the Go version that
is installed (the one output by `go env GOROOT`). In fact, if you just
change the on-disk content of those packages (e.g. edit `$(go env
GOROOT)/src/fmt/format.go`) it will automatically detect that and rebuild
the changed standard library packages as needed, just like it would with a
first party package. This can be a very useful (and fun) debugging tool, as
it means you can actually insert debug printfs *into the stdlib* to see
what is happening.

All of this assumes your Go installation is setup correctly, of course.

On Thu, Jan 11, 2024 at 2:08 AM Andrew Athan  wrote:

> Say I install golang 1.20.12 and go clean -cache and go clean -modcache.
>
> Then I build.
>
> Will that executable be using crypto/tls and other packages "as they were
> in 1.20.12"? Or is golang fetching the newest available compatible sources,
> and therefore I may be spinning my wheels trying to see if there is a bug
> in the latest crypto/tls?
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/597a23f1-e212-455a-b621-e64108281da8n%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/CAEkBMfG%3DQytK_T5tOAu0_srkrVsfFVjdyKx8XZYi-opMotfxKQ%40mail.gmail.com.


Re: [go-nuts] Type parameter embedded field

2024-01-09 Thread &#x27;Axel Wagner&#x27; via golang-nuts
I think that might work, yes. At least I don't see a major issue with it
right now.



On Tue, Jan 9, 2024 at 7:25 PM roger peppe  wrote:

>
>
> On Fri, 5 Jan 2024 at 05:58, 'Axel Wagner' via golang-nuts <
> golang-nuts@googlegroups.com> wrote:
>
>> Hi,
>>
>> I think the reason this has not happened is that it makes code using such
>> a type invalid, depending on the type-argument - in ways not captured by
>> the constraint. For example:
>>
>> type X[T any] struct {
>> T
>> *bufio.Reader
>> }
>> func main() {
>> var x X[int]
>> x.Read // definitely refers to X.Reader.Read
>> var y X[*strings.Reader]
>> y.Read // ambiguous
>> }
>>
>> Note, in particular, that this might happen very deeply in the call
>> stack, as you can have a generic function instantiating a generic type with
>> a type parameter as well.
>>
>> func main() {
>> F[*strings.Reader]()
>> }
>> func F[T any]() {
>> G[T]()
>> }
>> func G[T any]() {
>> var x X[T]
>> x.Read
>> }
>>
>> For us to actually allow embedding that way, one of three things would
>> need to happen:
>>
>
> To my mind, there's a reasonably obvious way through the issue you
> outlined above (although there may well be more):
> allow a static reference to a field/method if all the embedded types are
> known, and not otherwise.
>
> So in the above example, `x.Read` in `main` is fine; `y.Read` in `main` is
> ambiguous due to two methods at the same level as you say;
> `x.Read` in `G` is not allowed because we don't statically know the method
> set of `x`. Likewise, we couldn't assign `x` to an `io.Reader`,
> but we *could* convert to `any` and then do a dynamic type conversion to
> `io.Reader` if we wished (which would fail in the *strings.Reader case
> but succeed in the int case).
>
> ISTM those semantics would be reasonably intuitive, and good compiler
> error messages could make it quite clear *why* we aren't allowed to
> reference such methods statically.
>
>   cheers,
> rog.
>
>
>>

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


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

2024-01-07 Thread &#x27;Axel Wagner&#x27; via golang-nuts
The "missing return" error is defined in the spec, by requiring a function
to end in a terminating statement:
https://go.dev/ref/spec#Terminating_statements
The list is necessarily not complete. So it is necessarily more advisory
than anything else. What things to put in is mainly limited by how much
complexity it would be to specify it and how important we deem it.
Specifying this case seems pretty hard to specify (note that `i` could be
modified in the loop body, so this always terminating requires some pretty
complex statements about what is or is not in the loop body - in
particular, if you want to do it on a purely syntactical level).
It also also can be replaced by `func TestMethod() int { return 0 }`, which
is strictly better, more readable code, so I wouldn't even necessarily
agree that it's a false-positive error message: You *should* fix that.



On Mon, Jan 8, 2024 at 5:32 AM burak serdar  wrote:

> This question came up on Stack Overflow today:
>
> The following code is giving a "missing return" error where it shouldn't:
>
> func TestMethod() int {
>for i := 0; i < 10; i++ {
>return 0
>}
> }
>
> Looks like an overlooked case in control flow analysis.
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/CAMV2RqosYR2bo-j5Xg77BCf-HKeBV3679zFNLrpoV5GwKntX%2BQ%40mail.gmail.com
> .
>

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


Re: [go-nuts] Type parameter embedded field

2024-01-04 Thread &#x27;Axel Wagner&#x27; via golang-nuts
Hi,

I think the reason this has not happened is that it makes code using such a
type invalid, depending on the type-argument - in ways not captured by the
constraint. For example:

type X[T any] struct {
T
*bufio.Reader
}
func main() {
var x X[int]
x.Read // definitely refers to X.Reader.Read
var y X[*strings.Reader]
y.Read // ambiguous
}

Note, in particular, that this might happen very deeply in the call stack,
as you can have a generic function instantiating a generic type with a type
parameter as well.

func main() {
F[*strings.Reader]()
}
func F[T any]() {
G[T]()
}
func G[T any]() {
var x X[T]
x.Read
}

For us to actually allow embedding that way, one of three things would need
to happen:

1. We would have to decide to be happy with type-checking of generic code
only to happen at the instantiation site. That is what C++ is doing. It
seems very unlikely to me, that Go would ever do that - in fact "we
shouldn't do that" was one of the design constraints put unto generics. It
is bad if a seemingly innocuous and backwards-compatible change in a
library can break your code. Imagine that F and G above live in separate
modules and G introduces the x.Read call in a debug release - because it
seems innocuous and they tested it with their code and it works - because
*they* never instantiate it with an io.Reader. Then, after their release,
*your* code breaks, because you do.
2. We would have to enrich the constraint language to allow you to express
that kind of constraint. i.e. X's constraint would mention, that it can
only be instantiated with types that don't have a Read (or ReadByte,
ReadLine, …) field or method. Again, this seems very unlikely to me, as it
would require a really rich constraint language for relatively little
benefit. In particular, it seems likely that such a language would be
NP-complete to type check and we're unlikely to be happy about that. In
fact, if I may shamelessly plug that, I recently gave a talk about another
instance of a far more useful extension to the constraint language that we
disallow for that very reason

.
3. Someone comes up with a clever new compromise. To me, this actually is
one of the more likely cases where a clever compromise could happen
(compared to things like "allowing methods in unions", or "allowing to pass
around uninstantiated generic functions" or "adding generic methods"). But
I'm not aware of anyone having proposed or seriously working on anything
like that.

So, in my opinion: I wouldn't hold my breath. I think it's unlikely this
will happen and definitely not any time soon.

On Fri, Jan 5, 2024 at 1:07 AM 'Sylvain Rabot' via golang-nuts <
golang-nuts@googlegroups.com> wrote:

> type Nullable[T any] struct {
> T
> valid bool
> }
>

Just as an aside: I think this is actually a pretty interesting example.
Because in my opinion, you absolutely *don't* want embedding to work here.
Because it would mean that you could use an invalid `Nullable[T]` as if it
was a valid one. And ISTM the entire point of a `Nullable[T]` should be, to
prevent those kinds of bugs. In fact, `*T` seems *strictly preferable* over
a `Nullable[T]` as described here, because at least it might catch these
bugs at runtime.

But of course, there are other cases where embedding type parameters might
be useful.


>
> Regards.
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/f2b8c317-9530-45ff-b9f2-e9fe209a062cn%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/CAEkBMfEJGHsF7AzFFNUGB2nZFstR9dZg9r57aOnDQLnGKARJvA%40mail.gmail.com.


Re: [go-nuts] How to create a generic factory?

2023-12-31 Thread &#x27;Axel Wagner&#x27; via golang-nuts
Note that your code is not type-safe. It panics when instantiated with a
type that does not use a pointer receiver: https://go.dev/play/p/eHUKtXvgwAu
ISTM that being more type-safe would be an advantage here.

On Sat, Dec 30, 2023 at 8:47 PM Mazen Harake  wrote:

> @Alex,
>
> Oh, and I should point out that I actually went with what you mentioned in
> your 1st point, I was just curious if it was possible to do it the other
> way.
>
> On Saturday 30 December 2023 at 20:36:07 UTC+1 Mazen Harake wrote:
>
>> Cheers @Axel for the input. I think I worked it out though.
>>
>> The bad thing is that it involves reflection but considering that it
>> greatly simplifies the code base I would argue that it is good enough for
>> now.
>>
>> First, regarding your 2nd point of passing buf as a parameter to Decode()
>> instead of through a field. The examples I gave are made up to resemble the
>> actual situation to simplify it but what actually happens is that each
>> message has a "BaseMessage" struct. When receiving some payload the common
>> parts of the message (such as the length, type and checksums) are always
>> decoded into base message, then depending on the type the specific message
>> type is created and the rest of the bytes are decoded according to what
>> that message expects.
>>
>> Anyway... this is the solution I came up with (for internet searching
>> completeness sake):
>>
>> func DecodeMessage[T Decoder](bm *BaseMessage) (T, bool) {
>>   var mT T
>>   m := reflect.New(reflect.TypeOf(mT).Elem()).Interface().(T)
>>   d := Decoder(m)
>>   ok := d.Decode( bm )
>>   return d.(T), ok
>> }
>>
>> This function is then called with the following code example:
>>
>> transactionMsg, ok :=  DecodeMessage [*TransactionMessage](baseMsg)
>>
>> Cheers
>>
>>
>> On Friday 29 December 2023 at 23:17:47 UTC+1 Axel Wagner wrote:
>>
>> 1. Note that you can just write `NewMessage(&MessageA{}, buf)` in your
>> example, as the type can be inferred.
>> 2. You can use a constraint on a pointer-receiver to somewhat simplify
>> that: https://go.dev/play/p/pEu02Bn9t3f
>> That is not *quite* what you are asking for. It is not actually possible
>> to really do what you want, because there is no way to express a constraint
>> that "the type needs to have a `Buf []byte` field, which would be needed to
>> make your `m := &MessageAStruct{Buf: b}` work. But there isn't really a
>> reason to pass the buffer as a field anyways, in my opinion - passing it as
>> a parameter to `Decode` seems far more logical.
>>
>> On Fri, Dec 29, 2023 at 8:52 PM Mazen Harake  wrote:
>>
>> Hi all,
>>
>> Assume I have a tcp server with incoming tcp packets which can be decoded
>> in differently depending on some headers in that packet.
>>
>> Each message that comes in has a struct associated with it which can be
>> created with the traditionale NewX..(buf []byte ...). After creating the
>> object (or inside the constructor, doesn't matter) the Decode() function is
>> called to interpret the bytes and assign all the fields of the struct.
>>
>> This works fine. But is it possible to eliminate all the 200+ functions
>> that do the same thing but use a generic function instead?
>>
>> So instead of this:
>>
>> func NewMessageA(buf []byte) *MessageAStruct {
>>   m := &MessageAStruct{
>> Buf: buf,
>>   }
>>   m.Decode()
>>   return m
>> }
>>
>> msg := NewMessageA(buf)
>>
>> I would rather do something like this:
>>
>> msg := NewMessage[A](buf)
>>
>> and I would've wanted to do something like this in the generic function
>>
>> func NewMessage[T](buf []byte) *T {
>>   // ... something?
>>   // call Decode()
>>   // return *T
>> }
>>
>> I can do it by creating an interface called Decodable and then passing
>> the the type and the "empty" object to the generic function but it feels
>> clumsy and weird somehow and I probably wouldn't gain very much. E.g.
>>
>> func NewMessage[T Decodable](t T, buf []byte) T {
>>   t.Decode(buf)
>>   return t
>> }
>>
>> and I would call it like this
>>
>> msg := NewMessage[*MessageA](&MessageA{}, buf)
>>
>> The most likely answer is "You shouldn't do it like that", which would be
>> a completely fine and acceptable answer, but *can* you achieve this?
>>
>> Cheers
>>
>> --
>> You received this message because you are subscribed to the Google Groups
>> "golang-nuts" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to golang-nuts...@googlegroups.com.
>> To view this discussion on the web visit
>> https://groups.google.com/d/msgid/golang-nuts/5dc5715c-aad9-431f-8ea0-9c89db46d873n%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 discussio

Re: [go-nuts] How to create a generic factory?

2023-12-29 Thread &#x27;Axel Wagner&#x27; via golang-nuts
1. Note that you can just write `NewMessage(&MessageA{}, buf)` in your
example, as the type can be inferred.
2. You can use a constraint on a pointer-receiver to somewhat simplify
that: https://go.dev/play/p/pEu02Bn9t3f
That is not *quite* what you are asking for. It is not actually possible to
really do what you want, because there is no way to express a constraint
that "the type needs to have a `Buf []byte` field, which would be needed to
make your `m := &MessageAStruct{Buf: b}` work. But there isn't really a
reason to pass the buffer as a field anyways, in my opinion - passing it as
a parameter to `Decode` seems far more logical.

On Fri, Dec 29, 2023 at 8:52 PM Mazen Harake  wrote:

> Hi all,
>
> Assume I have a tcp server with incoming tcp packets which can be decoded
> in differently depending on some headers in that packet.
>
> Each message that comes in has a struct associated with it which can be
> created with the traditionale NewX..(buf []byte ...). After creating the
> object (or inside the constructor, doesn't matter) the Decode() function is
> called to interpret the bytes and assign all the fields of the struct.
>
> This works fine. But is it possible to eliminate all the 200+ functions
> that do the same thing but use a generic function instead?
>
> So instead of this:
>
> func NewMessageA(buf []byte) *MessageAStruct {
>   m := &MessageAStruct{
> Buf: buf,
>   }
>   m.Decode()
>   return m
> }
>
> msg := NewMessageA(buf)
>
> I would rather do something like this:
>
> msg := NewMessage[A](buf)
>
> and I would've wanted to do something like this in the generic function
>
> func NewMessage[T](buf []byte) *T {
>   // ... something?
>   // call Decode()
>   // return *T
> }
>
> I can do it by creating an interface called Decodable and then passing the
> the type and the "empty" object to the generic function but it feels clumsy
> and weird somehow and I probably wouldn't gain very much. E.g.
>
> func NewMessage[T Decodable](t T, buf []byte) T {
>   t.Decode(buf)
>   return t
> }
>
> and I would call it like this
>
> msg := NewMessage[*MessageA](&MessageA{}, buf)
>
> The most likely answer is "You shouldn't do it like that", which would be
> a completely fine and acceptable answer, but *can* you achieve this?
>
> Cheers
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/5dc5715c-aad9-431f-8ea0-9c89db46d873n%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/CAEkBMfH-NnvmvJ8h_EX2ZRcmyVH49P-VY7mYkPnPdr6Q-mxcww%40mail.gmail.com.


Re: [go-nuts] Re: Why there is no net.ListenContext?

2023-12-19 Thread &#x27;Axel Wagner&#x27; via golang-nuts
Hm, reading again, I don't think I actually understand your question. You
clearly are ListenConfig aware.
But what do you mean with "the same way we have Dial and DialContext"?
These are methods on Dialer, so ISTM that there is indeed a pretty clear
correspondence. Except that Dialer.Dial has been introduced in Go 1.1,
before we had context.Context, so we needed a new name for the
context-aware API.
So I'm not sure what exactly you are asking. ISTM you are not missing a
context-aware version of Listen, so what is it you are asking for?

On Tue, Dec 19, 2023 at 10:14 PM Axel Wagner 
wrote:

> You can use `ListenConfig.Listen` to do this:
> https://pkg.go.dev/net#ListenConfig.Listen
> I believe the reason to do it this way was the realization that there will
> probably be more ways to set up listening in the future and having lots of
> different ListenFoo functions in the package would overload the namespace
> too much.
>
> On Tue, Dec 19, 2023 at 9:28 PM Michał Matczuk  wrote:
>
>> The context is passed downstream but cancelling it seems to have no
>> effect.
>> I guess that the reason why it's not exported.
>> Can anyone shed more light on it?
>>
>> wtorek, 19 grudnia 2023 o 11:59:49 UTC+1 Michał Matczuk napisał(a):
>>
>>> If you take a look at net.Listen implementation
>>>
>>> func Listen(network, address string) (Listener, error) {
>>> var lc ListenConfig
>>> return lc.Listen(context.Background(), network, address)
>>> }
>>>
>>> you will notice the new listen API net.ListenConfig.
>>>
>>> This API is context aware, I think it would be handy if we had
>>> net.ListenContext the same way we have Dial and DialContext.
>>>
>>> Any thoughts on that?
>>>
>> --
>> You received this message because you are subscribed to the Google Groups
>> "golang-nuts" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to golang-nuts+unsubscr...@googlegroups.com.
>> To view this discussion on the web visit
>> https://groups.google.com/d/msgid/golang-nuts/8abe1abb-eb3b-4632-b3c0-e430f2f42270n%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/CAEkBMfFL%3D7FOBWWE2rRzPSVv99jtUUi%3D7Tiz7ZEtMYUtcCLT6g%40mail.gmail.com.


Re: [go-nuts] Re: Why there is no net.ListenContext?

2023-12-19 Thread &#x27;Axel Wagner&#x27; via golang-nuts
You can use `ListenConfig.Listen` to do this:
https://pkg.go.dev/net#ListenConfig.Listen
I believe the reason to do it this way was the realization that there will
probably be more ways to set up listening in the future and having lots of
different ListenFoo functions in the package would overload the namespace
too much.

On Tue, Dec 19, 2023 at 9:28 PM Michał Matczuk  wrote:

> The context is passed downstream but cancelling it seems to have no effect.
> I guess that the reason why it's not exported.
> Can anyone shed more light on it?
>
> wtorek, 19 grudnia 2023 o 11:59:49 UTC+1 Michał Matczuk napisał(a):
>
>> If you take a look at net.Listen implementation
>>
>> func Listen(network, address string) (Listener, error) {
>> var lc ListenConfig
>> return lc.Listen(context.Background(), network, address)
>> }
>>
>> you will notice the new listen API net.ListenConfig.
>>
>> This API is context aware, I think it would be handy if we had
>> net.ListenContext the same way we have Dial and DialContext.
>>
>> Any thoughts on that?
>>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/8abe1abb-eb3b-4632-b3c0-e430f2f42270n%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/CAEkBMfGavp70pXA%3DQWpa5NXroUWdCRhHUw%3D11JNssKDGvfgn3Q%40mail.gmail.com.


Re: [go-nuts] slog formatter funcs? (e.g. slog.Infof)

2023-12-13 Thread &#x27;Axel Wagner&#x27; via golang-nuts
I believe the intention is that you shouldn't format this, but make `err`
an `Attr`. i.e. the philosophy behind structured logging is specifically,
not to do formatting, as it produces unstructured data. Whether I'm
personally convinced by that philosophy is another question, but I think
that's the reason these where left out.

On Wed, Dec 13, 2023 at 3:30 AM 'Billy Lynch' via golang-nuts <
golang-nuts@googlegroups.com> wrote:

> Hi!
>
> I've been playing around with the new slog package, and I noticed that it
> was missing formatter funcs (Infof, Errorf, etc). I'm interested in adding
> these, but I wasn't sure if this was done intentionally since the godoc calls
> out this type of functionality in examples
> .
>
> Helpers have been suggested as a workaround for this
> , but
> this is common enough behavior for me that I think it'd be very helpful to
> have upstream to make it easy to do things like: slog.Errorf("error calling
> func: %v", err)
>
> Rough idea would be do expose formatter functions in the Logger
> , with the tradeoff that you replace
> formatter args for Attr args:
>
> ```go
> func (l *Logger) Errorf(format string, args ...any) {
> l.log(context.Background(), LevelError, fmt.Sprintf(msg, args...))
> }
>
> func (l *Logger) ErrorContextf(ctx context.Background(ctx context.Context,
> format string, args ...any) {
> l.log(ctx, LevelError, fmt.Sprintf(msg, args...))
> }
> ```
>
> I wanted to check in before I opened an issue! 🙏
> Let me know if this makes sense, or if there's context I'm missing.
>
> 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/9316489a-3a0c-4b8e-b789-534662a9bbben%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/CAEkBMfGQ-hs-C1cEy_WLWWX4Gj9ZP7%3DspyUgdv2s7Zs3TdHP0g%40mail.gmail.com.


Re: [go-nuts] Generic type for struct method: constraint problem && cannot use (untyped string constant) as string value

2023-11-09 Thread &#x27;Axel Wagner&#x27; via golang-nuts
I agree that it is an unfortunate error message, but to be clear, it is
entirely correct - you are defining a new type called `uint8` and it is
indeed not possible to assign an untyped integer constant to that, as its
underlying type is a type parameter (constrained on any).

I'm pretty sure there already is an issue about this, though I can't come
up with helpful search terms to look it up. But the short term fix is
absolutely "don't define types with the same name as predeclared idenfiers".

On Fri, Nov 10, 2023 at 3:25 PM ahuigo  wrote:

> Btw, please ignore the type logic in my code, I wrote this piece of code
> just to illustrate the oddities of generics in struct methods.
> Regardless of whether its type is int, string, any, *or the exact uint8,
> this error is very strange.*
>
>
> // it doesn't work
> func (c *cachedFn[uint8, V]) Get0() (V, error) {
> var s uint8 = 0
> s = 0 // error: cannot use 0 (untyped int constant) as uint8 value in
> assignment
> fmt.Printf("cache key: %#v, %T\n", s, s) // cache key: 0, uint8
> return c.Get(s)
> }
>
> // it works
> func (c *cachedFn[uint8, V]) Get0() (V, error) {
> var s uint8 = 0
> fmt.Printf("cache key: %#v, %T\n", s, s) // cache key: 0, uint8
> return c.Get(s)
> }
>
> On Friday, November 10, 2023 at 4:34:46 AM UTC+8 Axel Wagner wrote:
>
>> Yes, this has come up before.
>>
>> On Fri, Nov 10, 2023 at 7:09 AM ahuigo  wrote:
>>
>>> There is an example: https://go.dev/play/p/guzOWRKi-yp
>>>
>>> ```
>>> func (c *cachedFn[string, V]) Get0() (V, error) {
>>> // var s any
>>> var s string
>>> s = "abc" // error: cannot use "abc" (untyped string constant) as string
>>> value in assignment
>>> fmt.Printf("cache key: %#v, %T\n", s, s) // cache key: 0, uint8
>>> return c.Get(s)
>>> }
>>> ```
>>> I find the generic type of the struct method a bit confusing.
>>> 1.  The type `cachedFn[string, V]` does not really constrain the type
>>> of  `s` to **string**. It's actual type is `uint8`
>>>
>>
>> The type `cachedVn[string, V]` *would* in fact instantiate `cachedVn`
>> with `string` and `V`.
>> But that's not what you are doing. You are writing the receiver type as
>> `fun c(c *cachedFn[string, V])`, which means that "the receiver is the
>> generic type `cachedVn` with two type parameters called `string` and `V`".
>> Predeclared identifiers in Go are not special in any way, you can re-use
>> them for your own variables and types - or type parameters. So what you are
>> doing here is fundamentally similar to this problem:
>> https://go.dev/play/p/lDE-o7fGHi8
>>
>> There probably should be a vet check for using a predeclared identifier
>> as a type parameter name (or maybe even for any re-use of a predeclared
>> identifier).
>>
>> 2. And this error is a bit strange. (`s = "abc"  // error: cannot use
>>> "abc" (untyped string constant) as string value in assignment. ` )
>>>
>>>
>>> --
>>> You received this message because you are subscribed 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/58c92577-cb98-401a-978d-c22a1fb493ccn%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/e7540f45-1c74-4b51-9ed6-1b60837100bcn%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/CAEkBMfFNjkGLZzA2xLSZwua40-Ab852m6QE05wzaudg5HTruaQ%40mail.gmail.com.


Re: [go-nuts] Generic type for struct method: constraint problem && cannot use (untyped string constant) as string value

2023-11-09 Thread &#x27;Axel Wagner&#x27; via golang-nuts
Yes, this has come up before.

On Fri, Nov 10, 2023 at 7:09 AM ahuigo  wrote:

> There is an example: https://go.dev/play/p/guzOWRKi-yp
>
> ```
> func (c *cachedFn[string, V]) Get0() (V, error) {
> // var s any
> var s string
> s = "abc" // error: cannot use "abc" (untyped string constant) as string
> value in assignment
> fmt.Printf("cache key: %#v, %T\n", s, s) // cache key: 0, uint8
> return c.Get(s)
> }
> ```
> I find the generic type of the struct method a bit confusing.
> 1.  The type `cachedFn[string, V]` does not really constrain the type of
> `s` to **string**. It's actual type is `uint8`
>

The type `cachedVn[string, V]` *would* in fact instantiate `cachedVn` with
`string` and `V`.
But that's not what you are doing. You are writing the receiver type as
`fun c(c *cachedFn[string, V])`, which means that "the receiver is the
generic type `cachedVn` with two type parameters called `string` and `V`".
Predeclared identifiers in Go are not special in any way, you can re-use
them for your own variables and types - or type parameters. So what you are
doing here is fundamentally similar to this problem:
https://go.dev/play/p/lDE-o7fGHi8

There probably should be a vet check for using a predeclared identifier as
a type parameter name (or maybe even for any re-use of a predeclared
identifier).

2. And this error is a bit strange. (`s = "abc"  // error: cannot use "abc"
> (untyped string constant) as string value in assignment. ` )
>
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/58c92577-cb98-401a-978d-c22a1fb493ccn%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/CAEkBMfGJBR7QwNDyeCvp10mDhRTeGnk0T01OFq01GvgDSx8KgA%40mail.gmail.com.


Re: [go-nuts] Can Generics match implementers of an interface?

2023-10-24 Thread &#x27;Axel Wagner&#x27; via golang-nuts
On Tue, Oct 24, 2023 at 6:14 PM Victor Giordano 
wrote:

> TD;DR: The above is just a stream of consciousness that I release in this
> place that I find appropriate for this purpose. Forgive me in advance.
>

I find it inappropriate, pardon my bluntness. The use cases for generics
are well documented. We have them in Go, since three versions. Please move
on. If you want to improve the language, accept where we are right now and
how we can best continue from here. Instead of pretending it is still 2+
years ago and we would still discuss whether to add them.

This thread in particular is not even a significant complication of them.
It's about a comparatively mild, potential improvement on type inference.
It's not about improving their expressive power in any way.


>
> This is the thing about generics... make the world a very complex place..
> and I do wonder... ¿ What kind of problems can be solved by generics that
> can not be solved by interfaces?
> If the idea is to be minimalism... ¿why do you surrender to the temptation
> of generics?... ¿Does a language need generics to become better or is human
> temptation in its unfilled need to write less and less that invent
> generics...? ¿I'm the lazy one that rants for having to learn new types
> theory?
>
> and After a few drinks: First Object class now interface{} struct...
> you both have everything... generics... keep it simple please... don't
> become Scala...
>
> El mar, 24 oct 2023 a las 12:49, 'Axel Wagner' via golang-nuts (<
> golang-nuts@googlegroups.com>) escribió:
>
>> I think addressing this would sensibly include a rule to allow unifying
>> two types, if one is assignable to the other (which, AIUI, we already do
>> for directional channels).
>>
>> It's possible that this can be confusing in some circumstances including
>> composite types e.g. something like
>>
>> func Append[T any](s []T, v ...T)
>> func main() {
>> var (
>> s []any
>> v []io.Reader
>> )
>> s = Append(s, v...) // would infer Append[any] and then fail to
>> compile because []io.Reader is not assignable to []any
>> }
>>
>> But I can't really come up with an example where this is worse than the
>> status quo. Or even where something that *could* compile with fully
>> specified instantiation then doesn't compile with inferred arguments.
>>
>> The situation also becomes significantly more complex if we take
>> assignment context into account for inference. AIUI we currently don't and
>> it is something I want.
>>
>> I wouldn't want to confidently state that this is something we should or
>> should not do.
>>
>> On Tue, Oct 24, 2023 at 5:01 PM tapi...@gmail.com 
>> wrote:
>>
>>> My another surprise is that the below partial instantiation doesn't
>>> work.
>>>
>>> s = slices.Insert[[]Suiter](s, len(s), Clubs{}) // not work
>>> s = slices.Insert[[]Suiter, Suiter](s, len(s), Clubs{}) // works
>>>
>>> On Monday, October 23, 2023 at 11:01:47 AM UTC+8 tapi...@gmail.com
>>> wrote:
>>>
>>>> On Monday, October 23, 2023 at 10:38:59 AM UTC+8 tapi...@gmail.com
>>>> wrote:
>>>>
>>>> Sorry, I didn't look your full code.
>>>> I think the full code should work with Go toolchain 1.21.n.
>>>>
>>>>
>>>> Aha, it actually doesn't. I'm surprised.
>>>>
>>>>
>>>> On Sunday, October 22, 2023 at 4:40:55 PM UTC+8 Mike Schinkel wrote:
>>>>
>>>> How so?
>>>>
>>>> Can you give an example scenario where it could cause unintended
>>>> consequences?  Or some other negative?
>>>>
>>>> -Mike
>>>>
>>>> On Saturday, October 21, 2023 at 11:57:52 PM UTC-4 tapi...@gmail.com
>>>> wrote:
>>>>
>>>>
>>>> It is hard to call such type inference better. That is too aggressive.
>>>>
>>>> --
>>> You received this message because you are subscribed to the Google
>>> Groups "golang-nuts" group.
>>> To unsubscribe from this group and stop receiving emails from it, send
>>> an email to golang-nuts+unsubscr...@googlegroups.com.
>>> To view this discussion on the web visit
>>> https://groups.google.com/d/msgid/golang-nuts/7bd4727b-46ec-4972-b9a3-f7271892bff5n%40googlegroups.com
>>> <https://groups.google.com/d/msgid/golang-nuts/7bd4727b-46ec-4972-b9a3-f7271892bff5n%40googlegroups.com?utm_medium=email&utm_source=footer>

Re: [go-nuts] Can Generics match implementers of an interface?

2023-10-24 Thread &#x27;Axel Wagner&#x27; via golang-nuts
I think addressing this would sensibly include a rule to allow unifying two
types, if one is assignable to the other (which, AIUI, we already do for
directional channels).

It's possible that this can be confusing in some circumstances including
composite types e.g. something like

func Append[T any](s []T, v ...T)
func main() {
var (
s []any
v []io.Reader
)
s = Append(s, v...) // would infer Append[any] and then fail to compile
because []io.Reader is not assignable to []any
}

But I can't really come up with an example where this is worse than the
status quo. Or even where something that *could* compile with fully
specified instantiation then doesn't compile with inferred arguments.

The situation also becomes significantly more complex if we take assignment
context into account for inference. AIUI we currently don't and it is
something I want.

I wouldn't want to confidently state that this is something we should or
should not do.

On Tue, Oct 24, 2023 at 5:01 PM tapi...@gmail.com 
wrote:

> My another surprise is that the below partial instantiation doesn't work.
>
> s = slices.Insert[[]Suiter](s, len(s), Clubs{}) // not work
> s = slices.Insert[[]Suiter, Suiter](s, len(s), Clubs{}) // works
>
> On Monday, October 23, 2023 at 11:01:47 AM UTC+8 tapi...@gmail.com wrote:
>
>> On Monday, October 23, 2023 at 10:38:59 AM UTC+8 tapi...@gmail.com wrote:
>>
>> Sorry, I didn't look your full code.
>> I think the full code should work with Go toolchain 1.21.n.
>>
>>
>> Aha, it actually doesn't. I'm surprised.
>>
>>
>> On Sunday, October 22, 2023 at 4:40:55 PM UTC+8 Mike Schinkel wrote:
>>
>> How so?
>>
>> Can you give an example scenario where it could cause unintended
>> consequences?  Or some other negative?
>>
>> -Mike
>>
>> On Saturday, October 21, 2023 at 11:57:52 PM UTC-4 tapi...@gmail.com
>> wrote:
>>
>>
>> It is hard to call such type inference better. That is too aggressive.
>>
>> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/7bd4727b-46ec-4972-b9a3-f7271892bff5n%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/CAEkBMfEWgAvSqqL5mSr-Nf%2B5P%2BNkOA%2BCSbt8fi%3DRuJYKiZfYVA%40mail.gmail.com.


Re: [go-nuts] Can Generics match implementers of an interface?

2023-10-21 Thread &#x27;Axel Wagner&#x27; via golang-nuts
This is purely a type-inference problem. If you explicitly instantiate
`Append`, it works: https://goplay.tools/snippet/15RFAPFPl3y
Type inference is still relatively limited. It might become possible to at
some point omit the instantiation. I think this might be "Inferring based
on interfaces" in https://github.com/golang/go/issues/58650
Until then, it's expected that there will be some cases where you need to
specify the types.

On Sat, Oct 21, 2023 at 9:45 PM Mike Schinkel  wrote:

> No, that pre-generics case is not sufficient for my use-case.
>
> For my use-case I need to be able to use other types besides []Suiter such
> as []int, e.g.:
>
> var n []int
> n = Append(n, 1)
> n = Append(n, 2)
> n = Append(n, 3)
> n = Append(n, 4)
> for _, i := range n {
> fmt.Printf("Int: %d\n", i)
> }
>
> See full code in playground .
> On Saturday, October 21, 2023 at 3:15:03 PM UTC-4 Dan Kortschak wrote:
>
>> On Sat, 2023-10-21 at 11:58 -0700, Mike Schinkel wrote:
>> > Recently I was trying to write a func using generics where I wanted
>> > to use a slice of an interface that would contain implementers of
>> > that interface and then pass those types to a generic function, but I
>> > ran into this error:
>> >
>> > type MyStruct of MySlice{} does not match inferred type MyInterface
>> > for T
>> >
>> > My code is complex so I wrote the simplest example for this email and
>> > here is part of that code:
>> >
>> > type Suiter interface {
>> > Suit()
>> > }
>> > func Append[T any](s []T, i T) []T {
>> > return append(s, i)
>> > }
>> > func main() {
>> > var s []Suiter
>> >
>> > //CAN GENERICS SUPPORT THIS?
>> > //s = Append(s, Clubs{})
>> > //s = Append(s, Hearts{})
>> > //s = Append(s, Diamonds{})
>> > //s = Append(s, Spades{})
>> >
>> > //VERSUS HAVING TO DO THIS?
>> > s = Append(s, Suiter(Clubs{}))
>> > s = Append(s, Suiter(Hearts{}))
>> > s = Append(s, Suiter(Diamonds{}))
>> > s = Append(s, Suiter(Spades{}))
>> >
>> > for _, suit := range s {
>> > fmt.Printf("Suit: %s\n", suitName(suit))
>> > }
>> > }
>> > The full code is here in a playground.
>> >
>> > Note: My example func Append() makes no sense in real use, I only use
>> > it as it should be an easily understood example to show the syntax I
>> > am trying to illustrate.
>> >
>> > Question: Is there a way to write Append() such that I can call
>> > Append(s, Clubs{}) instead of having to write Append(s,
>> > Suiter(Clubs{}))?
>> >
>> > And if no, is there a chance that in the future Go generics will be
>> > able to support that level of type inference?
>> >
>>
>> The pre-generics language handles this case:
>> https://go.dev/play/p/jaJF7LTSVYe
>>
>> Is there something about your real case that makes this not acceptable?
>>
>> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/805dbd4a-e2a0-426e-b61f-45b9333803f5n%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/CAEkBMfEEBQsMR6RfHMw3nHvr7peq-Mu05X0M55XqZ%3DERVQ5Sbg%40mail.gmail.com.


Re: [go-nuts] Can we not invoke methods on types referring to generics?

2023-10-20 Thread &#x27;Axel Wagner&#x27; via golang-nuts
On Fri, Oct 20, 2023 at 1:07 PM Nurahmadie Nurahmadie 
wrote:

> This statement doesn't feel right to me, one can always do `type NewType
> struct{}` to create genuinely new types, but if you do `type String
> string`, for example, surely you expect String to has `string` value, hence
> there will always be a relationship between them? I might be missing
> something obvious here.
>

I think I distinguish between a type and its representation in my mental
model. A type has a semantic meaning going beyond its representation. And
when I say "a genuinely new type" I mean - in this context - without
implying a subtype-relationship.

For example, we could imagine a world in which we had `type Path string`
and `type FilePath string`, for use with `path` and `path/filepath`,
respectively. They have the same representation (underlying type, in Go's
parlance), but they are semantically different types and they are
semantically different from a `string`. We could imagine `os.Open` to take
a `FilePath` (instead of a `string`) and for `url.URL.Path` to be a `Path`
instead of a `string`. And perhaps the `path` package could use type
parameters to manipulate such paths, like `func Join[P Path|FilePath](p
...P) P` and provide helpers to validate and convert between them, like

func ToSlash(p FilePath) Path
func FromSlash(p Path) FilePath
func Validate(s string) (Path, error)

And we'd hope that this would give us a measure of safety. We would want
the compiler to warn us if we pass a `Path` to `os.Open`, prompting us to
convert and/or validate it first. To me, we certainly would not want the
compiler to just accept us passing one as the other or vice-versa.

Now, it is true that in Go, the representation will imbue some semantic
operations on a type. e.g. the language semi-assumes that a `string` is
UTF-8 encoded text, as demonstrated by `range` and the conversion to
`[]rune`. And part of that is a lack of type-safety, where even with our
types, you could assign an arbitrary string literal to a `FilePath`, for
example. At the end of the day, Go has always been a more practically
minded, than theoretically pure language. But that doesn't disprove the
larger point, that there is an advantage to treating types as semantically
separate entities, regardless of their representation.

The way the language works right now, `type A B` really means "define a new
type A with *the same underlying type* as B". In a way, the actual *type*
`B` is inconsequential, only its representation matters. And perhaps that
was a mistake, because it conflates a type with its representation. Perhaps
we should have required the right-hand side of a type declaration to always
be a type-literal - though that would open up the question of how we deal
with `string`, `int`,… which currently are defined types on equal footing
with what you use a type-declaration for (just that they are predeclared).
Perhaps if a type-declaration would have to be clearer about the fact that
it associates a completely new type with a *representation*, this confusion
would be avoided. But it's not what happened (and TBQH I'm not sure it
would've been better).



>
>
>> But we could imagine having a new form of type declaration, say `type A <
>> B` (syntax only illustrative) that would create a new type `A`, which
>> inherits all methods from `B`, could add its own and which is assignable to
>> `B` (but not vice-versa). We basically would have three kinds of
>> declarations: 1. `type A B`, introducing no subtype relationship between
>> `A` and `B`, 2. `type A < B`, which makes `A` a subtype of `B` and 3. `type
>> A = B`, which makes them identical (and is conveniently equivalent to `A <
>> B` and `B < A`).
>>
>
> I think it's perfectly makes sense if we resort to nominal subtyping given
> the new declaration, but I'm genuinely pondering about the existing
> structural subtyping characteristic instead, and I'm not trying to change
> anything about Go from the discussion. :D
>
>
>> I think this would honestly be fine and perfectly safe. You'd still have
>> to explicitly declare that you want the new type to be a subtype, so you
>> don't get the weak typing of C/C++. And the subtype relationship would only
>> "flow" in one direction, so you can't *arbitrarily* mix them up.
>>
>> Where difficulties would arise is that it naturally leads people to want
>> to subtype from *multiple* types. E.g. it would make sense wanting to do
>>
>> type Quadrilateral [4]Point
>> func (Quadrilateral) Area() float64
>> type Rhombus < Quadrilateral
>> func (Rhombus) Angles() (float64, float64)
>> type Rectangle < Quadrilateral
>> func (Rectangle) Bounds() (min, max Point)
>> type Square < (Rhombus, Rectangle) // again, syntax only illustrative)
>>
>> The issue this creates is that subtype relationships are transitive and
>> in this case would become *path-dependent*. `Square` is a subtype of
>> `Quadrilateral`, but it can get there either via `Rhombus` or via
>> `Rectangle` and it's not clear which w

Re: [go-nuts] Can we not invoke methods on types referring to generics?

2023-10-20 Thread &#x27;Axel Wagner&#x27; via golang-nuts
FWIW I think what OP is ultimately asking about is some form of nominal
subtyping. When they say "automatic upcasting", they refer (I believe) to
what Go calls "assignability", which is in essence a subtype relationship.
So they want to be able to define a new type, that is a subtype of an
existing type, but add some methods to it.

And - controversially, perhaps - I don't think they would be anything
inherently wrong about it. Except that it means we'd have two ways to have
subtyping in the language.

First, I agree with other posters here that it would be bad if `type String
string` would create a subtype relationship between `String` and `string`.
Ultimately, we do want to have the ability to create genuinely new types,
with no relationship between them. It's an important safety mechanism. But
we could imagine having a new form of type declaration, say `type A < B`
(syntax only illustrative) that would create a new type `A`, which inherits
all methods from `B`, could add its own and which is assignable to `B` (but
not vice-versa). We basically would have three kinds of declarations: 1.
`type A B`, introducing no subtype relationship between `A` and `B`, 2.
`type A < B`, which makes `A` a subtype of `B` and 3. `type A = B`, which
makes them identical (and is conveniently equivalent to `A < B` and `B <
A`).

I think this would honestly be fine and perfectly safe. You'd still have to
explicitly declare that you want the new type to be a subtype, so you don't
get the weak typing of C/C++. And the subtype relationship would only
"flow" in one direction, so you can't *arbitrarily* mix them up.

Where difficulties would arise is that it naturally leads people to want to
subtype from *multiple* types. E.g. it would make sense wanting to do

type Quadrilateral [4]Point
func (Quadrilateral) Area() float64
type Rhombus < Quadrilateral
func (Rhombus) Angles() (float64, float64)
type Rectangle < Quadrilateral
func (Rectangle) Bounds() (min, max Point)
type Square < (Rhombus, Rectangle) // again, syntax only illustrative)

The issue this creates is that subtype relationships are transitive and in
this case would become *path-dependent*. `Square` is a subtype of
`Quadrilateral`, but it can get there either via `Rhombus` or via
`Rectangle` and it's not clear which way to get there. This matters if
`Rhombus` or `Rectangle` (or both) start overwriting methods of
`Quadrilateral`. The compiler needs to decide which method to call. Usually
it does that by defining some tie-breaks, e.g. "use the type named first in
the subtype declaration". But there is a lot of implicity there and with
deeper hierarchies, you can get spooky breakages at a distance, if some
type in the middle of the hierarchy does some seemingly harmless change
like overloading a method. Look up "Python Method Resolution Order" for the
kinds of problems that can arise.

Structural subtyping does not have these issues, because the subtype
relationship is completely determined by a subset relationship - in Go's
case, sets of methods of the dynamic type of the interface. And since it
can't override methods, there is no path-dependence - any two methods sets
uniquely determine a maximal common subset and a minimum common superset
and the path from any interface type to any other interface is unique
(structural subtyping is a Lattice
).

I think any kind of subtyping relationship *should* ultimately allow you to
have multiple super types - these kinds of hierarchies are just far too
common to ignore. For example, look at the `io` package - pretty much every
combination of `Reader`, `Writer` and `Closer` has some reasonable use
cases. I also think there are good technical reasons to avoid the
path-dependency pitfall. So it seems to me an easily defensible decision to
use structural subtyping as the primary form of subtype relationship, as it
allows you to have the benefits without the problems.

We could do both (and disallow multiple inheritance for the nominal subtype
relationship). But I also think it's easy to argue that this is redundant
and a bit confusing. And ultimately you *can* express most of the useful
hierarchies, even if you need a bit more boilerplate.

On Fri, Oct 20, 2023 at 8:07 AM Bakul Shah  wrote:

> On Oct 19, 2023, at 9:02 PM, Nurahmadie Nurahmadie 
> wrote:
> >
> > Is it not possible to have both _auto_ downcasting and new method
> binding to work in Go?
>
> What you are suggesting may make things more *convenient* but
> at the same time the potential for accidental mistakes goes
> up. The key is find a happy medium. Not too much discipline,
> not too much freedom!
>
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/BB7C6A9

Re: [go-nuts] Generic "nillable" constraint

2023-10-18 Thread &#x27;Axel Wagner&#x27; via golang-nuts
On Wed, Oct 18, 2023 at 5:24 PM Jon Watte  wrote:

> I think "making all values comparable" is a worse change though (there's a
> reason they aren't comparable!)
>

FTR the proposal was not to make all values comparable, but to make all
values comparable to the predeclared identifier nil - similar to how,
currently, a lot of non-comparable values are comparable to the predeclared
identifier nil.


> and making everything comparable to nil without type qualification is
> better IMO.
>
> Sincerely,
>
> Jon Watte
>
>
> --
> "I find that the harder I work, the more luck I seem to have." -- Thomas
> Jefferson
>
>
> On Tue, Oct 17, 2023 at 10:25 PM Axel Wagner <
> axel.wagner...@googlemail.com> wrote:
>
>> On Wed, Oct 18, 2023 at 6:09 AM Jon Watte  wrote:
>>
>>> Circling back to this, because it came up today again.
>>>
>>> Here's the generic function I want to write. It comes up in a lot of
>>> function composition, which in turn comes up in a lot of interface adapters
>>> and such:
>>>
>>> func maybeAssign[T any](dst *T, src T, name string) {
>>> if *dst != nil { // any can't be compared with nil
>>> panic(fmt.Errorf("too many %s arguments", name))
>>> }
>>> *dst = src
>>> }
>>>
>>> Using this function in each assignment, instead of inlining the
>>> four-line construct with panic, can save a lot of space and make code a lot
>>> more readable.
>>> The above doesn't work, because not every type can be assigned nil.
>>> The following also doesn't work:
>>>
>>> func maybeAssign[T comparable](dst *T, src T, name string) {
>>> var zero T
>>> if *dst != zero { // interface and other nillable types can't be
>>> compared to zero
>>> panic(fmt.Errorf("too many %s arguments", name))
>>> }
>>> *dst = src
>>> }
>>>
>>> Because interface values aren't comparable. (As aren't chans, maps, etc,
>>> but THOSE can be jammed into various interface constructs, whereas "any
>>> interface" cannot, because "interface{}" doesn't actually mean "any
>>> interface")
>>>
>>> Let me try to answer:
>>>
>>> > Why is the *specific* split into (interfaces, pointers, slices,
>>> functions, maps, channels) and (numbers, booleans, strings, structs,
>>> arrays) a particularly important one?
>>>
>>> Because, while go tries very hard to make sure every storable type has a
>>> "zero value," it somehow decides that you can't necessarily COMPARE to that
>>> zero value.
>>> But the whole point of zero values is that you can tell them from
>>> non-zero values!
>>> So, the language has introduced a work-around with the concept of "I can
>>> compare to nil" for these reference types that aren't comparable to their
>>> zero value.
>>> But generics don't allow us to sense or make use of this, so generics
>>> can't express what the regular language can express. Even a very simple
>>> case like the above, can't currently be expressed, and this leads to more
>>> verbose code that's harder to read and harder to work with. (Granted, this
>>> is my opinion, but I'm not alone.)
>>>
>>
>> That does not actually answer the question, though. Again, note that your
>> problem would be solved both by #61372
>>  (you could write `if *dst !=
>> zero`) and by #62487  (you
>> could just write `if *dst != nil`), neither of which require you to make a
>> distinction between "nilable" types and "non-nilable" types. In fact, it
>> would make your `maybeAssign` function worse - it would be less general,
>> because it could only be used with a subset of types and it's not clear why
>> that subset is a good one.
>>
>> (also, nit: channels are comparable)
>>
>> If the language instead changes so that nil means "the zero value" in
>>> general, and it so happens that these nil-comparable types can be compared
>>> to nil without any particular qualification, that also solves the problem.
>>>
>>
>> Right. That is what my question was getting at.
>>
>>
>>> That might indeed be a good solution -- but if so, it'd be nice to know
>>> what we can do to make that happen, and what the other opposition to that
>>> change might be, because that change also feels much less narrow than a
>>> "nil" type constraint.
>>>
>>
>> Being "less narrow" can mean two things: It can mean "it is a more
>> general solution" and it can mean "it is a bigger change". The two
>> proposals above are a similarly big change, that are more general in the
>> kinds of problems they solve. So they seem better.
>>
>>
>>>
>>>
>>> Sincerely,
>>>
>>> Jon Watte
>>>
>>>
>>> --
>>> "I find that the harder I work, the more luck I seem to have." --
>>> Thomas Jefferson
>>>
>>>
>>> On Tue, Oct 3, 2023 at 10:41 PM Axel Wagner <
>>> axel.wagner...@googlemail.com> wrote:
>>>
 Oh (sorry, being forgetful) and re "it's less of a new mechanism than
 introducing a zero identifier": #62487
  introduces *even less* new
 mechanism, by expanding comparison t

Re: [go-nuts] Generic "nillable" constraint

2023-10-17 Thread &#x27;Axel Wagner&#x27; via golang-nuts
On Wed, Oct 18, 2023 at 6:09 AM Jon Watte  wrote:

> Circling back to this, because it came up today again.
>
> Here's the generic function I want to write. It comes up in a lot of
> function composition, which in turn comes up in a lot of interface adapters
> and such:
>
> func maybeAssign[T any](dst *T, src T, name string) {
> if *dst != nil { // any can't be compared with nil
> panic(fmt.Errorf("too many %s arguments", name))
> }
> *dst = src
> }
>
> Using this function in each assignment, instead of inlining the four-line
> construct with panic, can save a lot of space and make code a lot more
> readable.
> The above doesn't work, because not every type can be assigned nil.
> The following also doesn't work:
>
> func maybeAssign[T comparable](dst *T, src T, name string) {
> var zero T
> if *dst != zero { // interface and other nillable types can't be
> compared to zero
> panic(fmt.Errorf("too many %s arguments", name))
> }
> *dst = src
> }
>
> Because interface values aren't comparable. (As aren't chans, maps, etc,
> but THOSE can be jammed into various interface constructs, whereas "any
> interface" cannot, because "interface{}" doesn't actually mean "any
> interface")
>
> Let me try to answer:
>
> > Why is the *specific* split into (interfaces, pointers, slices,
> functions, maps, channels) and (numbers, booleans, strings, structs,
> arrays) a particularly important one?
>
> Because, while go tries very hard to make sure every storable type has a
> "zero value," it somehow decides that you can't necessarily COMPARE to that
> zero value.
> But the whole point of zero values is that you can tell them from non-zero
> values!
> So, the language has introduced a work-around with the concept of "I can
> compare to nil" for these reference types that aren't comparable to their
> zero value.
> But generics don't allow us to sense or make use of this, so generics
> can't express what the regular language can express. Even a very simple
> case like the above, can't currently be expressed, and this leads to more
> verbose code that's harder to read and harder to work with. (Granted, this
> is my opinion, but I'm not alone.)
>

That does not actually answer the question, though. Again, note that your
problem would be solved both by #61372
 (you could write `if *dst !=
zero`) and by #62487  (you could
just write `if *dst != nil`), neither of which require you to make a
distinction between "nilable" types and "non-nilable" types. In fact, it
would make your `maybeAssign` function worse - it would be less general,
because it could only be used with a subset of types and it's not clear why
that subset is a good one.

(also, nit: channels are comparable)

If the language instead changes so that nil means "the zero value" in
> general, and it so happens that these nil-comparable types can be compared
> to nil without any particular qualification, that also solves the problem.
>

Right. That is what my question was getting at.


> That might indeed be a good solution -- but if so, it'd be nice to know
> what we can do to make that happen, and what the other opposition to that
> change might be, because that change also feels much less narrow than a
> "nil" type constraint.
>

Being "less narrow" can mean two things: It can mean "it is a more general
solution" and it can mean "it is a bigger change". The two proposals above
are a similarly big change, that are more general in the kinds of problems
they solve. So they seem better.


>
>
> Sincerely,
>
> Jon Watte
>
>
> --
> "I find that the harder I work, the more luck I seem to have." -- Thomas
> Jefferson
>
>
> On Tue, Oct 3, 2023 at 10:41 PM Axel Wagner 
> wrote:
>
>> Oh (sorry, being forgetful) and re "it's less of a new mechanism than
>> introducing a zero identifier": #62487
>>  introduces *even less* new
>> mechanism, by expanding comparison to (and assignment of) `nil` to all
>> types inside a generic function. It's not a new class of constraint, it
>> just special-cases `nil` a bit more. So it is still a far more general
>> mechanism, that solves more problems than `nilable` constraint, while
>> requiring fewer (or at worst the same number of) new concepts.
>>
>> On Wed, Oct 4, 2023 at 7:36 AM Axel Wagner 
>> wrote:
>>
>>> (correction: It should be Convert[J isinterface, T J]. I changed the
>>> name from I to J to be more readable and then missed one occurrence)
>>>
>>> On Wed, Oct 4, 2023 at 7:33 AM Axel Wagner <
>>> axel.wagner...@googlemail.com> wrote:
>>>
 On Wed, Oct 4, 2023 at 6:54 AM Jon Watte  wrote:

> > where it is important to permit only type arguments that can be
> compared to nil
>
> I see! As in, if we somehow got a "equalszero" constraint, then that
> constraint would solve the problem I illustrate.
> I believe that assertion is correct, but I a

Re: [go-nuts] ResponseRecorder HTTP status code defaults to 200

2023-10-17 Thread &#x27;Axel Wagner&#x27; via golang-nuts
It is not "meant for tests internal to the http package". It's meant for
tests of users of the `net/http` package. That is, implementations of the
`http.Handler` interface.
In the context of the standard library, that is what "general purpose HTTP
testing" means.

On Tue, Oct 17, 2023 at 10:44 AM Simon Walter  wrote:

> It is good practice to use test lang/tools/libs/etc different from what
> you are using in your actual code.
>
> If the author has meant for the httptest package as general purpose HTTP
> testing library, then, I will argue that such defaults are incorrect. It is
> incorrect even if the intended purpose is to tests code that is derived
> from http package.
>
> If the author has meant for the httptest package to be used for tests
> internal to the http package, then it should be labeled such.
>
> I'll mention this to bradf...@golang.org.
> On Monday, October 16, 2023 at 4:58:16 PM UTC+2 Axel Wagner wrote:
>
>> To be clear: The behavior of an `http.ResponseWriter` to implicitly use a
>> 200 status code if no explicit WriteHeader call is made is documented:
>> https://pkg.go.dev/net/http#ResponseWriter.WriteHeader
>> I really think it is a bad (or at least strange) idea to claim to
>> implement `http.ResponseWriter` while *not* replicating this behavior.
>>
>> On Mon, Oct 16, 2023 at 4:53 PM Axel Wagner 
>> wrote:
>>
>>> It seems to me that the fact that the functions accept and return types
>>> from `net/http` (like `http.ResponseWriter` and `http.Handler`) and given
>>> that it's nested below `net/http` should make it fairly obvious that it's
>>> meant to be used with `net/http`. I also genuinely don't understand what
>>> the intersection is of "being tempted to use `httptest`" and "does not
>>> intend to be used with `net/http`". I also genuinely don't understand how
>>> the behavior of `httptest` could ever cause any harm (quite the opposite).
>>>
>>> But, YMMV, of course and you are free to roll your own testing helpers.
>>>
>>> On Mon, Oct 16, 2023 at 9:30 AM Simon Walter  wrote:
>>>
 Axel, thanks for providing some context.

 I suppose it is better for me to think of the httptest package as
 specific to the http package - although this is not explicitly stated:
 "Package httptest provides utilities for HTTP testing"

 This seems misleading as is the case with this '200' default.

 I stopped using httptest.NewRecorder() because of the possibility to
 introduce changes to tests that would make tests pass. Not everyone knows
 the internals of all the code. Because of this, I think it is risky to have
 values set by default to the value that causes the test to pass.

 Some questions that should not keep us awake at night: The test passed,
 but will it fail? Will it fail where/how I think it will?

 Simon

 On Monday, October 16, 2023 at 6:16:41 AM UTC+2 Axel Wagner wrote:

> If you want to argue that `net/http` should not set the response code
> to 200 by default, I would be inclined to agree. I don't particularly like
> that the API even *allows* you not to explicitly set a response code. But
> it does. And while it does, the best test is one that matches the behavior
> of the production environment as closely as possible, full stop.
>
> Another way to look at it: Why do you believe you have to test that
> your handler sets the response code to 200? Why should the test fail, if 
> it
> doesn't do it - given that *the production code* will still end up with 
> the
> right response code? If the response sent to the user is the right one -
> why would it matter whether it was your Handler that set it, or the
> framework?
>
> On Sun, Oct 15, 2023 at 10:22 PM Simon Walter 
> wrote:
>
>> How does that explain why it is a good idea?
>>
>> Perhaps my concern is not clear enough.
>>
>> For example:
>>
>> n := 5
>> funcThatShouldSetNtoFive(&n)
>> if n != 5 {
>>   panic("n is not 5)
>> }
>>
>> This is not a good test.
>>
>> I can check if the value has changed by:
>>
>> n := 0
>> funcThatShouldSetNtoFive(&n)
>> if n != 5 {
>>   panic("n is not 5)
>> }
>>
>> That's a bit more sensible.
>>
>> Wouldn't it be less risky for a test to fail by default? Removal of
>> the call to funcThatShouldSetNtoFive, IMO, should result in failure.
>>
>> On Sunday, October 15, 2023 at 6:10:36 PM UTC+2 Axel Wagner wrote:
>>
>>> A default `net/http` server also uses 200 as the default response
>>> code. The behavior of an `http.Handler` not setting a response code 
>>> should
>>> be the same, if it uses `httptest`, as if it uses `net/http`.
>>>
>>> On Sun, Oct 15, 2023 at 5:17 PM Simon Walter 
>>> wrote:
>>>
 Hi all,

 What is the reason that ResponseRecorder HTTP status code defaults
 to 200?
>>>

Re: [go-nuts] ResponseRecorder HTTP status code defaults to 200

2023-10-16 Thread &#x27;Axel Wagner&#x27; via golang-nuts
To be clear: The behavior of an `http.ResponseWriter` to implicitly use a
200 status code if no explicit WriteHeader call is made is documented:
https://pkg.go.dev/net/http#ResponseWriter.WriteHeader
I really think it is a bad (or at least strange) idea to claim to implement
`http.ResponseWriter` while *not* replicating this behavior.

On Mon, Oct 16, 2023 at 4:53 PM Axel Wagner 
wrote:

> It seems to me that the fact that the functions accept and return types
> from `net/http` (like `http.ResponseWriter` and `http.Handler`) and given
> that it's nested below `net/http` should make it fairly obvious that it's
> meant to be used with `net/http`. I also genuinely don't understand what
> the intersection is of "being tempted to use `httptest`" and "does not
> intend to be used with `net/http`". I also genuinely don't understand how
> the behavior of `httptest` could ever cause any harm (quite the opposite).
>
> But, YMMV, of course and you are free to roll your own testing helpers.
>
> On Mon, Oct 16, 2023 at 9:30 AM Simon Walter  wrote:
>
>> Axel, thanks for providing some context.
>>
>> I suppose it is better for me to think of the httptest package as
>> specific to the http package - although this is not explicitly stated:
>> "Package httptest provides utilities for HTTP testing"
>>
>> This seems misleading as is the case with this '200' default.
>>
>> I stopped using httptest.NewRecorder() because of the possibility to
>> introduce changes to tests that would make tests pass. Not everyone knows
>> the internals of all the code. Because of this, I think it is risky to have
>> values set by default to the value that causes the test to pass.
>>
>> Some questions that should not keep us awake at night: The test passed,
>> but will it fail? Will it fail where/how I think it will?
>>
>> Simon
>>
>> On Monday, October 16, 2023 at 6:16:41 AM UTC+2 Axel Wagner wrote:
>>
>>> If you want to argue that `net/http` should not set the response code to
>>> 200 by default, I would be inclined to agree. I don't particularly like
>>> that the API even *allows* you not to explicitly set a response code. But
>>> it does. And while it does, the best test is one that matches the behavior
>>> of the production environment as closely as possible, full stop.
>>>
>>> Another way to look at it: Why do you believe you have to test that your
>>> handler sets the response code to 200? Why should the test fail, if it
>>> doesn't do it - given that *the production code* will still end up with the
>>> right response code? If the response sent to the user is the right one -
>>> why would it matter whether it was your Handler that set it, or the
>>> framework?
>>>
>>> On Sun, Oct 15, 2023 at 10:22 PM Simon Walter 
>>> wrote:
>>>
 How does that explain why it is a good idea?

 Perhaps my concern is not clear enough.

 For example:

 n := 5
 funcThatShouldSetNtoFive(&n)
 if n != 5 {
   panic("n is not 5)
 }

 This is not a good test.

 I can check if the value has changed by:

 n := 0
 funcThatShouldSetNtoFive(&n)
 if n != 5 {
   panic("n is not 5)
 }

 That's a bit more sensible.

 Wouldn't it be less risky for a test to fail by default? Removal of the
 call to funcThatShouldSetNtoFive, IMO, should result in failure.

 On Sunday, October 15, 2023 at 6:10:36 PM UTC+2 Axel Wagner wrote:

> A default `net/http` server also uses 200 as the default response
> code. The behavior of an `http.Handler` not setting a response code should
> be the same, if it uses `httptest`, as if it uses `net/http`.
>
> On Sun, Oct 15, 2023 at 5:17 PM Simon Walter 
> wrote:
>
>> Hi all,
>>
>> What is the reason that ResponseRecorder HTTP status code defaults to
>> 200?
>>
>>
>> https://cs.opensource.google/go/go/+/refs/tags/go1.21.3:src/net/http/httptest/recorder.go;drc=ff14e844d26090e09aa335d836f737c09a7a0402;l=55
>>
>>
>> https://cs.opensource.google/go/go/+/refs/tags/go1.21.3:src/net/http/httptest/recorder.go;drc=ff14e844d26090e09aa335d836f737c09a7a0402;l=196
>>
>> Can someone explain to me why this is a good idea? Would it not make
>> more sense to set it to a value that is not a valid HTTP response code 
>> such
>> as 0?
>>
>> Simon
>>
>> --
>> You received this message because you are subscribed 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/321a84fa-3aeb-4f3a-ba4f-a05e797652d6n%40googlegroups.com
>> 
>> .
>>
> --
 You received this message because you are 

Re: [go-nuts] ResponseRecorder HTTP status code defaults to 200

2023-10-16 Thread &#x27;Axel Wagner&#x27; via golang-nuts
It seems to me that the fact that the functions accept and return types
from `net/http` (like `http.ResponseWriter` and `http.Handler`) and given
that it's nested below `net/http` should make it fairly obvious that it's
meant to be used with `net/http`. I also genuinely don't understand what
the intersection is of "being tempted to use `httptest`" and "does not
intend to be used with `net/http`". I also genuinely don't understand how
the behavior of `httptest` could ever cause any harm (quite the opposite).

But, YMMV, of course and you are free to roll your own testing helpers.

On Mon, Oct 16, 2023 at 9:30 AM Simon Walter  wrote:

> Axel, thanks for providing some context.
>
> I suppose it is better for me to think of the httptest package as specific
> to the http package - although this is not explicitly stated: "Package
> httptest provides utilities for HTTP testing"
>
> This seems misleading as is the case with this '200' default.
>
> I stopped using httptest.NewRecorder() because of the possibility to
> introduce changes to tests that would make tests pass. Not everyone knows
> the internals of all the code. Because of this, I think it is risky to have
> values set by default to the value that causes the test to pass.
>
> Some questions that should not keep us awake at night: The test passed,
> but will it fail? Will it fail where/how I think it will?
>
> Simon
>
> On Monday, October 16, 2023 at 6:16:41 AM UTC+2 Axel Wagner wrote:
>
>> If you want to argue that `net/http` should not set the response code to
>> 200 by default, I would be inclined to agree. I don't particularly like
>> that the API even *allows* you not to explicitly set a response code. But
>> it does. And while it does, the best test is one that matches the behavior
>> of the production environment as closely as possible, full stop.
>>
>> Another way to look at it: Why do you believe you have to test that your
>> handler sets the response code to 200? Why should the test fail, if it
>> doesn't do it - given that *the production code* will still end up with the
>> right response code? If the response sent to the user is the right one -
>> why would it matter whether it was your Handler that set it, or the
>> framework?
>>
>> On Sun, Oct 15, 2023 at 10:22 PM Simon Walter  wrote:
>>
>>> How does that explain why it is a good idea?
>>>
>>> Perhaps my concern is not clear enough.
>>>
>>> For example:
>>>
>>> n := 5
>>> funcThatShouldSetNtoFive(&n)
>>> if n != 5 {
>>>   panic("n is not 5)
>>> }
>>>
>>> This is not a good test.
>>>
>>> I can check if the value has changed by:
>>>
>>> n := 0
>>> funcThatShouldSetNtoFive(&n)
>>> if n != 5 {
>>>   panic("n is not 5)
>>> }
>>>
>>> That's a bit more sensible.
>>>
>>> Wouldn't it be less risky for a test to fail by default? Removal of the
>>> call to funcThatShouldSetNtoFive, IMO, should result in failure.
>>>
>>> On Sunday, October 15, 2023 at 6:10:36 PM UTC+2 Axel Wagner wrote:
>>>
 A default `net/http` server also uses 200 as the default response code.
 The behavior of an `http.Handler` not setting a response code should be the
 same, if it uses `httptest`, as if it uses `net/http`.

 On Sun, Oct 15, 2023 at 5:17 PM Simon Walter 
 wrote:

> Hi all,
>
> What is the reason that ResponseRecorder HTTP status code defaults to
> 200?
>
>
> https://cs.opensource.google/go/go/+/refs/tags/go1.21.3:src/net/http/httptest/recorder.go;drc=ff14e844d26090e09aa335d836f737c09a7a0402;l=55
>
>
> https://cs.opensource.google/go/go/+/refs/tags/go1.21.3:src/net/http/httptest/recorder.go;drc=ff14e844d26090e09aa335d836f737c09a7a0402;l=196
>
> Can someone explain to me why this is a good idea? Would it not make
> more sense to set it to a value that is not a valid HTTP response code 
> such
> as 0?
>
> Simon
>
> --
> You received this message because you are subscribed 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/321a84fa-3aeb-4f3a-ba4f-a05e797652d6n%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 discussion on the web visit
>>> https://groups.google.com/d/msgid/golang-nuts/df053fb7-70bf-483d-afd6-4caee9937aa6n%40googlegroups.com
>>> 
>>> .
>>>
>> --
> You received this m

Re: [go-nuts] ResponseRecorder HTTP status code defaults to 200

2023-10-15 Thread &#x27;Axel Wagner&#x27; via golang-nuts
If you want to argue that `net/http` should not set the response code to
200 by default, I would be inclined to agree. I don't particularly like
that the API even *allows* you not to explicitly set a response code. But
it does. And while it does, the best test is one that matches the behavior
of the production environment as closely as possible, full stop.

Another way to look at it: Why do you believe you have to test that your
handler sets the response code to 200? Why should the test fail, if it
doesn't do it - given that *the production code* will still end up with the
right response code? If the response sent to the user is the right one -
why would it matter whether it was your Handler that set it, or the
framework?

On Sun, Oct 15, 2023 at 10:22 PM Simon Walter  wrote:

> How does that explain why it is a good idea?
>
> Perhaps my concern is not clear enough.
>
> For example:
>
> n := 5
> funcThatShouldSetNtoFive(&n)
> if n != 5 {
>   panic("n is not 5)
> }
>
> This is not a good test.
>
> I can check if the value has changed by:
>
> n := 0
> funcThatShouldSetNtoFive(&n)
> if n != 5 {
>   panic("n is not 5)
> }
>
> That's a bit more sensible.
>
> Wouldn't it be less risky for a test to fail by default? Removal of the
> call to funcThatShouldSetNtoFive, IMO, should result in failure.
>
> On Sunday, October 15, 2023 at 6:10:36 PM UTC+2 Axel Wagner wrote:
>
>> A default `net/http` server also uses 200 as the default response code.
>> The behavior of an `http.Handler` not setting a response code should be the
>> same, if it uses `httptest`, as if it uses `net/http`.
>>
>> On Sun, Oct 15, 2023 at 5:17 PM Simon Walter  wrote:
>>
>>> Hi all,
>>>
>>> What is the reason that ResponseRecorder HTTP status code defaults to
>>> 200?
>>>
>>>
>>> https://cs.opensource.google/go/go/+/refs/tags/go1.21.3:src/net/http/httptest/recorder.go;drc=ff14e844d26090e09aa335d836f737c09a7a0402;l=55
>>>
>>>
>>> https://cs.opensource.google/go/go/+/refs/tags/go1.21.3:src/net/http/httptest/recorder.go;drc=ff14e844d26090e09aa335d836f737c09a7a0402;l=196
>>>
>>> Can someone explain to me why this is a good idea? Would it not make
>>> more sense to set it to a value that is not a valid HTTP response code such
>>> as 0?
>>>
>>> Simon
>>>
>>> --
>>> You received this message because you are subscribed 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/321a84fa-3aeb-4f3a-ba4f-a05e797652d6n%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/df053fb7-70bf-483d-afd6-4caee9937aa6n%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/CAEkBMfEq0Du--r2oGbxF73JujHr1aLz8kDAqic7B6Eo0FpEZDw%40mail.gmail.com.


Re: [go-nuts] ResponseRecorder HTTP status code defaults to 200

2023-10-15 Thread &#x27;Axel Wagner&#x27; via golang-nuts
A default `net/http` server also uses 200 as the default response code. The
behavior of an `http.Handler` not setting a response code should be the
same, if it uses `httptest`, as if it uses `net/http`.

On Sun, Oct 15, 2023 at 5:17 PM Simon Walter  wrote:

> Hi all,
>
> What is the reason that ResponseRecorder HTTP status code defaults to 200?
>
>
> https://cs.opensource.google/go/go/+/refs/tags/go1.21.3:src/net/http/httptest/recorder.go;drc=ff14e844d26090e09aa335d836f737c09a7a0402;l=55
>
>
> https://cs.opensource.google/go/go/+/refs/tags/go1.21.3:src/net/http/httptest/recorder.go;drc=ff14e844d26090e09aa335d836f737c09a7a0402;l=196
>
> Can someone explain to me why this is a good idea? Would it not make more
> sense to set it to a value that is not a valid HTTP response code such as 0?
>
> Simon
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/321a84fa-3aeb-4f3a-ba4f-a05e797652d6n%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/CAEkBMfG88A7dw2G8B_K%2B5TXjpS68Dxpg8opJu687wQgp%2B%3D68Zw%40mail.gmail.com.


Re: [go-nuts] Re: Why causes []any trouble in type equations?

2023-10-11 Thread &#x27;Axel Wagner&#x27; via golang-nuts
On Wed, Oct 11, 2023 at 8:11 PM Torsten Bronger <
bron...@physik.rwth-aachen.de> wrote:

> Then, all boils down to the fact that you can’t pass []float64 as an
> []any.  To be honest, I still don’t fully understand why this is
> forbidden


What would this do?

func F(s []any) {
s[0] = "Foo"
}
func main() {
s := []int{1,2,3,4}
F(s)
fmt.Println(s)
}



> , so I just accept that the language does not allow it.
>
> Thanks to both of you!
>
> Regards,
> Torsten.
>
> --
> Torsten Bronger
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/87il7dni96.fsf%40physik.rwth-aachen.de
> .
>

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


Re: [go-nuts] Re: Why causes []any trouble in type equations?

2023-10-10 Thread &#x27;Axel Wagner&#x27; via golang-nuts
In the first example, the inferred type is `float64`, so the signature of
the function is `func do([]float64)`. You can obviously pass a `[]float64`
to it.
If X is a concrete (i.e. non-interface) type, then `func F[T X]()` is
syntactic sugar for `func F[T interface{ X }]()`, which is a constraint
that has a single union-element and that union-element lists a single type.
So `func do[T []any](v T)` allows to instantiate the function with only a
single type: `[]any`. Because `[]any` is not an interface type.
And you can't pass a `[]float64` to a function accepting an `[]any`,
because slices are invariant.
The two signatures really mean completely different things. Writing `func
do[S []E, E any]` really means "S has type []E, where E can be any type",
which is a very different thing from saying "it's a slice of the specific
type any".

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


Re: [go-nuts] Why causes []any trouble in type equations?

2023-10-10 Thread &#x27;Axel Wagner&#x27; via golang-nuts
In the second case, the type argument is inferred to be `[]float64`. The
constraint on `T` in `do` is that it has to be `[]any`. `[]float64` is not
`[]any`, the two are different types, so instantiation fails.
Note that even if you explicitly instantiate `do` to `[]any`, you still
could not pass a `[]float64` to it. That's because slices are invariant in
Go, for good reasons
.

On Tue, Oct 10, 2023 at 9:01 AM Torsten Bronger <
bron...@physik.rwth-aachen.de> wrote:

> Hallöchen!
>
> The two most recent Go blog articles make we wonder why
>
> package main
>
> func do[T []E, E any](slice T) {
> }
>
> func main() {
> var a []float64
> do(a)
> }
>
> is valid while
>
> package main
>
> func do[T []any](slice T) {
> }
>
> func main() {
> var a []float64
> do(a)
> }
>
> is not.  The error message doe not help me.  Can someone explain
> this?  Thank you!
>
> Regards,
> Torsten.
>
> --
> Torsten Bronger
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/87bkd7nern.fsf%40physik.rwth-aachen.de
> .
>

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


Re: [go-nuts] The docs for secretbox seem very wrong

2023-10-09 Thread &#x27;Axel Wagner&#x27; via golang-nuts
I get the impression that the thing you are missing is that appending to a
slice does not modify it. That is, `append(s, x...)` modifies neither the
length, nor the content of `s`, you have to type `x = append(s, x...)`.
`Seal` (and `Open`) work exactly the same. They append to the `out`
parameter - and to enable you to get at the slice, they return it.
The docs could be slightly more clear, by explicitly stating that they
return the appended-to slice.0

On Mon, Oct 9, 2023 at 3:46 PM Dean Schulze 
wrote:

> If the docs are correct, how do you append to nil?  That's what the docs
> say.  Take a look at them.
>
> Your code example shows the first parameter to Seal() can be nil.  So what
> does that parameter do?  How do you append to it?
>
> On Sunday, October 8, 2023 at 11:19:13 PM UTC-6 Axel Wagner wrote:
>
>> For what it's worth, here is an example that demonstrates a typical
>> encryption/decryption roundtrip, perhaps more clearly:
>> https://go.dev/play/p/ZZry8IgTJQ_-
>> The `out` parameter can be used to make this more efficient by using
>> pre-allocated buffers (depending on use case) and there are cases where you
>> don't have to send the nonce, because you can derive them from common data,
>> which is why both of these parameters are there. But in the most common
>> usage, you'd do what this example does.
>>
>> The example code from the docs tries to be a little bit more efficient
>> and packs the `Box` struct into a single byte, perhaps at the cost of
>> understandability.
>>
>> On Mon, Oct 9, 2023 at 7:06 AM Axel Wagner 
>> wrote:
>>
>>> oh I forgot to emphasize: I don't believe the output is *really*
>>> ``. That is, I don't believe you can really treat
>>> the first N bytes as the encrypted text and decrypt it (say, if you didn't
>>> care about the authentication). It's just that you ultimately need to add
>>> 16 bytes of extra information to carry that authentication tag, which is
>>> why the box needs to be 16 bytes longer than the message. In reality, the
>>> two are probably cleverly mixed - I'm not a cryptographer.
>>> I just wanted to demonstrate where all the information ultimately goes.
>>>
>>> On Mon, Oct 9, 2023 at 7:03 AM Axel Wagner 
>>> wrote:
>>>
 I don't really understand your issue. You call
 encrypted := secretbox.Seal(nonce[:], []byte(s), &nonce, &secretKey)
 That means you pass `nonce[:]` as the `out` argument, `s` as the
 `message` argument, and the nonce and key and assign the result to
 `encrypted`.
 According to the docs of `secretbox`, `Seal` will `append` the
 encrypted message to `nonce[:]` and that encrypted message will be 16 bytes
 longer than the message, which is 11 bytes long. Appending 37 (16+11) bytes
 to a 24 byte nonce gives you 51 bytes, which is what you observe as the
 length of `encrypted`.
 The length of `nonce` doesn't change (it's an array, after all) - but
 passing `append` to a slice does not change the length of the slice, it
 just returns a new slice, so that seems expected.

 So, from what I can tell, the code does exactly what the docs say it
 should do.

 > In their example code the out parameter is nil.  So what does it do?

 Appending to `nil` allocates a new slice. The point of still accepting
 an `out` parameter is that you can potentially prevent an allocation by
 passing in a slice with 0 length and extra capacity (which can then be
 allocated on the stack, or which is from a `sync.Pool`). If you don't need
 that, passing in `nil` seems fine.

 > The second argument is encrypted[len(nonce):] which includes the
 Overhead at the start of the []byte. Apparently that Overhead is important.

 Yes, the Overhead is important. It is used to authenticate the message.
 You can imagine the process of `Seal` as "encrypt the message and attach a
 hash". The hash is the Overhead. The process also needs a random `nonce`,
 that both the sender and the receiver need to know. That's why the example
 code sends it along with the message (it doesn't have to be secret). So
 that `Seal` call does, effectively (again, for illustrative purposes):
 encrypted := append(append(nonce, ), )
 As `nonce` is an array, this allocates a new backing array for the
 returned slice, which ends up filled with
 

 The `Open` call then retrieves the `nonce` from the first 24 bytes (by
 copying it into `decryptNonce`) and passes the ``
 slice as the `box` argument. Which decrypts the message, authenticates the
 hash and appends the decrypted message to `out` (which is `nil` in the
 example code).

 So, the docs are correct. And it seems to me, the code works as
 expected. I'm not sure where the misunderstanding is.

>>> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send 

Re: [go-nuts] The docs for secretbox seem very wrong

2023-10-08 Thread &#x27;Axel Wagner&#x27; via golang-nuts
For what it's worth, here is an example that demonstrates a typical
encryption/decryption roundtrip, perhaps more clearly:
https://go.dev/play/p/ZZry8IgTJQ_-
The `out` parameter can be used to make this more efficient by using
pre-allocated buffers (depending on use case) and there are cases where you
don't have to send the nonce, because you can derive them from common data,
which is why both of these parameters are there. But in the most common
usage, you'd do what this example does.

The example code from the docs tries to be a little bit more efficient and
packs the `Box` struct into a single byte, perhaps at the cost of
understandability.

On Mon, Oct 9, 2023 at 7:06 AM Axel Wagner 
wrote:

> oh I forgot to emphasize: I don't believe the output is *really*
> ``. That is, I don't believe you can really treat
> the first N bytes as the encrypted text and decrypt it (say, if you didn't
> care about the authentication). It's just that you ultimately need to add
> 16 bytes of extra information to carry that authentication tag, which is
> why the box needs to be 16 bytes longer than the message. In reality, the
> two are probably cleverly mixed - I'm not a cryptographer.
> I just wanted to demonstrate where all the information ultimately goes.
>
> On Mon, Oct 9, 2023 at 7:03 AM Axel Wagner 
> wrote:
>
>> I don't really understand your issue. You call
>> encrypted := secretbox.Seal(nonce[:], []byte(s), &nonce, &secretKey)
>> That means you pass `nonce[:]` as the `out` argument, `s` as the
>> `message` argument, and the nonce and key and assign the result to
>> `encrypted`.
>> According to the docs of `secretbox`, `Seal` will `append` the encrypted
>> message to `nonce[:]` and that encrypted message will be 16 bytes longer
>> than the message, which is 11 bytes long. Appending 37 (16+11) bytes to a
>> 24 byte nonce gives you 51 bytes, which is what you observe as the length
>> of `encrypted`.
>> The length of `nonce` doesn't change (it's an array, after all) - but
>> passing `append` to a slice does not change the length of the slice, it
>> just returns a new slice, so that seems expected.
>>
>> So, from what I can tell, the code does exactly what the docs say it
>> should do.
>>
>> > In their example code the out parameter is nil.  So what does it do?
>>
>> Appending to `nil` allocates a new slice. The point of still accepting an
>> `out` parameter is that you can potentially prevent an allocation by
>> passing in a slice with 0 length and extra capacity (which can then be
>> allocated on the stack, or which is from a `sync.Pool`). If you don't need
>> that, passing in `nil` seems fine.
>>
>> > The second argument is encrypted[len(nonce):] which includes the
>> Overhead at the start of the []byte. Apparently that Overhead is important.
>>
>> Yes, the Overhead is important. It is used to authenticate the message.
>> You can imagine the process of `Seal` as "encrypt the message and attach a
>> hash". The hash is the Overhead. The process also needs a random `nonce`,
>> that both the sender and the receiver need to know. That's why the example
>> code sends it along with the message (it doesn't have to be secret). So
>> that `Seal` call does, effectively (again, for illustrative purposes):
>> encrypted := append(append(nonce, ), )
>> As `nonce` is an array, this allocates a new backing array for the
>> returned slice, which ends up filled with
>> 
>>
>> The `Open` call then retrieves the `nonce` from the first 24 bytes (by
>> copying it into `decryptNonce`) and passes the ``
>> slice as the `box` argument. Which decrypts the message, authenticates the
>> hash and appends the decrypted message to `out` (which is `nil` in the
>> example code).
>>
>> So, the docs are correct. And it seems to me, the code works as expected.
>> I'm not sure where the misunderstanding is.
>>
>

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


Re: [go-nuts] The docs for secretbox seem very wrong

2023-10-08 Thread &#x27;Axel Wagner&#x27; via golang-nuts
oh I forgot to emphasize: I don't believe the output is *really*
``. That is, I don't believe you can really treat
the first N bytes as the encrypted text and decrypt it (say, if you didn't
care about the authentication). It's just that you ultimately need to add
16 bytes of extra information to carry that authentication tag, which is
why the box needs to be 16 bytes longer than the message. In reality, the
two are probably cleverly mixed - I'm not a cryptographer.
I just wanted to demonstrate where all the information ultimately goes.

On Mon, Oct 9, 2023 at 7:03 AM Axel Wagner 
wrote:

> I don't really understand your issue. You call
> encrypted := secretbox.Seal(nonce[:], []byte(s), &nonce, &secretKey)
> That means you pass `nonce[:]` as the `out` argument, `s` as the `message`
> argument, and the nonce and key and assign the result to `encrypted`.
> According to the docs of `secretbox`, `Seal` will `append` the encrypted
> message to `nonce[:]` and that encrypted message will be 16 bytes longer
> than the message, which is 11 bytes long. Appending 37 (16+11) bytes to a
> 24 byte nonce gives you 51 bytes, which is what you observe as the length
> of `encrypted`.
> The length of `nonce` doesn't change (it's an array, after all) - but
> passing `append` to a slice does not change the length of the slice, it
> just returns a new slice, so that seems expected.
>
> So, from what I can tell, the code does exactly what the docs say it
> should do.
>
> > In their example code the out parameter is nil.  So what does it do?
>
> Appending to `nil` allocates a new slice. The point of still accepting an
> `out` parameter is that you can potentially prevent an allocation by
> passing in a slice with 0 length and extra capacity (which can then be
> allocated on the stack, or which is from a `sync.Pool`). If you don't need
> that, passing in `nil` seems fine.
>
> > The second argument is encrypted[len(nonce):] which includes the
> Overhead at the start of the []byte. Apparently that Overhead is important.
>
> Yes, the Overhead is important. It is used to authenticate the message.
> You can imagine the process of `Seal` as "encrypt the message and attach a
> hash". The hash is the Overhead. The process also needs a random `nonce`,
> that both the sender and the receiver need to know. That's why the example
> code sends it along with the message (it doesn't have to be secret). So
> that `Seal` call does, effectively (again, for illustrative purposes):
> encrypted := append(append(nonce, ), )
> As `nonce` is an array, this allocates a new backing array for the
> returned slice, which ends up filled with
> 
>
> The `Open` call then retrieves the `nonce` from the first 24 bytes (by
> copying it into `decryptNonce`) and passes the ``
> slice as the `box` argument. Which decrypts the message, authenticates the
> hash and appends the decrypted message to `out` (which is `nil` in the
> example code).
>
> So, the docs are correct. And it seems to me, the code works as expected.
> I'm not sure where the misunderstanding is.
>

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


Re: [go-nuts] The docs for secretbox seem very wrong

2023-10-08 Thread &#x27;Axel Wagner&#x27; via golang-nuts
I don't really understand your issue. You call
encrypted := secretbox.Seal(nonce[:], []byte(s), &nonce, &secretKey)
That means you pass `nonce[:]` as the `out` argument, `s` as the `message`
argument, and the nonce and key and assign the result to `encrypted`.
According to the docs of `secretbox`, `Seal` will `append` the encrypted
message to `nonce[:]` and that encrypted message will be 16 bytes longer
than the message, which is 11 bytes long. Appending 37 (16+11) bytes to a
24 byte nonce gives you 51 bytes, which is what you observe as the length
of `encrypted`.
The length of `nonce` doesn't change (it's an array, after all) - but
passing `append` to a slice does not change the length of the slice, it
just returns a new slice, so that seems expected.

So, from what I can tell, the code does exactly what the docs say it should
do.

> In their example code the out parameter is nil.  So what does it do?

Appending to `nil` allocates a new slice. The point of still accepting an
`out` parameter is that you can potentially prevent an allocation by
passing in a slice with 0 length and extra capacity (which can then be
allocated on the stack, or which is from a `sync.Pool`). If you don't need
that, passing in `nil` seems fine.

> The second argument is encrypted[len(nonce):] which includes the Overhead
at the start of the []byte. Apparently that Overhead is important.

Yes, the Overhead is important. It is used to authenticate the message. You
can imagine the process of `Seal` as "encrypt the message and attach a
hash". The hash is the Overhead. The process also needs a random `nonce`,
that both the sender and the receiver need to know. That's why the example
code sends it along with the message (it doesn't have to be secret). So
that `Seal` call does, effectively (again, for illustrative purposes):
encrypted := append(append(nonce, ), )
As `nonce` is an array, this allocates a new backing array for the returned
slice, which ends up filled with


The `Open` call then retrieves the `nonce` from the first 24 bytes (by
copying it into `decryptNonce`) and passes the ``
slice as the `box` argument. Which decrypts the message, authenticates the
hash and appends the decrypted message to `out` (which is `nil` in the
example code).

So, the docs are correct. And it seems to me, the code works as expected.
I'm not sure where the misunderstanding is.

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


Re: [go-nuts] Generic "nillable" constraint

2023-10-03 Thread &#x27;Axel Wagner&#x27; via golang-nuts
Oh (sorry, being forgetful) and re "it's less of a new mechanism than
introducing a zero identifier": #62487
 introduces *even less* new
mechanism, by expanding comparison to (and assignment of) `nil` to all
types inside a generic function. It's not a new class of constraint, it
just special-cases `nil` a bit more. So it is still a far more general
mechanism, that solves more problems than `nilable` constraint, while
requiring fewer (or at worst the same number of) new concepts.

On Wed, Oct 4, 2023 at 7:36 AM Axel Wagner 
wrote:

> (correction: It should be Convert[J isinterface, T J]. I changed the name
> from I to J to be more readable and then missed one occurrence)
>
> On Wed, Oct 4, 2023 at 7:33 AM Axel Wagner 
> wrote:
>
>> On Wed, Oct 4, 2023 at 6:54 AM Jon Watte  wrote:
>>
>>> > where it is important to permit only type arguments that can be
>>> compared to nil
>>>
>>> I see! As in, if we somehow got a "equalszero" constraint, then that
>>> constraint would solve the problem I illustrate.
>>> I believe that assertion is correct, but I also believe that is a
>>> stronger assertion, and also that it introduces more of a new concept than
>>> a simple "nil" constraint. (Unless you're looking for some way to make
>>> "any" work, and introduce a zero keyword or something...)
>>>
>>
>> Yes, that is what #61372  proposes:
>> Introduce a `zero` predeclared identifier (!) that is assignable to any
>> type and comparable to any type. With some discussion about whether it
>> should only apply inside generic code or not. There is no proposal (as far
>> as I know) for anything like an "equalszero" constraint, as every type can
>> be assigned a meaningful comparison to its zero value, so it seems we
>> should just allow it for all types.
>>
>> To be clear, the criticism of a `nilable` constraint is
>> 1. It only solves a subset of the problem we are seeing. You gave
>> examples from that subset. I gave some examples of problems we are seeing
>> that are *not* in that subset.
>> 2. It is not really clear this particular subset is particularly
>> important. Why is the *specific* split into (interfaces, pointers,
>> slices, functions, maps, channels) and (numbers, booleans, strings,
>> structs, arrays) a particularly important one?
>> 3. As long as that is not clear, it seems more prudent to focus on
>> mechanisms that solve more of the problems we are seeing.
>>
>> FWIW I could, personally, get more (though still not fully) on board with
>> an `isinterface` constraint, that would allow *only* interfaces. It
>> would still allow assignment and comparison to `nil`. But it seems far
>> clearer to me, that interfaces can be singled out. While a `nil` interface
>> is categorically an invalid value, the same is not true for `nil`
>> pointers/maps/channels/funcs *in general*. Any of those kinds of types
>> could still have methods callable on them that work perfectly fine (by
>> doing an `if receiver == nil` check in the method). You categorically can't
>> call a method on a `nil` interface.
>>
>> And an `isinterface` constraint could still conceivable be useful for
>> many of the examples you mentioned. Or it would allow
>>
>> func Convert[J isinterface, T I](s []T) []J {
>> out := make([]I, len(T))
>> for i, v := range s {
>> out[i] = J(v)
>> }
>> return out
>> }
>>
>> I'd still not be convinced this is really worth it, but at least it seems
>> clearer why that particular subset of types deserves to be singled out. In
>> fact, many people have argued that the interface zero value really
>> shouldn't have been spelled `nil`, because interfaces have so little in
>> common, conceptually, to other "nilable" types.
>>
>>
>>>
>>> Also, there's the ergonomics of having to make a zero value instance.
>>> Maybe we can rely on the compiler to optimize it away, but at a minimum it
>>> adds another required line of code in the implementation. E g:
>>>
>>> func MaybeNuke[T nil](b bool, val T) T {
>>>   if b {
>>> return nil
>>>   }
>>>   return val
>>> }
>>>
>>> func MaybeNuke(T zero](b bool, val T) T {
>>>   if b {
>>> var nope T // an extra line!
>>> return nope
>>>   }
>>>   return val
>>> }
>>>
>>> func MaybeNuke(T any](b bool, val T) T {
>>>   if b {
>>> return zero[T]{} // maybe? seems weird
>>>   }
>>>   return val
>>> }
>>>
>>> This is because not all zero values can be instantiated inline with
>>> simply T{}.
>>>
>>> Sincerely,
>>>
>>> Jon Watte
>>>
>>>
>>> --
>>> "I find that the harder I work, the more luck I seem to have." --
>>> Thomas Jefferson
>>>
>>

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

Re: [go-nuts] Generic "nillable" constraint

2023-10-03 Thread &#x27;Axel Wagner&#x27; via golang-nuts
(correction: It should be Convert[J isinterface, T J]. I changed the name
from I to J to be more readable and then missed one occurrence)

On Wed, Oct 4, 2023 at 7:33 AM Axel Wagner 
wrote:

> On Wed, Oct 4, 2023 at 6:54 AM Jon Watte  wrote:
>
>> > where it is important to permit only type arguments that can be
>> compared to nil
>>
>> I see! As in, if we somehow got a "equalszero" constraint, then that
>> constraint would solve the problem I illustrate.
>> I believe that assertion is correct, but I also believe that is a
>> stronger assertion, and also that it introduces more of a new concept than
>> a simple "nil" constraint. (Unless you're looking for some way to make
>> "any" work, and introduce a zero keyword or something...)
>>
>
> Yes, that is what #61372  proposes: Introduce
> a `zero` predeclared identifier (!) that is assignable to any type and
> comparable to any type. With some discussion about whether it should only
> apply inside generic code or not. There is no proposal (as far as I know)
> for anything like an "equalszero" constraint, as every type can be assigned
> a meaningful comparison to its zero value, so it seems we should just allow
> it for all types.
>
> To be clear, the criticism of a `nilable` constraint is
> 1. It only solves a subset of the problem we are seeing. You gave examples
> from that subset. I gave some examples of problems we are seeing that are
> *not* in that subset.
> 2. It is not really clear this particular subset is particularly
> important. Why is the *specific* split into (interfaces, pointers,
> slices, functions, maps, channels) and (numbers, booleans, strings,
> structs, arrays) a particularly important one?
> 3. As long as that is not clear, it seems more prudent to focus on
> mechanisms that solve more of the problems we are seeing.
>
> FWIW I could, personally, get more (though still not fully) on board with
> an `isinterface` constraint, that would allow *only* interfaces. It would
> still allow assignment and comparison to `nil`. But it seems far clearer to
> me, that interfaces can be singled out. While a `nil` interface is
> categorically an invalid value, the same is not true for `nil`
> pointers/maps/channels/funcs *in general*. Any of those kinds of types
> could still have methods callable on them that work perfectly fine (by
> doing an `if receiver == nil` check in the method). You categorically can't
> call a method on a `nil` interface.
>
> And an `isinterface` constraint could still conceivable be useful for many
> of the examples you mentioned. Or it would allow
>
> func Convert[J isinterface, T I](s []T) []J {
> out := make([]I, len(T))
> for i, v := range s {
> out[i] = J(v)
> }
> return out
> }
>
> I'd still not be convinced this is really worth it, but at least it seems
> clearer why that particular subset of types deserves to be singled out. In
> fact, many people have argued that the interface zero value really
> shouldn't have been spelled `nil`, because interfaces have so little in
> common, conceptually, to other "nilable" types.
>
>
>>
>> Also, there's the ergonomics of having to make a zero value instance.
>> Maybe we can rely on the compiler to optimize it away, but at a minimum it
>> adds another required line of code in the implementation. E g:
>>
>> func MaybeNuke[T nil](b bool, val T) T {
>>   if b {
>> return nil
>>   }
>>   return val
>> }
>>
>> func MaybeNuke(T zero](b bool, val T) T {
>>   if b {
>> var nope T // an extra line!
>> return nope
>>   }
>>   return val
>> }
>>
>> func MaybeNuke(T any](b bool, val T) T {
>>   if b {
>> return zero[T]{} // maybe? seems weird
>>   }
>>   return val
>> }
>>
>> This is because not all zero values can be instantiated inline with
>> simply T{}.
>>
>> Sincerely,
>>
>> Jon Watte
>>
>>
>> --
>> "I find that the harder I work, the more luck I seem to have." -- Thomas
>> Jefferson
>>
>

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


Re: [go-nuts] Generic "nillable" constraint

2023-10-03 Thread &#x27;Axel Wagner&#x27; via golang-nuts
On Wed, Oct 4, 2023 at 6:54 AM Jon Watte  wrote:

> > where it is important to permit only type arguments that can be compared
> to nil
>
> I see! As in, if we somehow got a "equalszero" constraint, then that
> constraint would solve the problem I illustrate.
> I believe that assertion is correct, but I also believe that is a stronger
> assertion, and also that it introduces more of a new concept than a simple
> "nil" constraint. (Unless you're looking for some way to make "any" work,
> and introduce a zero keyword or something...)
>

Yes, that is what #61372  proposes: Introduce a
`zero` predeclared identifier (!) that is assignable to any type and
comparable to any type. With some discussion about whether it should only
apply inside generic code or not. There is no proposal (as far as I know)
for anything like an "equalszero" constraint, as every type can be assigned
a meaningful comparison to its zero value, so it seems we should just allow
it for all types.

To be clear, the criticism of a `nilable` constraint is
1. It only solves a subset of the problem we are seeing. You gave examples
from that subset. I gave some examples of problems we are seeing that are
*not* in that subset.
2. It is not really clear this particular subset is particularly important.
Why is the *specific* split into (interfaces, pointers, slices, functions,
maps, channels) and (numbers, booleans, strings, structs, arrays) a
particularly important one?
3. As long as that is not clear, it seems more prudent to focus on
mechanisms that solve more of the problems we are seeing.

FWIW I could, personally, get more (though still not fully) on board with
an `isinterface` constraint, that would allow *only* interfaces. It would
still allow assignment and comparison to `nil`. But it seems far clearer to
me, that interfaces can be singled out. While a `nil` interface is
categorically an invalid value, the same is not true for `nil`
pointers/maps/channels/funcs *in general*. Any of those kinds of types
could still have methods callable on them that work perfectly fine (by
doing an `if receiver == nil` check in the method). You categorically can't
call a method on a `nil` interface.

And an `isinterface` constraint could still conceivable be useful for many
of the examples you mentioned. Or it would allow

func Convert[J isinterface, T I](s []T) []J {
out := make([]I, len(T))
for i, v := range s {
out[i] = J(v)
}
return out
}

I'd still not be convinced this is really worth it, but at least it seems
clearer why that particular subset of types deserves to be singled out. In
fact, many people have argued that the interface zero value really
shouldn't have been spelled `nil`, because interfaces have so little in
common, conceptually, to other "nilable" types.


>
> Also, there's the ergonomics of having to make a zero value instance.
> Maybe we can rely on the compiler to optimize it away, but at a minimum it
> adds another required line of code in the implementation. E g:
>
> func MaybeNuke[T nil](b bool, val T) T {
>   if b {
> return nil
>   }
>   return val
> }
>
> func MaybeNuke(T zero](b bool, val T) T {
>   if b {
> var nope T // an extra line!
> return nope
>   }
>   return val
> }
>
> func MaybeNuke(T any](b bool, val T) T {
>   if b {
> return zero[T]{} // maybe? seems weird
>   }
>   return val
> }
>
> This is because not all zero values can be instantiated inline with simply
> T{}.
>
> Sincerely,
>
> Jon Watte
>
>
> --
> "I find that the harder I work, the more luck I seem to have." -- Thomas
> Jefferson
>

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


Re: [go-nuts] Generic "nillable" constraint

2023-10-03 Thread &#x27;Axel Wagner&#x27; via golang-nuts
On Tue, Oct 3, 2023 at 9:06 PM Jon Watte  wrote:

> I don't want to include int or struct{} in this case. I care specifically
> about "can be compared to nil"
> The only thing I can do with a type parameter that is only constrained as
> "nil" is compare it to nil, or assign nil to it.
> This means approximately "any reference type" -- interfaces, pointers,
> maps, slices, chans...
>

Exactly. That is the problem. It means your suggestion does not allow a
slew of problems that #61372  would solve. It
means your suggestion is less powerful.


> But, let's put this out there:
> How would you, today, write a function that compacted a slice of
> interface, such that any "nil" interface value would be removed from the
> slice?
>
> func Compact[T ?](sl []T) []T {
> j := 0
> for i := 0; i < len(sl); i++ {
> if el := sl[i]; el != nil {
> sl[j] = el
> j++
> }
> }
> return sl[:j]
> }
>
> There's nothing today I can put in place of the "?" to make this
> perfectly-reasonable generic function work.
> I propose I should be able to put "nil" in place of the "?" to make this
> work, and it would work for any reference type (that can be compared or
> assigned to nil.)
>

With #61372, you would put `any` and write `el != zero`. And it would work
for all types, including the ones you mention.


>
> Unless I'm missing something?
>
> Sincerely,
>
> Jon Watte
>
>
> --
> "I find that the harder I work, the more luck I seem to have." -- Thomas
> Jefferson
>
>
> On Mon, Oct 2, 2023 at 9:26 PM Axel Wagner 
> wrote:
>
>> It doesn't solve the problem. That function signature you wrote could not
>> be instantiated by `int`, for example. You can't write `comparable | nil`,
>> as `comparable` is not allowed in a union. And if we allowed it, there
>> would be no way to write the body of the function. It doesn't help with
>> types like `struct{ F func() }`. And it doesn't make it easier to write the
>> zero value for returns etc. And it doesn't address the same kind of issue
>> for generated code.
>>
>> On Tue, Oct 3, 2023 at 3:51 AM Jon Watte  wrote:
>>
>>> What's the concern with "a constant interface that is inhabited exactly
>>> by the types that can compare to nil?"
>>>
>>> This is clearly something the language has as a concept -- it knows
>>> whether "foo == nil" is an error or not.
>>>
>>> "nil" could be the ergonomic name for this constraint:
>>>
>>> func Compact[T nil](s []T) ...
>>>
>>> Sincerely,
>>>
>>> Jon
>>>
>>>
>>> On Mon, Oct 2, 2023, 16:53 Ian Lance Taylor  wrote:
>>>
 There is a lot more on this topic at https://go.dev/issue/61372.
 We're not sure how best to handle it.

 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/CAJgyHGPRdv%3DjOPs34V1Q%3DNh9RVpD8c-qagr%3DdEz0OX-oDEaa7Q%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/CAEkBMfEuVW5C1zR6%3DCd-vxSyPOxg3MxERkcRTrgt10SS0_0ssw%40mail.gmail.com.


Re: [go-nuts] Generic "nillable" constraint

2023-10-02 Thread &#x27;Axel Wagner&#x27; via golang-nuts
It doesn't solve the problem. That function signature you wrote could not
be instantiated by `int`, for example. You can't write `comparable | nil`,
as `comparable` is not allowed in a union. And if we allowed it, there
would be no way to write the body of the function. It doesn't help with
types like `struct{ F func() }`. And it doesn't make it easier to write the
zero value for returns etc. And it doesn't address the same kind of issue
for generated code.

On Tue, Oct 3, 2023 at 3:51 AM Jon Watte  wrote:

> What's the concern with "a constant interface that is inhabited exactly by
> the types that can compare to nil?"
>
> This is clearly something the language has as a concept -- it knows
> whether "foo == nil" is an error or not.
>
> "nil" could be the ergonomic name for this constraint:
>
> func Compact[T nil](s []T) ...
>
> Sincerely,
>
> Jon
>
>
> On Mon, Oct 2, 2023, 16:53 Ian Lance Taylor  wrote:
>
>> There is a lot more on this topic at https://go.dev/issue/61372.
>> We're not sure how best to handle it.
>>
>> 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/CAJgyHGPRdv%3DjOPs34V1Q%3DNh9RVpD8c-qagr%3DdEz0OX-oDEaa7Q%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/CAEkBMfE_j3LvJ7H_QBag4u4nvJ9W6iAyeqXV%2BgB0cqv-z_ZYXQ%40mail.gmail.com.


Re: [go-nuts] What is a ordinary and exceptional error?

2023-10-01 Thread &#x27;Axel Wagner&#x27; via golang-nuts
On Sun, Oct 1, 2023 at 2:37 PM Jerry Londergaard 
wrote:

> I've been thinking about this point as well lately. I think I understand
> (at least some of) the conditions under which
> you would call a panic(), but I still don't quite grok why it's better
> than returning an error if that error is properly
> handled.  If I panic(), then no defer() statements will be called, and I
> don't give any chance to the calling code to cleanup etc.
>

`panic` does call defered functions.

The reason why not to return an error is who is responsible for fixing the
failure condition.

An error is usually returned to the user/operator and it is expected that
they remedy it. For example, if a connection fails because a name can not
be resolved, the program should just print "can't resolve example.com",
signalling that the user has to fix their inputs or network setup.

On the other hand, a panic is expected to be reported to the developer for
fixing. If a program has a bug, there really is nothing the user can do. No
amount of changed inputs or re-running will make the bug go away - the code
needs to be fixed.

Hence, a panic contains a stack trace (the developer needs that stack trace
to effectively find and fix the bug), while an error does not (the user
does not know your code so the stack trace doesn't help them).

To be clear, not everyone follows this philosophy and not every program
follows this dichotomy (in a service, the role of operator and developer
often overlap - hence "devops"). But it's a pretty self-consistent view
that can answer a lot of questions about good error handling and messages.


>
> I struggle to think of a scenario where it would be better to *not* allow
> the code to cleanup and exit gracefully. Is it because we
> don't want to give the code the possiiblity of ignoring the error?
>
> On Saturday, 30 September 2023 at 9:10:09 pm UTC+10 Kamil Ziemian wrote:
>
>> Thank you mister Rader, this was what I needed. I think I now have
>> intuition what this text want to say.
>>
>> Best regards
>> Kamil
>>
>> piątek, 29 września 2023 o 23:58:39 UTC+2 Kurtis Rader napisał(a):
>>
>>> An ordinary error is one that can be expected to occur. For example,
>>> opening a file may fail because the file does not exist or the process
>>> doesn't have permission to open it. An exceptional error is one that is not
>>> expected to occur and often indicates the state of the program is invalid.
>>> For example, a data structure that contains pointers that should never be
>>> nil. If a nil pointer is found that means the structure is corrupted.
>>> Probably due to a programming bug. Exceptional errors are those which may
>>> make it unsafe to continue execution. In which case calling panic() may be
>>> the only sensible course of action.
>>>
>>> On Fri, Sep 29, 2023 at 2:38 PM Kamil Ziemian 
>>> wrote:
>>>
 Hello,

 In Go FAQ we read "We believe that coupling exceptions to a control
 structure, as in the try-catch-finally idiom, results in convoluted
 code. It also tends to encourage programmers to label too many ordinary
 errors, such as failing to open a file, as exceptional.", " Go also has a
 couple of built-in functions to signal and recover from truly exceptional
 conditions.".

 Can you explain to me in general terms what is a ordinary and
 exceptional error? I'm just a hobbist programer and I never think about
 errors in that way.

 Best regards,
 Kamil

 --
 You received this message because you are subscribed to the Google
 Groups "golang-nuts" group.
 To unsubscribe from this group and stop receiving emails from it, send
 an email to golang-nuts...@googlegroups.com.
 To view this discussion on the web visit
 https://groups.google.com/d/msgid/golang-nuts/e9fdeb9d-e3b6-49ea-b7e3-5ab7ddafea7bn%40googlegroups.com
 
 .

>>>
>>>
>>> --
>>> Kurtis Rader
>>> Caretaker of the exceptional canines Junior and Hank
>>>
>> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/7a17fcf5-480b-44c8-89b4-2a44b1f71c2en%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/CAEkBMfG2ZGY3FUwieXekJDaK_qh_Dacf-z

Re: [go-nuts] About variables have per-iteration scope instead of per-loop scope

2023-09-30 Thread &#x27;Axel Wagner&#x27; via golang-nuts
So, how often do you depend on this particular scoping behavior, in Go or
JS? Do you have any example of where you intentionally rely on the current
behavior, that might break with the new one?

I think it's important to emphasize that we do not know of a *single case*
where the current behavior was usefully taken advantage of. Even strong
opponents of the change failed to produce any - they just created synthetic
(and extremely obfuscated) cases that would change behavior, without any
reference to real code these cases where taken from.

You keep asserting that you have to remember different sets of rules - I
just don't think that's true, in any real sense. I think you'll find that
in reality, it will have literally no effect on you - except that it is not
unlikely to fix a bug or two in your existing code base. Because it turns
out that no one actually thinks at that level about scoping.

On Sat, Sep 30, 2023 at 6:35 PM Victor Giordano 
wrote:

> Thanks Alex, your insight was very helpful.
>
> Allow me to share the feeling I have => I still struggle a little in my
> mind... I craft web fronts in javascript, and back in golang (and scala or
> java). With this change I will have two different scoping rules... and I
> feel I don't need it (because I learn how to use it well) nor ask for
> them... but it is okay.. changes work that way. The bottom line is: I was
> already comfortable with the language scope rules.
>
> El sáb, 30 sept 2023 a las 12:37, Axel Wagner (<
> axel.wagner...@googlemail.com>) escribió:
>
>> This has come up during the discussion already. I don't know enough about
>> other languages to speak with confidence, but apparently there already is
>> precedent for this and/or some languages are at least considering making a
>> similar change.
>>
>> Note that scoping rules already vary between languages - in some cases,
>> pretty widely. For example, Python is not block scoped - this works:
>> def f():
>> if True:
>> x = 42
>> print(x)
>> And Perl has dynamic scoping, where variables can be scoped to a call
>> stack, instead of any lexical element of the source code. Javascript, as
>> far as I know, is pretty notorious for having extremely idiosyncratic
>> scoping rules (e.g. it is a common confusion how `this` is scoped in
>> different contexts) and also has several different kinds of declarations
>> with AFAIK slightly different scoping rules.
>> In C, a symbol is only scoped to a single file (as far as the processor
>> is concerned) and in there, only from its declaration onwards, while in Go,
>> a package-scoped definition can appear in any file of any package. And
>> speaking of C, it doesn't have closures at all, so the scoping rules of
>> loop variables are *already* very different.
>>
>> So I think the case that you *currently* don't have to be aware of how a
>> language is using scoping is pretty vastly overstated. What's more, the
>> majority of programs won't actually be affected by this - and for those
>> that are, it seems that empirically, the new rules will align more closely
>> with what people expect subconsciously.
>>
>> I don't think you should worry too much. Run your tests with the new loop
>> variable semantics in Go 1.21 to see if everything still works. Most
>> likely, it will - or you will discover a bug in your current code.
>>
>> On Sat, Sep 30, 2023 at 4:58 PM Victor Giordano 
>> wrote:
>>
>>> Hi gophers! How you doing?
>>>
>>> In my work we recently discuss with a buddy about this article
>>> . I need to talk about this
>>>
>>> I appreaciate that golang makes a lot of effort on this. Working with
>>> clousures cames with perils and the go vet tool emiting a warning is a
>>> great thing.
>>>
>>> Althought I do not think that chaning language semantics is something
>>> 100% good,  see my point: As long I use several languages for making a
>>> system this "scope rule" will mismatch with other languajes, for example,
>>> javascript.
>>>
>>> So from now onwards I shall be aware that for loops have variables
>>> scopes in one fashion in Golang and in other fashion in another
>>> languages... so at the end of the day, I feel like is adding some burden.
>>> If for development we can use a single and sole language (Sauron don't read
>>> this :P !) I would think this change is good, but that is not the case in
>>> now-a-days. I try to think that with time, perhaps other languages evolves
>>> it this way... but.. ¿what if I wanna have my "for loop" with legacy scope
>>> (block scope, not per iteration scope)?
>>>
>>> So... I expect to the readers to talk with me, showing what they see and
>>> feel. Is not my intention to generate hard feelings at all. I'm a person
>>> that work crafting system in group with others.. I have had terrible
>>> nightmares working with Scala where implicits and invoking methods as they
>>> were feilds were terrible ideas for working in group (perhaps not if you
>>> work solo). And this feature

Re: [go-nuts] About variables have per-iteration scope instead of per-loop scope

2023-09-30 Thread &#x27;Axel Wagner&#x27; via golang-nuts
This has come up during the discussion already. I don't know enough about
other languages to speak with confidence, but apparently there already is
precedent for this and/or some languages are at least considering making a
similar change.

Note that scoping rules already vary between languages - in some cases,
pretty widely. For example, Python is not block scoped - this works:
def f():
if True:
x = 42
print(x)
And Perl has dynamic scoping, where variables can be scoped to a call
stack, instead of any lexical element of the source code. Javascript, as
far as I know, is pretty notorious for having extremely idiosyncratic
scoping rules (e.g. it is a common confusion how `this` is scoped in
different contexts) and also has several different kinds of declarations
with AFAIK slightly different scoping rules.
In C, a symbol is only scoped to a single file (as far as the processor is
concerned) and in there, only from its declaration onwards, while in Go, a
package-scoped definition can appear in any file of any package. And
speaking of C, it doesn't have closures at all, so the scoping rules of
loop variables are *already* very different.

So I think the case that you *currently* don't have to be aware of how a
language is using scoping is pretty vastly overstated. What's more, the
majority of programs won't actually be affected by this - and for those
that are, it seems that empirically, the new rules will align more closely
with what people expect subconsciously.

I don't think you should worry too much. Run your tests with the new loop
variable semantics in Go 1.21 to see if everything still works. Most
likely, it will - or you will discover a bug in your current code.

On Sat, Sep 30, 2023 at 4:58 PM Victor Giordano 
wrote:

> Hi gophers! How you doing?
>
> In my work we recently discuss with a buddy about this article
> . I need to talk about this
>
> I appreaciate that golang makes a lot of effort on this. Working with
> clousures cames with perils and the go vet tool emiting a warning is a
> great thing.
>
> Althought I do not think that chaning language semantics is something 100%
> good,  see my point: As long I use several languages for making a system
> this "scope rule" will mismatch with other languajes, for example,
> javascript.
>
> So from now onwards I shall be aware that for loops have variables scopes
> in one fashion in Golang and in other fashion in another languages... so at
> the end of the day, I feel like is adding some burden. If for development
> we can use a single and sole language (Sauron don't read this :P !) I would
> think this change is good, but that is not the case in now-a-days. I try to
> think that with time, perhaps other languages evolves it this way... but..
> ¿what if I wanna have my "for loop" with legacy scope (block scope, not per
> iteration scope)?
>
> So... I expect to the readers to talk with me, showing what they see and
> feel. Is not my intention to generate hard feelings at all. I'm a person
> that work crafting system in group with others.. I have had terrible
> nightmares working with Scala where implicits and invoking methods as they
> were feilds were terrible ideas for working in group (perhaps not if you
> work solo). And this feature recalls me those feelings.
>
> Greetings
> Víctor.
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/5f31be67-d246-4778-a373-69d525772974n%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/CAEkBMfFC7hvhi%3Deg8h5ard54hn7Wo-tjEPfbJ82SC6QbZ5PEYw%40mail.gmail.com.


Re: [go-nuts] Encrypting a small secret using curve25519

2023-09-20 Thread &#x27;Axel Wagner&#x27; via golang-nuts
To be clear: I'm by no means an expert, so take my advice with a huge grain
of salt (pun intended). But from what it seems, with no offense intended,
neither are you.

On Wed, Sep 20, 2023 at 10:32 AM Axel Wagner 
wrote:

> As I understand it, ed25519 is using Curve25519 in EdDSA, which is a
> signing scheme. So using "ed25519" for encryption does not make any sense.
> NaCl also uses Curve25519, ultimately using ECDH (again, as I understand
> it) to establish a secret key for Salsa20. So it is pretty fundamentally
> different than ed25519.
> Note that golang.org/x/crypto/nacl *is* a pure Go package, not a
> libsodium wrapper. And yes, it's very likely what you want, if you want to
> use Curve25519 for encryption. Unless you want to roll your own
> cryptography, in which case, here be dragons. But the `crypto/ecdh` package
> (available since Go 1.20) would probably the primitive to look at.
>
> On Wed, Sep 20, 2023 at 10:02 AM christoph...@gmail.com <
> christophe.mees...@gmail.com> wrote:
>
>> Hello,
>>
>> I noticed that the go standard library only support ed25519 signing (
>> https://pkg.go.dev/crypto/ed25519@go1.21.1).
>>
>> I would need to encrypt a small secret with the public key of the
>> receiver so that he is the only one able to decrypt it with its private
>> key. The small secret would typically be a random symmetric key used to
>> encrypt the possibly long message.
>>
>> The only solution I found is to use nacl.Box (
>> https://pkg.go.dev/golang.org/x/crypto/nacl/box). Why is it so ?
>>
>> Are there alternative reliable go packages I could use ? I'll use only a
>> pure Go package, not a libsodium wrapper package.
>>
>>
>> --
>> You received this message because you are subscribed to the Google Groups
>> "golang-nuts" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to golang-nuts+unsubscr...@googlegroups.com.
>> To view this discussion on the web visit
>> https://groups.google.com/d/msgid/golang-nuts/8018a90a-fae2-4c45-8c19-ed8b5c205319n%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/CAEkBMfGUwCYsF%2BvDUf2VXfbOeTextJXiFTKjQrO9WLQuRmsQ_w%40mail.gmail.com.


Re: [go-nuts] Encrypting a small secret using curve25519

2023-09-20 Thread &#x27;Axel Wagner&#x27; via golang-nuts
As I understand it, ed25519 is using Curve25519 in EdDSA, which is a
signing scheme. So using "ed25519" for encryption does not make any sense.
NaCl also uses Curve25519, ultimately using ECDH (again, as I understand
it) to establish a secret key for Salsa20. So it is pretty fundamentally
different than ed25519.
Note that golang.org/x/crypto/nacl *is* a pure Go package, not a libsodium
wrapper. And yes, it's very likely what you want, if you want to use
Curve25519 for encryption. Unless you want to roll your own cryptography,
in which case, here be dragons. But the `crypto/ecdh` package (available
since Go 1.20) would probably the primitive to look at.

On Wed, Sep 20, 2023 at 10:02 AM christoph...@gmail.com <
christophe.mees...@gmail.com> wrote:

> Hello,
>
> I noticed that the go standard library only support ed25519 signing (
> https://pkg.go.dev/crypto/ed25519@go1.21.1).
>
> I would need to encrypt a small secret with the public key of the receiver
> so that he is the only one able to decrypt it with its private key. The
> small secret would typically be a random symmetric key used to encrypt the
> possibly long message.
>
> The only solution I found is to use nacl.Box (
> https://pkg.go.dev/golang.org/x/crypto/nacl/box). Why is it so ?
>
> Are there alternative reliable go packages I could use ? I'll use only a
> pure Go package, not a libsodium wrapper package.
>
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/8018a90a-fae2-4c45-8c19-ed8b5c205319n%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/CAEkBMfEcrU2_L3wifm5%3DXYNkSW1hexYB5FniKPy2PtAEXeUSjQ%40mail.gmail.com.


Re: [go-nuts] Using go module 101, undefined types

2023-09-11 Thread &#x27;Axel Wagner&#x27; via golang-nuts
The code you posted does not actually contain the string `api.PetStore`, so
it seems to be incomplete. From extrapolation, I agree that it should work,
so the issue must be in that incomplete part.

On Mon, Sep 11, 2023 at 11:23 PM Tong Sun  wrote:

> This is really a go module 101 question, as I'm trying to understand and
> solve the *undefined types* problem that I'm having.
>
> I have:
>
> $ head -1 go.mod
> module backend
>
>
> And in my internal/petstore/main.go file, I have:
>
> package main
>
> import api "backend/internal/petstore/interfaces/ports"
>
> func main() {
> petStore := api.NewPetStore()
> }
>
>
> And in my internal/petstore/interfaces/ports/type.go file, I have:
>
> package api
> type PetStore struct {...}
>
>
> I think it should compile, but I'm getting:
>
> $ go run internal/petstore/main.go
> # command-line-arguments
> internal/petstore/main.go:..:38: undefined: api.PetStore
>
>
> and I have no idea how to fix it.
>
> I also tried to build the whole project with `go build .`, but got
>
> no Go files in 
>
> Please help. thx.
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/ee028af4-3de2-468c-9ef2-48d8a2ac24cbn%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/CAEkBMfFfguq3H6dVUDskxgrngoQU5xUFcYRqQS3sB2Do4fNKSw%40mail.gmail.com.


Re: [go-nuts] Why is pdfcpu v0.5.0 290MiB on proxy.golang.org ?

2023-08-25 Thread &#x27;Axel Wagner&#x27; via golang-nuts
Not sure if it's a good idea, but you could put them in a separate Go
module and only import that from tests. That way they *should* not get
downloaded when the module is only imported as a dependency. I think. OTOH
you'd have to use `go:embed` to export them, which means every `go test`
has to link in a couple hundred MB of data, which is also not great.
Alternatively, the tests could download and unpack them themselves - though
that is less hermetic, there is a danger of the downloaded version of the
test data and the one the test expect drifting apart.

Really, the best would probably be to try and reduce the number and/or size
of those files.

On Fri, Aug 25, 2023 at 10:22 AM Tamás Gulácsi  wrote:

> You're right, thanks.
>
> Do you have any simple solution for this (beside deleting those files)?
> Putting such files in a git submodule or git-LFS seems appropriate but
> complex.
>
>
> Axel Wagner a következőt írta (2023. augusztus 25., péntek, 10:08:47
> UTC+2):
>
>> ISTM that's because they include a lot of PDFs for samples and test data
>> in their repository now:
>> https://github.com/pdfcpu/pdfcpu/tree/master/pkg/samples (245 MB)
>> https://github.com/pdfcpu/pdfcpu/tree/master/pkg/testdata (77 MB)
>> This isn't due to the module mirror doing anything weird, it's just that
>> the module is now big because it includes tons of data it didn't use to.
>>
>> On Fri, Aug 25, 2023 at 9:53 AM Tamás Gulácsi  wrote:
>>
>>> go get github.com/pdfcpu/pdf...@v0.5.0
>>>  hung, so I've investigated:
>>>
>>> $ go get -x github.com/pdfcpu/pdfcpu/pkg/api@latest
>>> # get http://proxy.golang.org/github.com/@v/list
>>> # get http://proxy.golang.org/github.com/pdfcpu/pdfcpu/@v/list
>>> # get http://proxy.golang.org/github.com/pdfcpu/pdfcpu/pkg/api/@v/list
>>>
>>> # get http://proxy.golang.org/github.com/pdfcpu/pdfcpu/pkg/@v/list
>>> # get http://proxy.golang.org/github.com/pdfcpu/@v/list
>>> # get http://proxy.golang.org/github.com/@v/list: 404 Not Found (0.145s)
>>> # get http://proxy.golang.org/github.com/pdfcpu/@v/list: 404 Not Found
>>> (0.145s)
>>> # get http://proxy.golang.org/github.com/pdfcpu/pdfcpu/pkg/@v/list: 404
>>> Not Found (0.149s)
>>> # get http://proxy.golang.org/github.com/pdfcpu/pdfcpu/pkg/api/@v/list:
>>> 404 Not Found (0.149s)
>>> # get http://proxy.golang.org/github.com/pdfcpu/pdfcpu/@v/list: 200 OK
>>> (0.150s)
>>> go: downloading github.com/pdfcpu/pdfcpu v0.5.0
>>>
>>> # get http://proxy.golang.org/github.com/pdfcpu/pdfcpu/@v/v0.5.0.zip
>>>
>>>
>>>
>>> $ curl -X HEAD -L -v
>>> http://proxy.golang.org/github.com/pdfcpu/pdfcpu/@v/v0.5.0.zip
>>> < HTTP/2 302 Found
>>> < Location:
>>> https://storage.googleapis.com/proxy-golang-org-prod/98db0a8de358d04c-github.com:pdfcpu:pdfcpu-v0.5.0.zip?Expires=1693035533&GoogleAccessId=gcs-url
>>> signer-prod%40golang-modproxy.iam.gserviceaccount.com
>>> &Signature=Z6z%2FSzrSw6HYRQRAlZfRTB36whErbhGl4rVFBnnR%2FRG0J14GUYiFXHsk%2FmMPRJAIqcgdQZ0vND4QQ%2FRlJaS6AE4
>>>
>>> RQtwhqDx6pCJn6%2FTPbVUaVBPgEdWppd2x5r1%2BR1eOn54VjE%2BNWZ0LKT9IOCwLN9oWjZPQrz1WnPfKn7vZIc3E5MQd%2FxnZ8foQBfNEJ6WgNFcD6QzUlNRSJkZk8EPa8G7hsAEwZKLwI1GgfIWwtWgd2G
>>> We%2FqpUOqxdPhSorKlJqVGovpVY4n9QTHPRXJGqrXKSaCDZohdIK%2B%2FNklGctIXlK57HNMmzAatyETAOx5kCIfeL3PTxCWszixjy1PkZQA%3D%3D
>>>
>>> < HTTP/2 200
>>> < x-guploader-uploadid:
>>> ADPycdv391ZoUD64eO_-_QY6cAnAFZIdoaseg8u0fxxTTCD9kyNMn8g8cYd_mB3k1HNHMBOF_dxn9d36p_hNjHbTCYaCOw
>>> < date: Fri, 25 Aug 2023 07:47:24 GMT
>>> < cache-control: public,max-age=3600,must-revalidate
>>> < expires: Fri, 25 Aug 2023 08:47:24 GMT
>>> < last-modified: Sun, 20 Aug 2023 12:49:28 GMT
>>> < etag: "2396accaf05435436ab40e7eee3700f1"
>>> < x-goog-generation: 1692535768254742
>>> < x-goog-metageneration: 1
>>> < x-goog-stored-content-encoding: identity
>>> < x-goog-stored-content-length: 293287851
>>> < content-type: application/zip
>>> < content-disposition: attachment; filename="v0.5.0.zip"
>>> < x-goog-hash: crc32c=61bZnw==
>>> < x-goog-hash: md5=I5asyvBUNUNqtA5+7jcA8Q==
>>> < x-goog-storage-class: MULTI_REGIONAL
>>> < accept-ranges: bytes
>>> < content-length: 293287851
>>> < server: UploadServer
>>> < alt-svc: h3=":443"; ma=2592000,h3-29=":443"; ma=2592000
>>>
>>>
>>> ??
>>>
>>> v0.4.2 is just 3MiB.
>>>
>>> --
>>> You received this message because you are subscribed 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/00c8d89f-5d7c-47f7-810b-68ee6046b995n%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-nu

Re: [go-nuts] Why is pdfcpu v0.5.0 290MiB on proxy.golang.org ?

2023-08-25 Thread &#x27;Axel Wagner&#x27; via golang-nuts
ISTM that's because they include a lot of PDFs for samples and test data in
their repository now:
https://github.com/pdfcpu/pdfcpu/tree/master/pkg/samples (245 MB)
https://github.com/pdfcpu/pdfcpu/tree/master/pkg/testdata (77 MB)
This isn't due to the module mirror doing anything weird, it's just that
the module is now big because it includes tons of data it didn't use to.

On Fri, Aug 25, 2023 at 9:53 AM Tamás Gulácsi  wrote:

> go get github.com/pdfcpu/pdfcpu@v0.5.0 hung, so I've investigated:
>
> $ go get -x github.com/pdfcpu/pdfcpu/pkg/api@latest
> # get http://proxy.golang.org/github.com/@v/list
> # get http://proxy.golang.org/github.com/pdfcpu/pdfcpu/@v/list
> # get http://proxy.golang.org/github.com/pdfcpu/pdfcpu/pkg/api/@v/list
>
> # get http://proxy.golang.org/github.com/pdfcpu/pdfcpu/pkg/@v/list
> # get http://proxy.golang.org/github.com/pdfcpu/@v/list
> # get http://proxy.golang.org/github.com/@v/list: 404 Not Found (0.145s)
> # get http://proxy.golang.org/github.com/pdfcpu/@v/list: 404 Not Found
> (0.145s)
> # get http://proxy.golang.org/github.com/pdfcpu/pdfcpu/pkg/@v/list: 404
> Not Found (0.149s)
> # get http://proxy.golang.org/github.com/pdfcpu/pdfcpu/pkg/api/@v/list:
> 404 Not Found (0.149s)
> # get http://proxy.golang.org/github.com/pdfcpu/pdfcpu/@v/list: 200 OK
> (0.150s)
> go: downloading github.com/pdfcpu/pdfcpu v0.5.0
> # get http://proxy.golang.org/github.com/pdfcpu/pdfcpu/@v/v0.5.0.zip
>
>
>
> $ curl -X HEAD -L -v
> http://proxy.golang.org/github.com/pdfcpu/pdfcpu/@v/v0.5.0.zip
> < HTTP/2 302 Found
> < Location:
> https://storage.googleapis.com/proxy-golang-org-prod/98db0a8de358d04c-github.com:pdfcpu:pdfcpu-v0.5.0.zip?Expires=1693035533&GoogleAccessId=gcs-url
> signer-prod%40golang-modproxy.iam.gserviceaccount.com
> &Signature=Z6z%2FSzrSw6HYRQRAlZfRTB36whErbhGl4rVFBnnR%2FRG0J14GUYiFXHsk%2FmMPRJAIqcgdQZ0vND4QQ%2FRlJaS6AE4
>
> RQtwhqDx6pCJn6%2FTPbVUaVBPgEdWppd2x5r1%2BR1eOn54VjE%2BNWZ0LKT9IOCwLN9oWjZPQrz1WnPfKn7vZIc3E5MQd%2FxnZ8foQBfNEJ6WgNFcD6QzUlNRSJkZk8EPa8G7hsAEwZKLwI1GgfIWwtWgd2G
> We%2FqpUOqxdPhSorKlJqVGovpVY4n9QTHPRXJGqrXKSaCDZohdIK%2B%2FNklGctIXlK57HNMmzAatyETAOx5kCIfeL3PTxCWszixjy1PkZQA%3D%3D
>
> < HTTP/2 200
> < x-guploader-uploadid:
> ADPycdv391ZoUD64eO_-_QY6cAnAFZIdoaseg8u0fxxTTCD9kyNMn8g8cYd_mB3k1HNHMBOF_dxn9d36p_hNjHbTCYaCOw
> < date: Fri, 25 Aug 2023 07:47:24 GMT
> < cache-control: public,max-age=3600,must-revalidate
> < expires: Fri, 25 Aug 2023 08:47:24 GMT
> < last-modified: Sun, 20 Aug 2023 12:49:28 GMT
> < etag: "2396accaf05435436ab40e7eee3700f1"
> < x-goog-generation: 1692535768254742
> < x-goog-metageneration: 1
> < x-goog-stored-content-encoding: identity
> < x-goog-stored-content-length: 293287851
> < content-type: application/zip
> < content-disposition: attachment; filename="v0.5.0.zip"
> < x-goog-hash: crc32c=61bZnw==
> < x-goog-hash: md5=I5asyvBUNUNqtA5+7jcA8Q==
> < x-goog-storage-class: MULTI_REGIONAL
> < accept-ranges: bytes
> < content-length: 293287851
> < server: UploadServer
> < alt-svc: h3=":443"; ma=2592000,h3-29=":443"; ma=2592000
>
>
> ??
>
> v0.4.2 is just 3MiB.
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/00c8d89f-5d7c-47f7-810b-68ee6046b995n%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/CAEkBMfEyxP3PkzbxgFkH6H3Sw7bxDw7MKiHcNRi1aPrQ-8-7rg%40mail.gmail.com.


Re: [go-nuts] How to try out the new range func CL in a module

2023-08-21 Thread &#x27;Axel Wagner&#x27; via golang-nuts
(or change the `go` directive to `Go 1.21` (no minor version) apparently)

On Tue, Aug 22, 2023 at 7:52 AM Axel Wagner 
wrote:

> By coincidence, I was just reading https://go.dev/blog/toolchain and
> realized I put `GOTOOLCHAIN=local` into my ~/.confiig/go/env a while ago,
> so as to not have the Go tool transparently download different versions. If
> I remove that, I can indeed reproduce the behavior you are seeing.
> So, my recommendation for experimenting would be to run `go env -w
> GOTOOLCHAIN=local`.
>
> On Tue, Aug 22, 2023 at 12:51 AM Hein Meling 
> wrote:
>
>> Thanks Axel for your reply. That's interesting. I'm able to run your
>> example just fine. However, using a different go.mod file with the content
>> below (and a longer code example with iteration over a LevelDB thing... not
>> able to provide the code), I get:
>>
>> % gotip version
>> go version go1.21.0 darwin/arm64
>>
>> % gotip run iter.go
>> # command-line-arguments
>> ./iter.go:48:25: cannot range over SnapshotHash(ldb, nonce) (value of
>> type Seq2[uint64, error])
>>
>> module iter
>>
>> go 1.21.0
>>
>> require (
>> github.com/opencoff/go-fasthash v0.0.0-20180406145558-aed761496075
>> github.com/syndtr/goleveldb v1.0.0
>> )
>>
>> require (
>> github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db // indirect
>> golang.org/x/net v0.10.0 // indirect
>> golang.org/x/sys v0.11.0 // indirect
>> golang.org/x/text v0.12.0 // indirect
>> )
>>
>>
>> On Sunday, August 20, 2023 at 10:59:20 PM UTC-7 Axel Wagner wrote:
>>
>>> Hm. For me, it still enables the rangefunc experiment, even though
>>> go.mod says go 1.21:
>>>
>>> mero@vetinari ~/tmp/x$ gotip version
>>> go version devel go1.21-ca691a8566d Tue Jul 18 10:30:20 2023 -0400 (w/
>>> rangefunc) linux/amd64
>>> mero@vetinari ~/tmp/x$ cat go.mod
>>> module x
>>>
>>> go 1.21
>>> mero@vetinari ~/tmp/x$ cat x.go
>>> package main
>>>
>>> import "fmt"
>>>
>>> func main() {
>>> s := []int{1, 2, 3}
>>> for v := range All(s) {
>>> fmt.Println(v)
>>> }
>>> }
>>>
>>> func All[T any](s []T) func(yield func(T) bool) bool {
>>> return func(yield func(T) bool) bool {
>>> for _, v := range s {
>>> if !yield(v) {
>>> return false
>>> }
>>> }
>>> return true
>>> }
>>> }
>>> mero@vetinari ~/tmp/x$ gotip run x.go
>>> 1
>>> 2
>>> 3
>>>
>>> On Fri, Aug 18, 2023 at 10:54 PM Hein Meling  wrote:
>>>
 Hi all,

 I wanted to play around with the new range func CL
 .

 Doing simple stuff works just fine, but if I need to import packages to
 construct my custom iterator func, the go/gotip command insists on a go.mod
 file, which effectively resets the go version to 1.21.0 (due to go.mod),
 instead of the "(w/ rangefunc)" CL.

 Anyone know any workarounds for this?

 Thanks,
 :) Hein

 --
 You received this message because you are subscribed 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/f01ff376-b789-4d8a-89f5-165a6527325fn%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/09e1c142-0532-4d05-8dbe-6114fefdc2fdn%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/CAEkBMfHZwz-KReuHL0c8aJ%2BOZ%3DVNVuSDUWJjv-khoN1fvu8oCg%40mail.gmail.com.


Re: [go-nuts] How to try out the new range func CL in a module

2023-08-21 Thread &#x27;Axel Wagner&#x27; via golang-nuts
By coincidence, I was just reading https://go.dev/blog/toolchain and
realized I put `GOTOOLCHAIN=local` into my ~/.confiig/go/env a while ago,
so as to not have the Go tool transparently download different versions. If
I remove that, I can indeed reproduce the behavior you are seeing.
So, my recommendation for experimenting would be to run `go env -w
GOTOOLCHAIN=local`.

On Tue, Aug 22, 2023 at 12:51 AM Hein Meling  wrote:

> Thanks Axel for your reply. That's interesting. I'm able to run your
> example just fine. However, using a different go.mod file with the content
> below (and a longer code example with iteration over a LevelDB thing... not
> able to provide the code), I get:
>
> % gotip version
> go version go1.21.0 darwin/arm64
>
> % gotip run iter.go
> # command-line-arguments
> ./iter.go:48:25: cannot range over SnapshotHash(ldb, nonce) (value of type
> Seq2[uint64, error])
>
> module iter
>
> go 1.21.0
>
> require (
> github.com/opencoff/go-fasthash v0.0.0-20180406145558-aed761496075
> github.com/syndtr/goleveldb v1.0.0
> )
>
> require (
> github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db // indirect
> golang.org/x/net v0.10.0 // indirect
> golang.org/x/sys v0.11.0 // indirect
> golang.org/x/text v0.12.0 // indirect
> )
>
>
> On Sunday, August 20, 2023 at 10:59:20 PM UTC-7 Axel Wagner wrote:
>
>> Hm. For me, it still enables the rangefunc experiment, even though go.mod
>> says go 1.21:
>>
>> mero@vetinari ~/tmp/x$ gotip version
>> go version devel go1.21-ca691a8566d Tue Jul 18 10:30:20 2023 -0400 (w/
>> rangefunc) linux/amd64
>> mero@vetinari ~/tmp/x$ cat go.mod
>> module x
>>
>> go 1.21
>> mero@vetinari ~/tmp/x$ cat x.go
>> package main
>>
>> import "fmt"
>>
>> func main() {
>> s := []int{1, 2, 3}
>> for v := range All(s) {
>> fmt.Println(v)
>> }
>> }
>>
>> func All[T any](s []T) func(yield func(T) bool) bool {
>> return func(yield func(T) bool) bool {
>> for _, v := range s {
>> if !yield(v) {
>> return false
>> }
>> }
>> return true
>> }
>> }
>> mero@vetinari ~/tmp/x$ gotip run x.go
>> 1
>> 2
>> 3
>>
>> On Fri, Aug 18, 2023 at 10:54 PM Hein Meling  wrote:
>>
>>> Hi all,
>>>
>>> I wanted to play around with the new range func CL
>>> .
>>>
>>> Doing simple stuff works just fine, but if I need to import packages to
>>> construct my custom iterator func, the go/gotip command insists on a go.mod
>>> file, which effectively resets the go version to 1.21.0 (due to go.mod),
>>> instead of the "(w/ rangefunc)" CL.
>>>
>>> Anyone know any workarounds for this?
>>>
>>> Thanks,
>>> :) Hein
>>>
>>> --
>>> You received this message because you are subscribed 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/f01ff376-b789-4d8a-89f5-165a6527325fn%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/09e1c142-0532-4d05-8dbe-6114fefdc2fdn%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/CAEkBMfG7821dpxwPeC9tgUNZYGdNfwneSQBcrdtnmaSPCLiSNA%40mail.gmail.com.


Re: [go-nuts] How to try out the new range func CL in a module

2023-08-21 Thread &#x27;Axel Wagner&#x27; via golang-nuts
Your `gotip` version seems to be at Go 1.21.0, not at the `rangefunc`
experiment CL. `gotip version` should say `go version devel
go1.21-ca691a8566 Tue Jul 18 10:30:20 2023 -0400 (w/ rangefunc)
linux/amd64` - regardless of the contents of the `go.mod`, as far as I
know. At least I can't reproduce it saying anything different by tinkering
with mine.

On Tue, Aug 22, 2023 at 12:51 AM Hein Meling  wrote:

> Thanks Axel for your reply. That's interesting. I'm able to run your
> example just fine. However, using a different go.mod file with the content
> below (and a longer code example with iteration over a LevelDB thing... not
> able to provide the code), I get:
>
> % gotip version
> go version go1.21.0 darwin/arm64
>
> % gotip run iter.go
> # command-line-arguments
> ./iter.go:48:25: cannot range over SnapshotHash(ldb, nonce) (value of type
> Seq2[uint64, error])
>
> module iter
>
> go 1.21.0
>
> require (
> github.com/opencoff/go-fasthash v0.0.0-20180406145558-aed761496075
> github.com/syndtr/goleveldb v1.0.0
> )
>
> require (
> github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db // indirect
> golang.org/x/net v0.10.0 // indirect
> golang.org/x/sys v0.11.0 // indirect
> golang.org/x/text v0.12.0 // indirect
> )
>
>
> On Sunday, August 20, 2023 at 10:59:20 PM UTC-7 Axel Wagner wrote:
>
>> Hm. For me, it still enables the rangefunc experiment, even though go.mod
>> says go 1.21:
>>
>> mero@vetinari ~/tmp/x$ gotip version
>> go version devel go1.21-ca691a8566d Tue Jul 18 10:30:20 2023 -0400 (w/
>> rangefunc) linux/amd64
>> mero@vetinari ~/tmp/x$ cat go.mod
>> module x
>>
>> go 1.21
>> mero@vetinari ~/tmp/x$ cat x.go
>> package main
>>
>> import "fmt"
>>
>> func main() {
>> s := []int{1, 2, 3}
>> for v := range All(s) {
>> fmt.Println(v)
>> }
>> }
>>
>> func All[T any](s []T) func(yield func(T) bool) bool {
>> return func(yield func(T) bool) bool {
>> for _, v := range s {
>> if !yield(v) {
>> return false
>> }
>> }
>> return true
>> }
>> }
>> mero@vetinari ~/tmp/x$ gotip run x.go
>> 1
>> 2
>> 3
>>
>> On Fri, Aug 18, 2023 at 10:54 PM Hein Meling  wrote:
>>
>>> Hi all,
>>>
>>> I wanted to play around with the new range func CL
>>> .
>>>
>>> Doing simple stuff works just fine, but if I need to import packages to
>>> construct my custom iterator func, the go/gotip command insists on a go.mod
>>> file, which effectively resets the go version to 1.21.0 (due to go.mod),
>>> instead of the "(w/ rangefunc)" CL.
>>>
>>> Anyone know any workarounds for this?
>>>
>>> Thanks,
>>> :) Hein
>>>
>>> --
>>> You received this message because you are subscribed 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/f01ff376-b789-4d8a-89f5-165a6527325fn%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/09e1c142-0532-4d05-8dbe-6114fefdc2fdn%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/CAEkBMfFL1jkoQAtfO1KAH7oyiqY%2B6x_dMXFoitnAoE%2BppoBnhA%40mail.gmail.com.


Re: [go-nuts] How to try out the new range func CL in a module

2023-08-20 Thread &#x27;Axel Wagner&#x27; via golang-nuts
Hm. For me, it still enables the rangefunc experiment, even though go.mod
says go 1.21:

mero@vetinari ~/tmp/x$ gotip version
go version devel go1.21-ca691a8566d Tue Jul 18 10:30:20 2023 -0400 (w/
rangefunc) linux/amd64
mero@vetinari ~/tmp/x$ cat go.mod
module x

go 1.21
mero@vetinari ~/tmp/x$ cat x.go
package main

import "fmt"

func main() {
s := []int{1, 2, 3}
for v := range All(s) {
fmt.Println(v)
}
}

func All[T any](s []T) func(yield func(T) bool) bool {
return func(yield func(T) bool) bool {
for _, v := range s {
if !yield(v) {
return false
}
}
return true
}
}
mero@vetinari ~/tmp/x$ gotip run x.go
1
2
3

On Fri, Aug 18, 2023 at 10:54 PM Hein Meling  wrote:

> Hi all,
>
> I wanted to play around with the new range func CL
> .
>
> Doing simple stuff works just fine, but if I need to import packages to
> construct my custom iterator func, the go/gotip command insists on a go.mod
> file, which effectively resets the go version to 1.21.0 (due to go.mod),
> instead of the "(w/ rangefunc)" CL.
>
> Anyone know any workarounds for this?
>
> Thanks,
> :) Hein
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/f01ff376-b789-4d8a-89f5-165a6527325fn%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/CAEkBMfEcs_jjH29FUA_sVd%2BFRbNPGy3Tq96kam7peSTVGfNgSA%40mail.gmail.com.


Re: [go-nuts] keyword= support for function calls

2023-08-17 Thread &#x27;Axel Wagner&#x27; via golang-nuts
The reason `os.Open` has not changed is because it doesn't have to change.
None of the features you mention really make sense for what it does. At
least that would be my interpretation. If you want to support your
interpretation, I would suggest digging up proposals to add those features
which got rejected because we didn't want to add more functions. That would
show that a lack of keyword arguments is to blame for a lack of `os.Open`
evolution, instead of a lack of need for evolution.

On the other hand, `net.Dial` empirically shows that it *is* possible to
use this approach to not add more functions, while expanding functionality.
Pre Go 1.0 there was only net.Dial. For Go 1.0, we determined that we would
want to be able to specify timeouts, so we added net.DialTimeout
. Then, for Go 1.1, we also wanted to specify a
local address to use. However, it became clear that it is not sustainable
to add more and more versions of a `Dial` function, so net.Dialer was added
in Go 1.1 . Since then, we have added
many more options to it . As adding fields
to a struct is backwards-compatible, we can add as many options as we like,
while still maintaining compatibility and not adding new package-scoped API
surface or functions.

The actual history of `net.Dial` strongly implies that if we *wanted* to
evolve `os.Open`, then what we would do is add a new struct type
`os.Opener`, with fields for all these optional features, which would then
have an `func (*Opener) Open(name string) (*File, error)` method. It's not
a perfect mechanism, but so far, it seems to have sufficed.

To be clear, if you feel strongly that we should support keyword arguments,
you can write and file a proposal to that effect. All I can say is that in
the past, this has come up repeatedly, but obviously has not been accepted.
So your case should better be strong - and in particular, it should
acknowledge the evidence and history we've built in over a decade. And you
might ultimately save yourself some frustration by instead adopting the
imperfect solutions we do have.

On Thu, Aug 17, 2023 at 7:32 AM Jon Perryman  wrote:

> The net.dialer solution you mention uses a struct which does not simplify.
> How does this get programmers out of the add another function mentality?
> GOLANG and C/C++ programmers have the same solution because it's not
> convenient to use a struct. Compare charts in C++ versus JavaScript. C++
> solution chose to implement 1,000 functions instead of using the struct as
> you suggest. JavaScript looked to the future and implemented it using the
> method that I'm proposing for GOLANG. The method I'm suggesting is so easy
> and convenient that people use it as seen with chartjs.
>
> Ask yourself why os.open() has remained unchanged since the beginning
> instead of expanding to include new features. Adding new features is
> extremely inconvenient. Using a struct is inconvenient.  Let's just add
> more functions.
>
> On Wed, Aug 16, 2023 at 9:14 PM Axel Wagner 
> wrote:
>
>> Have a look at net.Dialer . It is
>> essentially a struct that adds optional, keyword arguments to net.Dial
>> .
>>
>> On Thu, Aug 17, 2023 at 3:44 AM Jon Perryman 
>> wrote:
>>
>>> Struct does not solve the basic problem. In what way are you suggesting
>>> to solve the described os.open() changes? Should each API be seperate from
>>> os.open where it must be used with every read/write?
>>>
>>> On Wed, Aug 16, 2023 at 6:14 PM Kurtis Rader 
>>> wrote:
>>>
 Personally, and I say this as a happy user of Python, I dislike keyword
 parameters. Note that in Python keyword parameters are (or should be)
 seldom used for anything other than optional arguments. And if your API has
 so many parameters that they need names the API probably needs refactoring.
 Alternatively, pass a struct whose contents can be initialized using the
 struct member names.

 On Wed, Aug 16, 2023 at 6:04 PM Jon Perryman 
 wrote:

> Do you feel your GOLANG API implementations allows your API's
> and functions to evolve and grow? Personally, positional args has pissed 
> me
> off for years when a proven simple solution has never been adopted by most
> Unix programming languages (except Javascript). Most notably, it's missing
> from GOLANG.
>
> Everyone here understands and uses os.open from the os package.  For
> argument's sake, let's say os.open() is your responsibility to integrate
> nosql, memory files, compression, encryption, btree, key indexed files and
> more. How do you modify os.open( ) to integrate these file related
> features? This was solved years ago in languages not used in Unix
> using keyword arguments that also included positional. For example:
>
> func os.open(name string, memoryfile= bool, compress= bool, btree{
> btree_opto

Re: [go-nuts] keyword= support for function calls

2023-08-16 Thread &#x27;Axel Wagner&#x27; via golang-nuts
Have a look at net.Dialer . It is
essentially a struct that adds optional, keyword arguments to net.Dial
.

On Thu, Aug 17, 2023 at 3:44 AM Jon Perryman  wrote:

> Struct does not solve the basic problem. In what way are you suggesting to
> solve the described os.open() changes? Should each API be seperate from
> os.open where it must be used with every read/write?
>
> On Wed, Aug 16, 2023 at 6:14 PM Kurtis Rader  wrote:
>
>> Personally, and I say this as a happy user of Python, I dislike keyword
>> parameters. Note that in Python keyword parameters are (or should be)
>> seldom used for anything other than optional arguments. And if your API has
>> so many parameters that they need names the API probably needs refactoring.
>> Alternatively, pass a struct whose contents can be initialized using the
>> struct member names.
>>
>> On Wed, Aug 16, 2023 at 6:04 PM Jon Perryman 
>> wrote:
>>
>>> Do you feel your GOLANG API implementations allows your API's
>>> and functions to evolve and grow? Personally, positional args has pissed me
>>> off for years when a proven simple solution has never been adopted by most
>>> Unix programming languages (except Javascript). Most notably, it's missing
>>> from GOLANG.
>>>
>>> Everyone here understands and uses os.open from the os package.  For
>>> argument's sake, let's say os.open() is your responsibility to integrate
>>> nosql, memory files, compression, encryption, btree, key indexed files and
>>> more. How do you modify os.open( ) to integrate these file related
>>> features? This was solved years ago in languages not used in Unix
>>> using keyword arguments that also included positional. For example:
>>>
>>> func os.open(name string, memoryfile= bool, compress= bool, btree{
>>> btree_optons string }, encrypt{ key= string }, nosql{ nosql_options string
>>> } ) (*File, error)
>>> os.open('myfile.txt', encrypt{ key='abc' }, compress=true)
>>>
>>> The os.open args 1, 3 and 5 would be set from the specified arguments.
>>>
>>>  Is this something that others need and I should pursue or should I just
>>> forget it? Proposal https://github.com/golang/go/issues/62078 was
>>> closed with "I don't see anything concrete being proposed here.". If I
>>> should pursue this, should I reword it or reduce it to this Email?
>>>
>>> Thanks, Jon.
>>>
>>> --
>>> You received this message because you are subscribed to the Google
>>> Groups "golang-nuts" group.
>>> To unsubscribe from this group and stop receiving emails from it, send
>>> an email to golang-nuts+unsubscr...@googlegroups.com.
>>> To view this discussion on the web visit
>>> https://groups.google.com/d/msgid/golang-nuts/CAByJhJnkuai27VNiE6PraU9-5hoO85Hm__0UQJrT75a7KqD8uw%40mail.gmail.com
>>> 
>>> .
>>>
>>
>>
>> --
>> Kurtis Rader
>> Caretaker of the exceptional canines Junior and Hank
>>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/CAByJhJnTVs-gkQqnFtQ-kvJ%2Bqhnehij13hDh7yv4AoAXuxvKLg%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/CAEkBMfEi6hSGB87RNXdtQmP5dWkC8%2Bh%2B7R4L07GBbGa8GwCHsw%40mail.gmail.com.


Re: [go-nuts] Generic zero value for compiler optimization

2023-08-14 Thread &#x27;Axel Wagner&#x27; via golang-nuts
You might be interested in https://github.com/golang/go/issues/61372

On Mon, Aug 14, 2023 at 3:52 PM Diego Augusto Molina <
diegoaugustomol...@gmail.com> wrote:

> Hi, thank you for reading. Whenever I need to use a zero value for a
> generic type in a func I do something like the following:
>
> 
> func SetZero[T any](pt *T) T {
> var zeroT T
> *pt = zeroT
> }
> 
>
> That's all good, but I wonder how, if possible, it could be proved to the
> compiler that zeroT is the zero value for T. That would be to enable
> memclr optimization when bulk setting slice or array values to the zero
> value of their element type. Currently, as of 1.21, this only works when
> the src is a constant holding the zero value of the type. I also tried with
> something like *new(T), and it doesn't work either. But proving that the
> expression *new(T) in the src is the zero value for the type could
> potentially be easier than checking back if a certain variable (e.g. zeroT
> in the example) hasn't yet been reassigned or initialized to a non-zero
> value.
> Also, as there's no guarantee of what would T could hold, it could use
> memclrHasPointers if that makes sense, which seems like a fare tradeoff
> at least for now if we want to play with slices with generic element type.
> For reference, this is the code I'm trying:
>
> 
> package main
> // file generic_slice_element_type_memclr.go
>
> func clear[T any](s []T) {
> for i := range s {
> s[i] = *new(T)
> }
> }
>
> func main() {
> clear([]int{1, 2, 3})
> }
> 
>
> And I'm compiling it with:
>
> 
> $ go version
> go version go1.21.0 darwin/amd64
> $ go tool compile -S generic_slice_element_type_memclr.go
> ...
> 
>
> Kind regards.
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/b8ec1335-911c-42ed-96ce-a4b50153b8c9n%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/CAEkBMfF%2Bwu5zqF6_PQMDdDXKQEuVjH5ZDsQYqPXwXqgpmQ3JCQ%40mail.gmail.com.


  1   2   3   4   5   6   7   8   9   10   >