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

2024-05-06 Thread 'Axel Wagner' 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 'Axel Wagner' 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 'Axel Wagner' 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, ); 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-04-01 Thread 'Axel Wagner' 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 'Axel Wagner' 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 `[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?
>>>

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

2024-03-25 Thread 'Axel Wagner' 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 `[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:06 写道:
>>>>>>
>>>>>>> Have you tried running the code with the race detector enabled? I

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

2024-03-25 Thread 'Axel Wagner' 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 `[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 {
>>>>>> // ASCII fast path
>>>>>> i := 0
>

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

2024-03-21 Thread 'Axel Wagner' 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()).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 

Re: [go-nuts] Nillable basic types?

2024-03-20 Thread 'Axel Wagner' 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 'Axel Wagner' 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()).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 'Axel Wagner' 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 'Axel Wagner' 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) bool {
> return x == y
> }
>
> if the definition of == for empty st

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

2024-02-28 Thread 'Axel Wagner' 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 'Axel Wagner' 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 particular, for floating
>> point/complex type arguments, `==` is irreflexive (e.g

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

2024-02-27 Thread 'Axel Wagner' 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 

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

2024-02-26 Thread 'Axel Wagner' 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 = , 
>
> func main() {
> if (p == q) {
> p, q = , 
> 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 := {}
>> b := {}
>> fmt.Printf("%t\n", *a == *b)
>> fmt.Printf("%t\n", a == b)
>> fmt.Printf("%t\n", Bar(a) == Bar(b))
>>
>> c := {A: 1}
>> d := {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 'Axel Wagner' 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 = {}, {}
>   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 := {}
>>> b := {}
>>> fmt.Printf("%t\n", *a == *b)
>>> fmt.Printf("%t\n", a == b)
>>> fmt.Printf("%t\n", Bar(a) == Bar(b))
>>>
>>> c := {A: 1}
>>> d := {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 'Axel Wagner' 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 := {}
> b := {}
> 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  ==
>>> , 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 combinations 

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

2024-02-22 Thread 'Axel Wagner' 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 := {}
> b := {}
> fmt.Printf("%t\n", *a == *b)
> fmt.Printf("%t\n", a == b)
> fmt.Printf("%t\n", Bar(a) == Bar(b))
>
> c := {A: 1}
> d := {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 'Axel Wagner' 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 'Axel Wagner' 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 'Axel Wagner' 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 'Axel Wagner' 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
>   

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

2024-02-07 Thread 'Axel Wagner' 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 'Axel Wagner' 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().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 {
> Observation: [*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 'Axel Wagner' 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 'Axel Wagner' 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 'Axel Wagner' 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 'Axel Wagner' 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 'Axel Wagner' 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({}, 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 := {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 := {
>> 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]({}, 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 discussion on the web visit
> 

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

2023-12-29 Thread 'Axel Wagner' via golang-nuts
1. Note that you can just write `NewMessage({}, 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 := {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 := {
> 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]({}, 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 'Axel Wagner' 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 'Axel Wagner' 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 'Axel Wagner' 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 'Axel Wagner' 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 'Axel Wagner' 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 'Axel Wagner' 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_source=footer>
>>> .
>>>
>> --
>> You received this message beca

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

2023-10-24 Thread 'Axel Wagner' 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 'Axel Wagner' 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 'Axel Wagner' 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 

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

2023-10-20 Thread 'Axel Wagner' 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
> 

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

2023-10-18 Thread 'Axel Wagner' 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 

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

2023-10-17 Thread 'Axel Wagner' 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 

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

2023-10-17 Thread 'Axel Wagner' 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()
>> 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()
>> 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 'Axel Wagner' 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()
 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()
 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 'Axel Wagner' 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()
>>> 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()
>>> 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 message 

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

2023-10-15 Thread 'Axel Wagner' 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()
> 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()
> 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 'Axel Wagner' 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 'Axel Wagner' 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 'Axel Wagner' 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 'Axel Wagner' 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 'Axel Wagner' 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), , )
 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 

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

2023-10-08 Thread 'Axel Wagner' 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), , )
>> 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 'Axel Wagner' 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), , )
> 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 'Axel Wagner' via golang-nuts
I don't really understand your issue. You call
encrypted := secretbox.Seal(nonce[:], []byte(s), , )
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 'Axel Wagner' 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 

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

2023-10-03 Thread 'Axel Wagner' 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 'Axel Wagner' 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 'Axel Wagner' 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 'Axel Wagner' 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 'Axel Wagner' 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 

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

2023-09-30 Thread 'Axel Wagner' 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 

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

2023-09-30 Thread 'Axel Wagner' 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 'Axel Wagner' 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 'Axel Wagner' 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 'Axel Wagner' 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 'Axel Wagner' 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=gcs-url
>>> signer-prod%40golang-modproxy.iam.gserviceaccount.com
>>> =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 

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

2023-08-25 Thread 'Axel Wagner' 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=gcs-url
> signer-prod%40golang-modproxy.iam.gserviceaccount.com
> =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 'Axel Wagner' 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 'Axel Wagner' 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 'Axel Wagner' 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 'Axel Wagner' 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 'Axel Wagner' 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{
> 

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

2023-08-16 Thread 'Axel Wagner' 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 'Axel Wagner' 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.


Re: [go-nuts] Why does Go (so far) not have support for generators/ iterators for custom types ?

2023-08-06 Thread 'Axel Wagner' via golang-nuts
Small corrections:
1. in the first sentence, add an "early days Go"
2. In the second sentence, "now we do have *generics*", not iterators.

On Sun, Aug 6, 2023 at 11:35 AM Axel Wagner 
wrote:

> For one, Go did not have generic types or functions, which really limits
> the usefulness (and abilities to write) custom iterators in Go.
> Now we do have iterators, but it turns out there still are a lot of subtle
> Go-specific issues with how to support custom iterator types, which to be
> honest are too complicated to explain in an E-Mail. You can skim these
> discussions, to get an impression:
> https://github.com/golang/go/discussions/54245 (discussion, probably the
> first serious attempt)
> https://github.com/golang/go/discussions/56413 (discussion, follows from
> the previous one with a significantly simpler approach)
> https://github.com/golang/go/issues/61405 (proposal, from 3 weeks ago,
> currently actively discussed)
> If you decide to participate, I strongly recommend reading both the
> top-post (with the actual proposal) and the first comment (with an
> extensive summary of the discussion and FAQ).
>
> It's complicated.
>
> On Sun, Aug 6, 2023 at 10:05 AM Serge Hulne  wrote:
>
>> Why does Go (so far) not have support for generators/ iterators for
>> custom types ?
>>
>> I wrote this workaround:
>> https://github.com/serge-hulne/go_iter
>>
>> But I was wondering what lead to the idea of leaving iterators out in the
>> early days of the design of Go. What simplification of the language was
>> expected from leaving out iterators for custom types.
>>
>>
>> --
>> You received this message because you are subscribed to the Google 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/1fd9e5e8-8196-4bfb-910c-89ed461c42c5n%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/CAEkBMfGDJz6bYc3we2fu5gnw7fm6UBR6j7QA%3DeNtpOXoeRi2dg%40mail.gmail.com.


Re: [go-nuts] Why does Go (so far) not have support for generators/ iterators for custom types ?

2023-08-06 Thread 'Axel Wagner' via golang-nuts
For one, Go did not have generic types or functions, which really limits
the usefulness (and abilities to write) custom iterators in Go.
Now we do have iterators, but it turns out there still are a lot of subtle
Go-specific issues with how to support custom iterator types, which to be
honest are too complicated to explain in an E-Mail. You can skim these
discussions, to get an impression:
https://github.com/golang/go/discussions/54245 (discussion, probably the
first serious attempt)
https://github.com/golang/go/discussions/56413 (discussion, follows from
the previous one with a significantly simpler approach)
https://github.com/golang/go/issues/61405 (proposal, from 3 weeks ago,
currently actively discussed)
If you decide to participate, I strongly recommend reading both the
top-post (with the actual proposal) and the first comment (with an
extensive summary of the discussion and FAQ).

It's complicated.

On Sun, Aug 6, 2023 at 10:05 AM Serge Hulne  wrote:

> Why does Go (so far) not have support for generators/ iterators for custom
> types ?
>
> I wrote this workaround:
> https://github.com/serge-hulne/go_iter
>
> But I was wondering what lead to the idea of leaving iterators out in the
> early days of the design of Go. What simplification of the language was
> expected from leaving out iterators for custom types.
>
>
> --
> You received this message because you are subscribed to the Google 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/1fd9e5e8-8196-4bfb-910c-89ed461c42c5n%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/CAEkBMfFsjtfqeu9oJ8gUANvn%2BE-Hb2vyMmnQNV7fY6Sv800-cg%40mail.gmail.com.


Re: [go-nuts] Clarification on code snippet

2023-08-04 Thread 'Axel Wagner' via golang-nuts
Another relevant section is Calls  (emphasis
mine):

> A method call x.m() is valid if the method set of (the type of) x contains
> m and the argument list can be assigned to the parameter list of m. *If x
> is addressable and 's method set contains m, x.m() is shorthand for
> ().m()*:




On Fri, Aug 4, 2023 at 6:39 PM burak serdar  wrote:

>
>
> On Fri, Aug 4, 2023 at 10:33 AM alchemist vk 
> wrote:
>
>> Hi folks,
>>  In below code, I am invoking receiver api show() via a simple uInteger
>> type variable instead of pointer, by which it expects to be invoked . Go
>> being  strict with type casing and I was expecting a compiler error. But to
>> my surprise, it compiled and executed successfully.  Can you folks please
>> explain this behavior.
>>
>>
>>
>>
>>
>>
>>
>>
>> *package mainimport "fmt"type uInteger intfunc main() {var x uInteger
>> = 10x.show()*
>>
>
> Above, the variable x is addressable, so the compiler passes  to show().
>
> To call a pointer receiver method of a variable, that variable has to be
> addressable (it doesn't have to be a pointer), so the compiler knows how to
> pass the address of it. Here's how it is described in the spec:
>
> https://go.dev/ref/spec#Method_values
>
>
>>
>>
>>
>>
>> *}func (x *uInteger) show() {   fmt.Printf("In show, x = %d\n", *x)}*
>>
>> Thanks in Advance,
>> Venkatesh
>>
>> --
>> You received this message because you are subscribed to the Google 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/CAJr0cerqTGvQA56yQWVYW3F2Ms5vbwq3YyO%2But%3DzJ%2BM4rqf81A%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/CAMV2Rqq%2BZi7ioHi4PPXTmQ7du45LRJaEiSSWJpf1zeH%2Bq3Wjeg%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/CAEkBMfEaeUm3kRb6%2B6e5UMh_vx9RfQkCN7fiHGxtyDDQgU%3DGNQ%40mail.gmail.com.


Re: [go-nuts] Re: Amateur's questions about "Go lang spec"

2023-08-02 Thread 'Axel Wagner' via golang-nuts
o back to reading Go Spec.
>>>>>>>>
>>>>>>>> In the section "Expression statements" we read that "The following
>>>>>>>> built-in functions are not permitted in statement context:
>>>>>>>>
>>>>>>>> append cap complex imag len make new real
>>>>>>>> unsafe.Add unsafe.Alignof unsafe.Offsetof unsafe.Sizeof unsafe.Slice
>>>>>>>>
>>>>>>>> h(x+y)
>>>>>>>> f.Close()
>>>>>>>> <-ch
>>>>>>>> (<-ch)
>>>>>>>> len("foo")  // illegal if len is the built-in function"
>>>>>>>>
>>>>>>>> Are things following "h(x+y)" also forbidden in the statement
>>>>>>>> context? This part of spec isn't specially clear in my opinion.
>>>>>>>>
>>>>>>>
>>>>>>> No, they are not. Otherwise, they'd have a comment following them
>>>>>>> saying "illegal for $reason".
>>>>>>>
>>>>>>>
>>>>>>>>
>>>>>>>> Best regards,
>>>>>>>> Kamil
>>>>>>>> poniedziałek, 12 czerwca 2023 o 02:02:27 UTC+2 Rob Pike napisał(a):
>>>>>>>>
>>>>>>>>> Although the sentence is OK as it stands, the section should be
>>>>>>>>> tweaked a bit. One of the examples there (myString(0x65e5)) is valid 
>>>>>>>>> Go but
>>>>>>>>> vet rejects it, as part of the move towards disallowing this 
>>>>>>>>> conversion,
>>>>>>>>> which was there mostly for bootstrapping the libraries.
>>>>>>>>>
>>>>>>>>> -rob
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> On Mon, Jun 12, 2023 at 3:10 AM 'Axel Wagner' via golang-nuts <
>>>>>>>>> golan...@googlegroups.com> wrote:
>>>>>>>>>
>>>>>>>>>> Ah, the spec does actually say:
>>>>>>>>>>>
>>>>>>>>>>> Converting a signed or unsigned integer value to a string type
>>>>>>>>>>> yields a string containing the UTF-8 representation of the integer. 
>>>>>>>>>>> Values
>>>>>>>>>>> outside the range of valid Unicode code points are converted to 
>>>>>>>>>>> "\uFFFD".
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> Personally, I think this is fine as is. I think people understand
>>>>>>>>>> what happens from these two sentences.
>>>>>>>>>>
>>>>>>>>>> On Sun, Jun 11, 2023 at 7:02 PM Axel Wagner <
>>>>>>>>>> axel.wa...@googlemail.com> wrote:
>>>>>>>>>>
>>>>>>>>>>> I'm not entirely sure. I don't think your phrasing is correct,
>>>>>>>>>>> as it doesn't represent what happens if the integer value exceeds 
>>>>>>>>>>> the range
>>>>>>>>>>> of valid codepoints (i.e. if it needs more than 32 bits to 
>>>>>>>>>>> represent). That
>>>>>>>>>>> being said, the sentence as is also isn't really precise about it. 
>>>>>>>>>>> From
>>>>>>>>>>> what I can tell, the result is not valid UTF-8 in any case.
>>>>>>>>>>>
>>>>>>>>>>> I think it might make sense to file an issue about this, though
>>>>>>>>>>> in general that conversion is deprecated anyway and gets flagged by 
>>>>>>>>>>> `go
>>>>>>>>>>> vet` (and `go test`) because it is not what's usually expected. So 
>>>>>>>>>>> I'm not
>>>>>>>>>>> sure how important it is to get this exactly right and 
>>>>>>>>>>> understandable.
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> On

Re: [go-nuts] Re: Amateur's questions about "Go lang spec"

2023-07-28 Thread 'Axel Wagner' via golang-nuts
Note also, that you didn't paste the entire section:

With the exception of specific built-in functions, function and method
calls and receive operations can appear in statement context. Such
statements may be parenthesized. […] The following built-in functions are
not permitted in statement context:

This is IMO very clear about those other examples being allowed.

On Fri, Jul 28, 2023 at 4:42 PM Axel Wagner 
wrote:

>
>
> On Fri, Jul 28, 2023 at 4:04 PM Kamil Ziemian 
> wrote:
>
>> Hello,
>>
>> After a long break, I go back to reading Go Spec.
>>
>> In the section "Expression statements" we read that "The following
>> built-in functions are not permitted in statement context:
>>
>> append cap complex imag len make new real
>> unsafe.Add unsafe.Alignof unsafe.Offsetof unsafe.Sizeof unsafe.Slice
>>
>> h(x+y)
>> f.Close()
>> <-ch
>> (<-ch)
>> len("foo")  // illegal if len is the built-in function"
>>
>> Are things following "h(x+y)" also forbidden in the statement context?
>> This part of spec isn't specially clear in my opinion.
>>
>
> No, they are not. Otherwise, they'd have a comment following them saying
> "illegal for $reason".
>
>
>>
>> Best regards,
>> Kamil
>> poniedziałek, 12 czerwca 2023 o 02:02:27 UTC+2 Rob Pike napisał(a):
>>
>>> Although the sentence is OK as it stands, the section should be tweaked
>>> a bit. One of the examples there (myString(0x65e5)) is valid Go but vet
>>> rejects it, as part of the move towards disallowing this conversion, which
>>> was there mostly for bootstrapping the libraries.
>>>
>>> -rob
>>>
>>>
>>> On Mon, Jun 12, 2023 at 3:10 AM 'Axel Wagner' via golang-nuts <
>>> golan...@googlegroups.com> wrote:
>>>
>>>> Ah, the spec does actually say:
>>>>>
>>>>> Converting a signed or unsigned integer value to a string type yields
>>>>> a string containing the UTF-8 representation of the integer. Values 
>>>>> outside
>>>>> the range of valid Unicode code points are converted to "\uFFFD".
>>>>
>>>>
>>>> Personally, I think this is fine as is. I think people understand what
>>>> happens from these two sentences.
>>>>
>>>> On Sun, Jun 11, 2023 at 7:02 PM Axel Wagner 
>>>> wrote:
>>>>
>>>>> I'm not entirely sure. I don't think your phrasing is correct, as it
>>>>> doesn't represent what happens if the integer value exceeds the range of
>>>>> valid codepoints (i.e. if it needs more than 32 bits to represent). That
>>>>> being said, the sentence as is also isn't really precise about it. From
>>>>> what I can tell, the result is not valid UTF-8 in any case.
>>>>>
>>>>> I think it might make sense to file an issue about this, though in
>>>>> general that conversion is deprecated anyway and gets flagged by `go vet`
>>>>> (and `go test`) because it is not what's usually expected. So I'm not sure
>>>>> how important it is to get this exactly right and understandable.
>>>>>
>>>>>
>>>>> On Sun, Jun 11, 2023 at 5:17 PM Kamil Ziemian 
>>>>> wrote:
>>>>>
>>>>>> I have some hair splitting question. In the "Conversions to and from
>>>>>> a string type" we read:
>>>>>> "Converting a signed or unsigned integer value to a string type
>>>>>> yields a string containing the UTF-8 representation of the integer."
>>>>>>
>>>>>> Would it be more corrected to say, that conversion from integer to
>>>>>> string gives you UTF-8 representation of code point described by value of
>>>>>> the integer? Or maybe it is indeed representation of integer described by
>>>>>> UTF-8 specification?
>>>>>>
>>>>>> Best regards,
>>>>>> Kamil
>>>>>> czwartek, 28 października 2021 o 19:33:27 UTC+2 Kamil Ziemian
>>>>>> napisał(a):
>>>>>>
>>>>>>> Hello,
>>>>>>>
>>>>>>> From what I understand proper Gopher read at least one time "The Go
>>>>>>> Programming Language Specification" (https://golang.org/ref/spec)
>>>>>>> and now I need to read it too.
>>>>>>>
>>>

Re: [go-nuts] Re: Amateur's questions about "Go lang spec"

2023-07-28 Thread 'Axel Wagner' via golang-nuts
On Fri, Jul 28, 2023 at 4:04 PM Kamil Ziemian  wrote:

> Hello,
>
> After a long break, I go back to reading Go Spec.
>
> In the section "Expression statements" we read that "The following
> built-in functions are not permitted in statement context:
>
> append cap complex imag len make new real
> unsafe.Add unsafe.Alignof unsafe.Offsetof unsafe.Sizeof unsafe.Slice
>
> h(x+y)
> f.Close()
> <-ch
> (<-ch)
> len("foo")  // illegal if len is the built-in function"
>
> Are things following "h(x+y)" also forbidden in the statement context?
> This part of spec isn't specially clear in my opinion.
>

No, they are not. Otherwise, they'd have a comment following them saying
"illegal for $reason".


>
> Best regards,
> Kamil
> poniedziałek, 12 czerwca 2023 o 02:02:27 UTC+2 Rob Pike napisał(a):
>
>> Although the sentence is OK as it stands, the section should be tweaked a
>> bit. One of the examples there (myString(0x65e5)) is valid Go but vet
>> rejects it, as part of the move towards disallowing this conversion, which
>> was there mostly for bootstrapping the libraries.
>>
>> -rob
>>
>>
>> On Mon, Jun 12, 2023 at 3:10 AM 'Axel Wagner' via golang-nuts <
>> golan...@googlegroups.com> wrote:
>>
>>> Ah, the spec does actually say:
>>>>
>>>> Converting a signed or unsigned integer value to a string type yields a
>>>> string containing the UTF-8 representation of the integer. Values outside
>>>> the range of valid Unicode code points are converted to "\uFFFD".
>>>
>>>
>>> Personally, I think this is fine as is. I think people understand what
>>> happens from these two sentences.
>>>
>>> On Sun, Jun 11, 2023 at 7:02 PM Axel Wagner 
>>> wrote:
>>>
>>>> I'm not entirely sure. I don't think your phrasing is correct, as it
>>>> doesn't represent what happens if the integer value exceeds the range of
>>>> valid codepoints (i.e. if it needs more than 32 bits to represent). That
>>>> being said, the sentence as is also isn't really precise about it. From
>>>> what I can tell, the result is not valid UTF-8 in any case.
>>>>
>>>> I think it might make sense to file an issue about this, though in
>>>> general that conversion is deprecated anyway and gets flagged by `go vet`
>>>> (and `go test`) because it is not what's usually expected. So I'm not sure
>>>> how important it is to get this exactly right and understandable.
>>>>
>>>>
>>>> On Sun, Jun 11, 2023 at 5:17 PM Kamil Ziemian 
>>>> wrote:
>>>>
>>>>> I have some hair splitting question. In the "Conversions to and from a
>>>>> string type" we read:
>>>>> "Converting a signed or unsigned integer value to a string type yields
>>>>> a string containing the UTF-8 representation of the integer."
>>>>>
>>>>> Would it be more corrected to say, that conversion from integer to
>>>>> string gives you UTF-8 representation of code point described by value of
>>>>> the integer? Or maybe it is indeed representation of integer described by
>>>>> UTF-8 specification?
>>>>>
>>>>> Best regards,
>>>>> Kamil
>>>>> czwartek, 28 października 2021 o 19:33:27 UTC+2 Kamil Ziemian
>>>>> napisał(a):
>>>>>
>>>>>> Hello,
>>>>>>
>>>>>> From what I understand proper Gopher read at least one time "The Go
>>>>>> Programming Language Specification" (https://golang.org/ref/spec)
>>>>>> and now I need to read it too.
>>>>>>
>>>>>> I learn something of Extended Backus-Naur Form to understand it, so
>>>>>> if I say something stupid beyond belief, I hope you will forgive me. In 
>>>>>> the
>>>>>> first part "Notation" (https://golang.org/ref/spec#Notation) I
>>>>>> believe that I understand meaning of all concepts except of
>>>>>> "production_name". On one hand "production_name" means that it is name of
>>>>>> the production, not rocket science here. On the other, after reading 
>>>>>> about
>>>>>> EBNF I feel that I should have more information about it. Can you explain
>>>>>> it to me?
>>>>>>
>>>>>> Aga

Re: [go-nuts] Re: Generics and "static" adapters

2023-07-28 Thread 'Axel Wagner' via golang-nuts
Why not remove the `recordFactory` type then?

type Record interface {
Key() string
Marshal() []byte
Unmarshal([]byte) error
}

func put[R Record](db *SimpleDatabase,  t UpdateTransaction, v R) error {
k := v.Key()
b := v.Marshal()
if err := db.put(t, k, b); err != nil {
return fmt.Errorf("db error: %w", err)
}
return nil
}

You might need to do the Pointer Receiver Trick (not sure if there's an FAQ
entry to link to here, so I'll just link to my not super great talk
 explaining it) to implement get, i.e.:

type Record[T any] interface {
*T
Key() string
Marshal() []byte
Unmarshal([]byte) error
}

func get[R any, PR[R]](db *SimpleDatabase, t ViewTransaction) (R, error) {
var r R
k := PR().Key()
b, err := db.get(t, k)
if err != nil {
return r, err
}
err = PR().Unmarshal(b)
return r, err
}

(Note: This assumes that the `Key() string` method is still stateless, but
ISTM your factory type assumes that as well?)

On Fri, Jul 28, 2023 at 10:48 AM Salvatore Domenick Desiano <
neard...@gmail.com> wrote:

> I guess I didn't ask an actual question... is there a more idiomatic way
> of doing this?
>
> Thank you!
>
> -- Salvatore
> smile.
>
>
> On Monday, July 24, 2023 at 4:00:59 PM UTC-4 Salvatore Domenick Desiano
> wrote:
>
>> Ever since 1.18 came out I've been struggling to find an idiomatic way to
>> implement a certain kind of adapter. I'm starting to suspect I'm Holding It
>> Wrong (TM) so here I am.
>>
>> In short, I have an adapter that is effectively a collection of static
>> methods and it doesn't look right.
>>
>> Imagine you have a generic key-value database (transaction and life-cycle
>> methods omitted for brevity):
>>
>> type SimpleDatabase interface {
>> Get(t ViewTransaction, key string) ([]byte, bool, error)
>> Put(t UpdateTransaction, key string, value []byte) error
>> }
>>
>> You then want to build something more specific on top using generics to
>> avoid repetition of tricky code:
>>
>> type ApplicationDatabase struct {
>>   impl *SimpleDatabase
>> }
>>
>> func (db *ApplicationDatabase) PutProjectRecord(t UpdateTransaction, r
>> *ProjectRecord) error {
>>   return put[ProjectRecord](db.impl, projectRecordFactory, t, r)
>> }
>>
>> type recordFactory[V any] interface {
>>   dbKey(value V) string
>>   encodeValue(value V) []byte
>>   decodeValue(data []byte) (V, error)
>> }
>>
>> func put[V any](db *SimpleDatabase, f *recordFactory[V], t
>> UpdateTransaction, value V) error {
>>   key := f.dbKey(value)
>>   valueBytes := f.encodeValue(value)
>>   if err := db.put(t, key, valueBytes); err != nil
>> return fmt.Errorf("db error: %w", err)
>>   }
>>   return nil
>> }
>>
>> This is nice and clean -- adding a new record type is just a matter of
>> adding a new recordFactory implementation. Adding more complexity to the
>> put/get (recovery, etc.) only has to happen once. The part that bugs me,
>> though, is that the implementation has no state and really looks like it
>> shouldn't be instantiated:
>>
>> type projectRecordFactory struct{}
>> func (f *projectRecordFactory) dbKey() string { return  }
>> func (f *projectRecordFactory) encodeValue(value V) []byte {
>> json.Marshal(...) }
>> func (f *projectRecordFactory) decodeValue(data []byte) (V, error) {
>> json.Unmarshal(...) }
>>
>> and, frankly, if I didn't instantiate it, it would feel like either Java
>> or C++ metaprogramming.
>>
>> I'm open to a completely different structure but I am really hoping to
>> add new record types by adding a new package or type.
>>
>> Thanks!
>>
>> -- Salvatore
>> smile.
>>
>> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/318e98c2-d13e-4188-b65b-bbc7644e3ab7n%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/CAEkBMfFLJYt9N8fvMALfthk-s7q2WTE3yKx95u7puwDEfA5p5g%40mail.gmail.com.


Re: [go-nuts] Re: error handling thoughts

2023-07-27 Thread 'Axel Wagner' via golang-nuts
It's not a compiler error, but OP is probably referring to golint.
FWIW I also prefer the `if v, err := fn(); err != nil { … }` form, in
general, but in cases like these I just write

v, err := fn()
if err != nil {
// handle error and return
}
// do thing with v

I honestly don't see a huge problem with that.

On Thu, Jul 27, 2023 at 5:34 PM Stephen Illingworth <
stephen.illingwo...@gmail.com> wrote:

> Hi Steve,
>
> What's the compiler error that you're seeing?
>
> Here's a go playground example of your scenario. It doesn't seem to cause
> any issues but maybe I'm misunderstanding.
>
> https://go.dev/play/p/vvtrQTl7FSr
>
> Regards, Stephen
>
> On Thursday, 27 July 2023 at 16:04:19 UTC+1 Steve Roth wrote:
>
>> The ongoing Go survey asked a question about satisfaction with error
>> handling in Go.  I'd like to express an opinion on it that I haven't seen
>> elsewhere, for which there was not room in the survey.
>>
>> I am generally a fan of the explicit error handling code in Go, but I get
>> frustrated by the interactions between error handling, := assignments, and
>> compiler warnings.  My preferred way of writing the standard clause is
>>
>> if err := fn(); err != nil {
>>
>> // handle error and bail out
>> }
>>
>>
>> However, often the function in question returns a result I want to work
>> with.  If it's something important for the whole rest of the function, I'll
>> probably just define it as a variable at function scope:
>>
>> var (
>>
>> result sometype
>>
>> err error
>> )
>> // ...
>>
>> if result, err = fn(); err != nil {
>>
>> // handle error and bail out
>> }
>>
>> // act on result
>>
>>
>> But often, the result is something I'm only going to use for one
>> statement and is not a variable of significance to the whole function.
>> Those are the sorts of cases that := is best for, in my opinion.  In those
>> cases, what I'd like to write is
>>
>> if result, err := fn(); err != nil {
>>
>> // handle error and bail out
>>
>> } else {
>>
>> // act on result
>> }
>>
>>
>> Unfortunately, the compiler gives a warning on that.  Because the truth
>> clause bailed out (e.g., "return"), it insists that I remove the else and
>> turn the code into
>>
>> if result, err := fn(); err != nil {
>>
>> // handle error and bail out
>>
>> }
>>
>> // act on result
>>
>>
>> But that doesn't compile because result is no longer in scope.
>>
>> What I often wind up doing instead is
>>
>> if result, err = fn(); err == nil {
>>
>> // act on result
>>
>> } else {
>>
>> // handle error and bail out
>> }
>>
>>
>> That works, but it leaves my code with a mixture of "handle error case
>> first, then success" and "handle success case first, then error" patterns,
>> which I find adds a lot to cognitive load.
>>
>> I have no idea whether others share my frustration on this admittedly
>> minor point.  But since the survey prodded me, I thought I would voice it
>> and see what reactions it gets.  For me, the ideal solution would be to
>> suppress the compiler warning about removing the else, when doing so would
>> break the code altogether.
>>
>> Regards,
>> Steve
>>
>> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/3a98bae6-8ca9-49d4-8a32-c95ae8863baen%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/CAEkBMfEG8its5mq2mkJguhRNhGFh%2BPfbm7a2FBQQPq0uJT%2Bq0w%40mail.gmail.com.


Re: [go-nuts] testing whether two maps are the same object

2023-07-19 Thread 'Axel Wagner' via golang-nuts
On Tue, Jul 18, 2023 at 5:22 PM Jochen Voss  wrote:

> Dear Jason,
>
> Thanks for the idea of using reflect.  Do you know whether
> `reflect.ValueOf(a).UnsafePointer()` is somehow "safer" than
> `*(*uintptr)(unsafe.Pointer())`?
>

For what it's worth: I'd argue comparing
`reflect.ValueOf(a).UnsafePointer()` provides stronger guarantees of
portability and correctness than comparing
`*(*uintptr)(unsafe.Pointer())`. Also, you should probably use
`*(*unsafe.Pointer)(unsafe.Pointer())` if anything. It does the same
thing, when it works, but I'm not sure that the conversion to `uintptr`
that is happening is guaranteed to work under a moving GC. A comparison
isn't necessarily arithmetic  - and
those rules are just what `gc` is specifying anyways, an implementation is
free to choose others, in theory.

That's because the latter relies on maps being "pointer-shaped". In theory,
an implementation might not represent a map as a plain pointer. Though I
admittedly having trouble coming up with an alternative design.

Plus, the documentation  of
`reflect.Value.UnsafePointer` *also* doesn't really say *what* the returned
pointer is for a map and what its semantics are. But it seems somewhat
safer to assume that an implementation that would *not* represent a map as
a plain pointer, would implement `reflect.Value.UnsafePointer` in a way
that still allowed you to compare them for identity purposes.

But, as you might be able to tell, all of this is a bit of a nitpick of how
willing you are to make assumptions about reasonable ways an implementation
might deviate from what they *have* to do. I'm pretty sure there is no way
to compare map values that is keeping *strictly* in the bounds of
well-defined behavior. I would, personally, feel comfortable using either
and to just assume that I never have to run my code in a sufficiently wild
implementation. And I'd probably try to benchmark/test if the `reflect`
based version changes performance characteristics (I would assume it makes
it easier for the map to escape, but maybe maps *always* escape anyways)
and if not, use `reflect`.


> reflect.DeepEqual will not work, since it just compares contents of the
> maps: https://go.dev/play/p/tE_qZI2cKEd
>
> All the best,
> Jochen
> On Tuesday, 18 July 2023 at 15:52:24 UTC+1 Jason Phillips wrote:
>
>> You can also use the reflect package rather than (directly) reaching for
>> unsafe. The reflect.DeepEqual function does something along the lines of:
>> https://go.dev/play/p/IVt0Z-mxugh
>>
>> On Tuesday, July 18, 2023 at 10:45:18 AM UTC-4 Jan Mercl wrote:
>>
>>> On Tue, Jul 18, 2023 at 4:35 PM Jochen Voss  wrote:
>>>
>>> > Is there a better way?
>>>
>>> I have never been here and please don't do this:
>>> https://go.dev/play/p/x4QYJubXMnQ
>>>
>> --
> You received this message because you are subscribed to the Google 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/30202b52-554e-462e-aaa4-dfe7f4d23554n%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/CAEkBMfGSn7D4My8HgW97RZ95kdDH-2UFUasQS9R87aN--ZGJ%2BQ%40mail.gmail.com.


Re: [go-nuts] Go 1.21 new builtin function clear()

2023-07-06 Thread 'Axel Wagner' via golang-nuts
On Thu 6. Jul 2023 at 09:41, Henry  wrote:

> 'make' allocates the required memory.


Does it? What about channels and maps?

'len' returns the length.


What’s the “length” of a channel? What’s the “length” of a map?

'cap' returns the capacity.


For maps?

These questions are rhetorical, for what it’s worth. I understand how the
language works, I just try to illustrate that brushing aside these
differences is like me saying “clear clears it’s argument”.

The underlying implementation may be different, but the concept is the
> same. There is no issue with those.
>
> It is common for a collection to have methods such as 'Add', 'Delete', and
> 'Clear'. The common interpretation of clearing a collection means removing
> all items from the collection and setting its length to zero. Clear works
> like that with map, but it does differently with slice. I would not say
> replacing the values in a slice with the default values as clearing. Maybe
> you can call that zeroing, but that's not clearing. Many people would
> expect after calling 'Clear(slice)' then the slice length should be zero.
> That's why I think the function is incoherent.
>

Note that this has been discussed on the issue, as far as I remember.
Nothing of what you say is wrong. But there are counterpoints. For example,
there is no precedence for a function (prefects red or not) that takes a
slice and modifies it. For example, append has to return a modified slice.
So I don’t think it really is right to say “people would expect the length
of a to be zero after clear(a)”. I think they would be differently
surprised.

But really, I’m not super sold on the final semantics of clear either. But
these questions have been considered.


> On Thursday, July 6, 2023 at 1:17:39 PM UTC+7 Axel Wagner wrote:
>
>> Oh and FWIW: You are right (in my opinion) that the different things
>> `clear` does are, well, different. But note that clear is not the only
>> builtin for which that is the case. `make`, `len` and `cap` all do
>> different things (to varying degrees) on maps, slices and channels.
>> That's not necessarily a good reason to add more builtins that do
>> different things, but there is precedent.
>>
>> On Thu, Jul 6, 2023 at 8:14 AM Axel Wagner 
>> wrote:
>>
>>> On Thu, Jul 6, 2023 at 7:49 AM Henry  wrote:
>>>
>> So, if I get this right, clear on map will result in map length equals to
 zero, but clear on slice is only a value-zeroing operation and the slice
 length remains unchanged?
>>>
>>>
>>> That understanding is correct.
>>>
>>>
 They seem like two different operations to me. I don't think that
 built-in clear function is necessary. It doesn't seem like the function has
 a good reason to be there.

>>>
>>> There is one thing that `clear` allows which is impossible without it
>>> and that's removing irreflexive keys (those that contain floating point
>>> types/elements/fields which are NaN) from a map.
>>>
>>> Whether that's a "good" reason is up for debate, of course. There has
>>> been quite a bit of that in the issue already:
>>> https://github.com/golang/go/issues/56351
>>>
>>>
>>
 On Wednesday, July 5, 2023 at 3:54:43 PM UTC+7 Tharaneedharan
 Vilwanathan wrote:

> Hi Axel,
>
> Okay, that helps! Thanks for the details.
>
> Regards
> dharani
>
>
> On Wed, Jul 5, 2023 at 1:38 AM Axel Wagner 
> wrote:
>
>> Hi,
>>
>> this has come up on the issue as well. Robert Griesemer provided an
>> explanation
>> :
>>
>> If the argument type (the type of the argument provided to clear) is
>>> a type parameter (is of type parameter type), all types in its type set 
>>> (in
>>> the type set of the constraint corresponding to the type parameter) 
>>> must be
>>> maps or slices, and clear performs the operation corresponding to the
>>> actual type argument (corresponding to the type of the actual type 
>>> argument
>>> with which the type parameter was instantiated).
>>
>>
>> That is, the sentence is about this situation:
>>
>> func Clear[T, any, S ~[]T](s S) {
>> clear(s)
>> }
>> func main() {
>> Clear(make([]int, 42))
>> }
>>
>> In this case, the type of s is S, which is a type parameter. So
>> `clear` performs the operation corresponding to the type argument - in 
>> this
>> example []int.
>>
>> The sentence is a bit confusing (I've seen this question come up four
>> times now), so it probably should be clarified a bit.
>>
>> On Wed, Jul 5, 2023 at 9:06 AM Tharaneedharan Vilwanathan <
>> vdha...@gmail.com> wrote:
>>
>>> Hi All,
>>>
>>> Go 1.21 introduces a new clear() builtin function. I see this text
>>> in https://tip.golang.org/ref/spec#Clear:
>>>
>>> clear(t) type parameter see below
>>>
>>> If the argument type is a type 

Re: [go-nuts] Where are closure storing the captured variables ?

2023-07-06 Thread 'Axel Wagner' via golang-nuts
It depends a bit on escape analysis. I think the easiest way to reason
about it is to say that they are stored in the `func` value. If the `func`
value escapes, than so do the closed-over variables. If it doesn't (and the
closed-over variables are not otherwise escaped) they don't. At least to an
approximation.

The precise details of how closures are implemented are described in this
document:
https://docs.google.com/document/d/1bMwCey-gmqZVTpRax-ESeVuZGmjwbocYs1iHplK-cjo/pub
I don't think anything material has changed since then.

On Thu, Jul 6, 2023 at 2:35 AM christo...@meessen.net <
christo...@meessen.net> wrote:

> Hello,
>
> Closure need space to store the captured variables. According to
> runtime.MemStats, it is not on the heap. Where are these variable stored ?
> On the stack ?
>
> --
> You received this message because you are subscribed to the Google 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/dd7074fc-670d-4bb3-9b88-51af65d23d45n%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/CAEkBMfE8co8oxPw38cP2KurDtGawm75v4OkfMoj95ZR%2BeRge-w%40mail.gmail.com.


Re: [go-nuts] Go 1.21 new builtin function clear()

2023-07-06 Thread 'Axel Wagner' via golang-nuts
Oh and FWIW: You are right (in my opinion) that the different things
`clear` does are, well, different. But note that clear is not the only
builtin for which that is the case. `make`, `len` and `cap` all do
different things (to varying degrees) on maps, slices and channels.
That's not necessarily a good reason to add more builtins that do different
things, but there is precedent.

On Thu, Jul 6, 2023 at 8:14 AM Axel Wagner 
wrote:

> On Thu, Jul 6, 2023 at 7:49 AM Henry  wrote:
>
>> So, if I get this right, clear on map will result in map length equals to
>> zero, but clear on slice is only a value-zeroing operation and the slice
>> length remains unchanged?
>
>
> That understanding is correct.
>
>
>> They seem like two different operations to me. I don't think that
>> built-in clear function is necessary. It doesn't seem like the function has
>> a good reason to be there.
>>
>
> There is one thing that `clear` allows which is impossible without it and
> that's removing irreflexive keys (those that contain floating point
> types/elements/fields which are NaN) from a map.
>
> Whether that's a "good" reason is up for debate, of course. There has been
> quite a bit of that in the issue already:
> https://github.com/golang/go/issues/56351
>
>
>>
>> On Wednesday, July 5, 2023 at 3:54:43 PM UTC+7 Tharaneedharan Vilwanathan
>> wrote:
>>
>>> Hi Axel,
>>>
>>> Okay, that helps! Thanks for the details.
>>>
>>> Regards
>>> dharani
>>>
>>>
>>> On Wed, Jul 5, 2023 at 1:38 AM Axel Wagner 
>>> wrote:
>>>
 Hi,

 this has come up on the issue as well. Robert Griesemer provided an
 explanation
 :

 If the argument type (the type of the argument provided to clear) is a
> type parameter (is of type parameter type), all types in its type set (in
> the type set of the constraint corresponding to the type parameter) must 
> be
> maps or slices, and clear performs the operation corresponding to the
> actual type argument (corresponding to the type of the actual type 
> argument
> with which the type parameter was instantiated).


 That is, the sentence is about this situation:

 func Clear[T, any, S ~[]T](s S) {
 clear(s)
 }
 func main() {
 Clear(make([]int, 42))
 }

 In this case, the type of s is S, which is a type parameter. So `clear`
 performs the operation corresponding to the type argument - in this example
 []int.

 The sentence is a bit confusing (I've seen this question come up four
 times now), so it probably should be clarified a bit.

 On Wed, Jul 5, 2023 at 9:06 AM Tharaneedharan Vilwanathan <
 vdha...@gmail.com> wrote:

> Hi All,
>
> Go 1.21 introduces a new clear() builtin function. I see this text in
> https://tip.golang.org/ref/spec#Clear:
>
> clear(t) type parameter see below
>
> If the argument type is a type parameter
> , all
> types in its type set must be maps or slices, and clear performs the
> operation corresponding to the actual type argument.
>
> I am not able to make sense of it. What does this mean? Any examples
> on the usage?
>
> Appreciate your help.
>
> Thanks
> dharani
>
> --
> You received this message because you are subscribed to the Google
> Groups "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send
> an email to golang-nuts...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/CAN-HoCn99D-m71aJr3DRzCJvk_c7h8OhG2O4wPC-1Wd2ruEYNg%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/00e424f1-1a62-4183-8974-9a585960ce7dn%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/CAEkBMfEsZ67fQEqOPMNEj%3Dgz5Y%2Bz5kgjPSHR8casGvt8YzaFuw%40mail.gmail.com.


Re: [go-nuts] Go 1.21 new builtin function clear()

2023-07-06 Thread 'Axel Wagner' via golang-nuts
On Thu, Jul 6, 2023 at 7:49 AM Henry  wrote:

> So, if I get this right, clear on map will result in map length equals to
> zero, but clear on slice is only a value-zeroing operation and the slice
> length remains unchanged?


That understanding is correct.


> They seem like two different operations to me. I don't think that built-in
> clear function is necessary. It doesn't seem like the function has a good
> reason to be there.
>

There is one thing that `clear` allows which is impossible without it and
that's removing irreflexive keys (those that contain floating point
types/elements/fields which are NaN) from a map.

Whether that's a "good" reason is up for debate, of course. There has been
quite a bit of that in the issue already:
https://github.com/golang/go/issues/56351


>
> On Wednesday, July 5, 2023 at 3:54:43 PM UTC+7 Tharaneedharan Vilwanathan
> wrote:
>
>> Hi Axel,
>>
>> Okay, that helps! Thanks for the details.
>>
>> Regards
>> dharani
>>
>>
>> On Wed, Jul 5, 2023 at 1:38 AM Axel Wagner 
>> wrote:
>>
>>> Hi,
>>>
>>> this has come up on the issue as well. Robert Griesemer provided an
>>> explanation
>>> :
>>>
>>> If the argument type (the type of the argument provided to clear) is a
 type parameter (is of type parameter type), all types in its type set (in
 the type set of the constraint corresponding to the type parameter) must be
 maps or slices, and clear performs the operation corresponding to the
 actual type argument (corresponding to the type of the actual type argument
 with which the type parameter was instantiated).
>>>
>>>
>>> That is, the sentence is about this situation:
>>>
>>> func Clear[T, any, S ~[]T](s S) {
>>> clear(s)
>>> }
>>> func main() {
>>> Clear(make([]int, 42))
>>> }
>>>
>>> In this case, the type of s is S, which is a type parameter. So `clear`
>>> performs the operation corresponding to the type argument - in this example
>>> []int.
>>>
>>> The sentence is a bit confusing (I've seen this question come up four
>>> times now), so it probably should be clarified a bit.
>>>
>>> On Wed, Jul 5, 2023 at 9:06 AM Tharaneedharan Vilwanathan <
>>> vdha...@gmail.com> wrote:
>>>
 Hi All,

 Go 1.21 introduces a new clear() builtin function. I see this text in
 https://tip.golang.org/ref/spec#Clear:

 clear(t) type parameter see below

 If the argument type is a type parameter
 , all
 types in its type set must be maps or slices, and clear performs the
 operation corresponding to the actual type argument.

 I am not able to make sense of it. What does this mean? Any examples on
 the usage?

 Appreciate your help.

 Thanks
 dharani

 --
 You received this message because you are subscribed to the Google
 Groups "golang-nuts" group.
 To unsubscribe from this group and stop receiving emails from it, send
 an email to golang-nuts...@googlegroups.com.
 To view this discussion on the web visit
 https://groups.google.com/d/msgid/golang-nuts/CAN-HoCn99D-m71aJr3DRzCJvk_c7h8OhG2O4wPC-1Wd2ruEYNg%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/00e424f1-1a62-4183-8974-9a585960ce7dn%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/CAEkBMfFZNkUQkJTnjwNjnPyHKd0hy%2BH%2BTg1L3wBLyG2WjUj5Tw%40mail.gmail.com.


Re: [go-nuts] Go 1.21 new builtin function clear()

2023-07-05 Thread 'Axel Wagner' via golang-nuts
Hi,

this has come up on the issue as well. Robert Griesemer provided an
explanation
:

If the argument type (the type of the argument provided to clear) is a type
> parameter (is of type parameter type), all types in its type set (in the
> type set of the constraint corresponding to the type parameter) must be
> maps or slices, and clear performs the operation corresponding to the
> actual type argument (corresponding to the type of the actual type argument
> with which the type parameter was instantiated).


That is, the sentence is about this situation:

func Clear[T, any, S ~[]T](s S) {
clear(s)
}
func main() {
Clear(make([]int, 42))
}

In this case, the type of s is S, which is a type parameter. So `clear`
performs the operation corresponding to the type argument - in this example
[]int.

The sentence is a bit confusing (I've seen this question come up four times
now), so it probably should be clarified a bit.

On Wed, Jul 5, 2023 at 9:06 AM Tharaneedharan Vilwanathan <
vdhar...@gmail.com> wrote:

> Hi All,
>
> Go 1.21 introduces a new clear() builtin function. I see this text in
> https://tip.golang.org/ref/spec#Clear:
>
> clear(t) type parameter see below
>
> If the argument type is a type parameter
> , all types
> in its type set must be maps or slices, and clear performs the operation
> corresponding to the actual type argument.
>
> I am not able to make sense of it. What does this mean? Any examples on
> the usage?
>
> Appreciate your help.
>
> Thanks
> dharani
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/CAN-HoCn99D-m71aJr3DRzCJvk_c7h8OhG2O4wPC-1Wd2ruEYNg%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/CAEkBMfFPof4VYTQWoAGN-B3FtvZJ%3D%3Dxs5s%3D-P%2BEwc%3DO%2BafFjYw%40mail.gmail.com.


Re: [go-nuts] Please consider voting to reopen Golang subreddit

2023-06-27 Thread 'Axel Wagner' via golang-nuts
On Tue, Jun 27, 2023 at 12:10 AM Eltjon Metko  wrote:

> The commercial dispute is between Reddit and API Consumers. it has nothing
> to do with mods or the users.
>

Then why are the mods and users protesting?


> No-mater how certain you may be who is in the right and who is in the
> wrong, the most certain thing here is that there is great part of the
> commuinty who are being held hostage
>

The mods of /r/golang making their decision based on a vote. This hyperbole
seems uncalled for.



> and used as tool for commercial disupute that has nothing to do with them
> or this subredit. To be clear I am not accusing the mods of Golang subredit
> for being in a powertrip (because initally it did not come from them) but
> other users who try to force their narrow worldview onto others. If this
> was an ethics issue, depnding on how clear it is there might be ground for
> protests, commercial disputes should never be ground for holding even a
> fraction of the users hostage.
> On Monday, June 26, 2023 at 10:43:36 PM UTC+2 Axel Wagner wrote:
>
>> On Mon, Jun 26, 2023 at 6:53 PM Eltjon Metko  wrote:
>>
>>> Protests like this (temporary) never make sense, they only create
>>> inconvinience for users while reddit will just have to ride it out.
>>
>>
>> Note that the common hypothesis is that there is a reason reddit is so
>> urgently pushing through the API charges, why they are urgently trying to
>> shut off the protest and why they are *particularly* urgent about shutting
>> down the protest of setting subreddits to NSFW: That they consider doing an
>> IPO in the near future. In that case, they can't really "ride it out". They
>> are likely pretty heavily interested in looking good to investors *right
>> now*.
>>
>>
>>> This is a commercial dispute nothing more and everyone that acts like a
>>> crusader in this case is simply in a power trip.
>>>
>>
>> I find this a strange stance, given that most of the people actually
>> participating in the protest are unpaid volunteers. So I don't see how that
>> can be considered a "commercial dispute", to be honest.
>>
>>
>>>
>>> On Monday, June 26, 2023 at 5:01:29 PM UTC+2 drc...@google.com wrote:
>>>
 Have you considered moving to another platform, either Lemmy or Kbin?
 (He says, not having completed his own move of the benchmarking bot to
 botsin.space).
 On Saturday, June 24, 2023 at 1:51:10 PM UTC-4 Robert Engels wrote:

> I’m fairly certain Reddit will license those tools for moderators use.
> That is not what they are trying to prevent.
>
> > On Jun 24, 2023, at 8:39 AM, Wojciech S. Czarnecki 
> wrote:
> >
> > Dnia 2023-06-23, o godz. 23:50:32
> > Amnon  napisał(a):
> >
> >> Sorry, but I have been away and missed the context.
> >
> >> What is the protest about?
> >
> > Reddit's decision to sink all good free tools that allow people
> (mods) to work several hours per day
> > keeping their communities free of propaganda and scams.
> >
> >>
> >> What has redit changed?
> >
> > APIs that were free to access by third parties will be priced as
> gold.
> >
> >> Thanks
> > yw.
> >
> > P.S.
> > It is worth mentioning that Reddit *has* a good reason to close APIs
> that are abused by A"I" businesses.
> > Just there is no will to make such changes robust, IMO, as it would
> cost. It seems to me that current Reddit's
> > brass has no faintest idea how many $millions monthly mod's work is
> worth.
> >
> > --
> > Wojciech S. Czarnecki
> > << ^oo^ >> OHIR-RIPE
> >
> > --
> > You received this message because you are subscribed 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/20230624153919.43160eba%40xmint.
>
>
 --
>>> You received this message because you are subscribed 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/b45472ed-b150-4752-bc5b-7158e152dafan%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/4f9951e1-93c5-4d3e-a56e-f1444a1896dbn%40googlegroups.com
> 

Re: [go-nuts] Please consider voting to reopen Golang subreddit

2023-06-26 Thread 'Axel Wagner' via golang-nuts
On Mon, Jun 26, 2023 at 6:53 PM Eltjon Metko  wrote:

> Protests like this (temporary) never make sense, they only create
> inconvinience for users while reddit will just have to ride it out.


Note that the common hypothesis is that there is a reason reddit is so
urgently pushing through the API charges, why they are urgently trying to
shut off the protest and why they are *particularly* urgent about shutting
down the protest of setting subreddits to NSFW: That they consider doing an
IPO in the near future. In that case, they can't really "ride it out". They
are likely pretty heavily interested in looking good to investors *right
now*.


> This is a commercial dispute nothing more and everyone that acts like a
> crusader in this case is simply in a power trip.
>

I find this a strange stance, given that most of the people actually
participating in the protest are unpaid volunteers. So I don't see how that
can be considered a "commercial dispute", to be honest.


>
> On Monday, June 26, 2023 at 5:01:29 PM UTC+2 drc...@google.com wrote:
>
>> Have you considered moving to another platform, either Lemmy or Kbin?
>> (He says, not having completed his own move of the benchmarking bot to
>> botsin.space).
>> On Saturday, June 24, 2023 at 1:51:10 PM UTC-4 Robert Engels wrote:
>>
>>> I’m fairly certain Reddit will license those tools for moderators use.
>>> That is not what they are trying to prevent.
>>>
>>> > On Jun 24, 2023, at 8:39 AM, Wojciech S. Czarnecki 
>>> wrote:
>>> >
>>> > Dnia 2023-06-23, o godz. 23:50:32
>>> > Amnon  napisał(a):
>>> >
>>> >> Sorry, but I have been away and missed the context.
>>> >
>>> >> What is the protest about?
>>> >
>>> > Reddit's decision to sink all good free tools that allow people (mods)
>>> to work several hours per day
>>> > keeping their communities free of propaganda and scams.
>>> >
>>> >>
>>> >> What has redit changed?
>>> >
>>> > APIs that were free to access by third parties will be priced as gold.
>>> >
>>> >> Thanks
>>> > yw.
>>> >
>>> > P.S.
>>> > It is worth mentioning that Reddit *has* a good reason to close APIs
>>> that are abused by A"I" businesses.
>>> > Just there is no will to make such changes robust, IMO, as it would
>>> cost. It seems to me that current Reddit's
>>> > brass has no faintest idea how many $millions monthly mod's work is
>>> worth.
>>> >
>>> > --
>>> > Wojciech S. Czarnecki
>>> > << ^oo^ >> OHIR-RIPE
>>> >
>>> > --
>>> > You received this message because you are subscribed 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/20230624153919.43160eba%40xmint.
>>>
>>>
>> --
> You received this message because you are subscribed to the Google 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/b45472ed-b150-4752-bc5b-7158e152dafan%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/CAEkBMfGN3qNUw4t3p%3DmdYWy6FyrQmqkcXOnP5pN0uG3qkEseZQ%40mail.gmail.com.


Re: [go-nuts] Please consider voting to reopen Golang subreddit

2023-06-23 Thread 'Axel Wagner' via golang-nuts
On Sat, Jun 24, 2023 at 3:03 AM cpa...@gmail.com  wrote:

> If 100 people are on a boat and 51 want to sink the boat is that fair to
> the 49 who want to live?


This is not a life-or-death situation and such comparisons are almost
universally unhelpful, as you literally do not have a choice in them.

You’re taking a resource away from others.
>
> If someone wants to protest Walmart they don’t burn it down.
>

No one is burning down anything. But, again, protest has to be
inconvenient. And contrary to the claims made by you and Jan, yes, it is
actually completely normal (and legal, in most legislatures) for a protest
to temporarily "take resources away from others". Roads get closed for
protest marches all the time.

But really, what I miss most here is an argument about the actual subject
matter. If you are frustrated about the subreddit being closed, you can
direct that frustration at the moderators or you can direct it at Reddit.
If they didn't implement their API changes, the protest would end, after
all.

You seem to be taking it as a given that the moderators are the appropriate
target of the frustration and that they should be automatically the one to
give in. When Jan asked me - an unrelated party - to refund his Reddit fee,
he could've just as well written to Reddit, telling them that he wants his
money back because their insistence on overcharging for their API causes
this protest and makes reddit less valuable to him. That would've likely
done exactly as much to get his money back. But it would actually exert
pressure on someone who has a hand in this issue - after all, threatening
Reddit's bottom line is what this protest is all about. And given that his
business relationship is with Reddit, that's the only party he actually has
any real leverage with. So I'm really confused that someone would bend over
backwards, logically speaking, to misdirect their frustration this way.

If you want to convince me, at least, that the protest is bad, you have to
convince me that the API charges Reddit is implementing are good and
justified and that the moderators are wrong to object to them. You won't
convince me with arguments about the procedure.

Or to put it another way: In your metaphor, you are assuming that the
moderators protesting are the ones who are trying to sink the boat. I'm not
convinced of that. To me, they make a pretty convincing case that it's
their actions which are trying to keep the boat afloat, by preserving
third-party tools that are essential to reddit's operation and the
voluntary labor of the moderators. And if the owner of a ship directs it to
steer into an iceberg and the crew objects, I'd expect the passengers to
back them in it, instead of complaining that they'll be late and how dare
they obstruct *my* right to have the ship go wherever I want.

Anyways… as I said, this isn't actually such a dramatic situation. It's
just a website being closed for a bit. And if the mods are open to a vote
on whether or not to participate in the protest, that seems a perfectly
serviceable process to me. People should feel free to vote on that poll
however they like. I just wanted to provide some counterweight to the
initial call to vote against the protest.


>
> On Friday, June 23, 2023 at 4:37:20 AM UTC-4 Axel Wagner wrote:
>
>> On Fri, Jun 23, 2023 at 10:29 AM Jan Mercl <0xj...@gmail.com> wrote:
>>
>>> On Fri, Jun 23, 2023 at 10:18 AM Axel Wagner
>>>  wrote:
>>>
>>> > Just for context, as not everyone seems to be aware: I was, in that
>>> sentence you quoted, referring to examples like this
>>> >
>>> https://www.reddit.com/r/ModCoord/comments/14eq8ip/the_entire_rmildlyinteresting_mod_team_has_just/
>>> > This demonstrates that even with overwhelming support from the
>>> community (and yes, in this example the modifier applies), the company
>>> overwrites those wishes to shut down protest. There are a couple of other
>>> subreddits with similar stories.
>>> >
>>> > So I was making the case to *provide* overwhelming support for the
>>> mods of /r/golang, referring to precedent of other subreddits where that is
>>> happening. Not claiming that they already have it.
>>>
>>> Thanks for the added conext.
>>>
>>> Anyone not liking Reddit is free to not visit the site. Anyone not
>>> accepting the price for the API access is free to not buy it. It's
>>> fine to vote by your visits and by your wallet. That's how the free
>>> market works and it works well unless there's some monopoly. But
>>> Reddit has no monopoly.
>>>
>>> Protesters are free to protest. That's their respected right.
>>> Protesters have no right to deny access to other users. That's my
>>> right and I expect it to be equally respected.
>>>
>>
>> /r/golang has no monopoly.
>>
>>
>>> PS: I'm paying $7/month to Reddit to have r/golang ad-free. May I ask
>>> you for a refund? Thanks for your consideration.
>>>
>>
>> You may certainly ask *the company you are paying* for a refund.
>>
>>
> --
> You received this message because you are 

Re: [go-nuts] Please consider voting to reopen Golang subreddit

2023-06-23 Thread 'Axel Wagner' via golang-nuts
On Fri, Jun 23, 2023 at 10:29 AM Jan Mercl <0xj...@gmail.com> wrote:

> On Fri, Jun 23, 2023 at 10:18 AM Axel Wagner
>  wrote:
>
> > Just for context, as not everyone seems to be aware: I was, in that
> sentence you quoted, referring to examples like this
> >
> https://www.reddit.com/r/ModCoord/comments/14eq8ip/the_entire_rmildlyinteresting_mod_team_has_just/
> > This demonstrates that even with overwhelming support from the community
> (and yes, in this example the modifier applies), the company overwrites
> those wishes to shut down protest. There are a couple of other subreddits
> with similar stories.
> >
> > So I was making the case to *provide* overwhelming support for the mods
> of /r/golang, referring to precedent of other subreddits where that is
> happening. Not claiming that they already have it.
>
> Thanks for the added conext.
>
> Anyone not liking Reddit is free to not visit the site. Anyone not
> accepting the price for the API access is free to not buy it. It's
> fine to vote by your visits and by your wallet. That's how the free
> market works and it works well unless there's some monopoly. But
> Reddit has no monopoly.
>
> Protesters are free to protest. That's their respected right.
> Protesters have no right to deny access to other users. That's my
> right and I expect it to be equally respected.
>

/r/golang has no monopoly.


> PS: I'm paying $7/month to Reddit to have r/golang ad-free. May I ask
> you for a refund? Thanks for your consideration.
>

You may certainly ask *the company you are paying* for a refund.

-- 
You received this message because you are subscribed to the Google 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/CAEkBMfHrYa4aaKZZ7Zuue188V0Z-%2BOuNd5VU8rOsLsjcRHeDfg%40mail.gmail.com.


Re: [go-nuts] Please consider voting to reopen Golang subreddit

2023-06-23 Thread 'Axel Wagner' via golang-nuts
Just for context, as not everyone seems to be aware: I was, in that
sentence you quoted, referring to examples like this
https://www.reddit.com/r/ModCoord/comments/14eq8ip/the_entire_rmildlyinteresting_mod_team_has_just/
This demonstrates that even with overwhelming support from the community
(and yes, in this example the modifier applies), the company overwrites
those wishes to shut down protest. There are a couple of other subreddits
with similar stories.

So I was making the case to *provide* overwhelming support for the mods of
/r/golang, referring to precedent of other subreddits where that is
happening. Not claiming that they already have it.

On Fri, Jun 23, 2023 at 10:08 AM Axel Wagner 
wrote:

> There exists more than one subreddit.
>
> On Fri, Jun 23, 2023 at 9:38 AM Jan Mercl <0xj...@gmail.com> wrote:
>
>> On Fri, Jun 23, 2023 at 7:01 AM 'Axel Wagner' via golang-nuts <
>> golang-nuts@googlegroups.com> wrote:
>>
>> > And even *when* they ask and get overwhelming backing from their
>> communities, ...
>>
>> Latest poll results on r/golang as of now:
>>
>> [image: image.png]
>>
>> https://www.google.com/search?q=define+overwhelming
>>
>>

-- 
You received this message because you are subscribed to the Google 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/CAEkBMfG0FWG_Afarm8-G06Bev8KgrHCCjFQj%3DxzY3ujah5CB2Q%40mail.gmail.com.


Re: [go-nuts] Please consider voting to reopen Golang subreddit

2023-06-23 Thread 'Axel Wagner' via golang-nuts
There exists more than one subreddit.

On Fri, Jun 23, 2023 at 9:38 AM Jan Mercl <0xj...@gmail.com> wrote:

> On Fri, Jun 23, 2023 at 7:01 AM 'Axel Wagner' via golang-nuts <
> golang-nuts@googlegroups.com> wrote:
>
> > And even *when* they ask and get overwhelming backing from their
> communities, ...
>
> Latest poll results on r/golang as of now:
>
> [image: image.png]
>
> https://www.google.com/search?q=define+overwhelming
>
>

-- 
You received this message because you are subscribed to the Google 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/CAEkBMfFnYRmqzp6t3tmnOOfRK6m%3DvqEiaOHxL__LHHKKHwOQUQ%40mail.gmail.com.


Re: [go-nuts] Please consider voting to reopen Golang subreddit

2023-06-22 Thread 'Axel Wagner' via golang-nuts
On Thu, Jun 22, 2023 at 11:04 PM cpa...@gmail.com  wrote:

> Anyone can choose to stop reading it or posting to it. Opening it will not
> stop individuals from protesting.
>

I'm going to state the obvious: Given that closing it was an act of
protest, opening it will certainly stop *some* individuals from protesting.
And it so happens they are the ones most affected by the changes.

Personally, I find it kind of ludicrous, that mods even have to ask their
communities for permission to protest - after all, protest *has* to be
inconvenient to be effective. But it seems that if they don't, their
protest will be silenced by the company. And even *when* they ask and get
overwhelming backing from their communities, the company seems to end up
doing that.

So, under those circumstances, I find it far more important to give mods
the ammunition they need in their protest. Personally.
But, it's a poll. People can vote however they like, obviously. Just
thought the counter-position also deserves some space in this thread.

-- 
You received this message because you are subscribed to the Google 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_nL-BVi54Txvf0fM1H8PNyGkJv1jyqjF7kVqdC2j1Qw%40mail.gmail.com.


Re: [go-nuts] Unexpected circular type definition limitation

2023-06-15 Thread 'Axel Wagner' via golang-nuts
Type declarations in functions are only scoped from the point of their
declaration until the end of the function.
So the reason you can not do the recursive type definition in a function is
that at the point of the first declaration, the second is not yet in scope.
Package scoped declarations are different from function scoped definitions,
because in a function, you have a notion of "progress" - one statement
comes after the next. At the package scope, that isn't he case. All package
scoped declarations are "simultaneous", in a sense. That was intentional,
to avoid an issue C has, where you have to sometimes declare a function
before separately, to get mutual recursion.

I think it would have been possible to make type declarations apply to the
entire function scope. But that wouldn't even solve the entire issue - for
example, you run into a similar problem when defining recursive functions
locally. Python does actually solve this by making every declaration apply
to the entire function scope - but that has its own surprises. Either way,
it's a decision that was made and we can't really reverse it now, as it
would break existing code. For example, you can do this today:

func F(x int) {
x = 42
type x string
var y x
}

which would presumably break.

Ultimately, you just have to bite the bullet here and define your types at
package scope. You can always solve name spacing issues by splitting it up
into separate packages.

On Thu, Jun 15, 2023 at 10:32 AM Christophe Meessen <
christophe.mees...@gmail.com> wrote:

> The following playground example shows the problem:
>
> https://go.dev/play/p/1kC2j57M_fW
>
>
> Le 15/06/2023 à 10:28, Jan Mercl a écrit :
> > On Thu, Jun 15, 2023 at 10:16 AM christoph...@gmail.com
> >  wrote:
> >
> >> It is possible to define two structures globally with mutual type
> dependency as this:
> >>
> >> type A struct {
> >>  B []B
> >> }
> >>
> >> type B struct {
> >>  A A[]
> >> }
> >>
> >> but I just noticed that we can't do that inside a function:
> >>
> >> func Foo() {
> >>  type A struct {
> >>  B []B
> >>  }
> >>
> >>  type B struct {
> >> A A[]
> >>  }
> >> }
> >>
> >> Is there a reason for this limitation ?
> > Syntax error: https://go.dev/play/p/ZOGyZyQDW0I
>
> --
> Bien cordialement,
> Ch.Meessen
>
> --
> You received this message because you are subscribed to the Google 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/801e7e6b-d3f8-c1df-8eae-46aa619d49a5%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/CAEkBMfEOKGgnf4PucKudOdK6WyDX9g1stey04U7SAOoXnLyvZg%40mail.gmail.com.


Re: [go-nuts] Re: Amateur's questions about "Go lang spec"

2023-06-11 Thread 'Axel Wagner' via golang-nuts
Ah, the spec does actually say:
>
> Converting a signed or unsigned integer value to a string type yields a
> string containing the UTF-8 representation of the integer. Values outside
> the range of valid Unicode code points are converted to "\uFFFD".


Personally, I think this is fine as is. I think people understand what
happens from these two sentences.

On Sun, Jun 11, 2023 at 7:02 PM Axel Wagner 
wrote:

> I'm not entirely sure. I don't think your phrasing is correct, as it
> doesn't represent what happens if the integer value exceeds the range of
> valid codepoints (i.e. if it needs more than 32 bits to represent). That
> being said, the sentence as is also isn't really precise about it. From
> what I can tell, the result is not valid UTF-8 in any case.
>
> I think it might make sense to file an issue about this, though in general
> that conversion is deprecated anyway and gets flagged by `go vet` (and `go
> test`) because it is not what's usually expected. So I'm not sure how
> important it is to get this exactly right and understandable.
>
>
> On Sun, Jun 11, 2023 at 5:17 PM Kamil Ziemian 
> wrote:
>
>> I have some hair splitting question. In the "Conversions to and from a
>> string type" we read:
>> "Converting a signed or unsigned integer value to a string type yields a
>> string containing the UTF-8 representation of the integer."
>>
>> Would it be more corrected to say, that conversion from integer to string
>> gives you UTF-8 representation of code point described by value of the
>> integer? Or maybe it is indeed representation of integer described by UTF-8
>> specification?
>>
>> Best regards,
>> Kamil
>> czwartek, 28 października 2021 o 19:33:27 UTC+2 Kamil Ziemian napisał(a):
>>
>>> Hello,
>>>
>>> From what I understand proper Gopher read at least one time "The Go
>>> Programming Language Specification" (https://golang.org/ref/spec) and
>>> now I need to read it too.
>>>
>>> I learn something of Extended Backus-Naur Form to understand it, so if I
>>> say something stupid beyond belief, I hope you will forgive me. In the
>>> first part "Notation" (https://golang.org/ref/spec#Notation) I believe
>>> that I understand meaning of all concepts except of "production_name". On
>>> one hand "production_name" means that it is name of the production, not
>>> rocket science here. On the other, after reading about EBNF I feel that I
>>> should have more information about it. Can you explain it to me?
>>>
>>> Again I'm new to EBNF, so maybe this is stupid question.
>>>
>>> Best
>>> 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+unsubscr...@googlegroups.com.
>> To view this discussion on the web visit
>> https://groups.google.com/d/msgid/golang-nuts/06347585-fd2c-4bfa-9527-3439389c6414n%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/CAEkBMfHaG8bYNLvLERu0-ad57wpoWsiB%2BFC5asyKA7FH6%2BvgZw%40mail.gmail.com.


Re: [go-nuts] Re: Amateur's questions about "Go lang spec"

2023-06-11 Thread 'Axel Wagner' via golang-nuts
I'm not entirely sure. I don't think your phrasing is correct, as it
doesn't represent what happens if the integer value exceeds the range of
valid codepoints (i.e. if it needs more than 32 bits to represent). That
being said, the sentence as is also isn't really precise about it. From
what I can tell, the result is not valid UTF-8 in any case.

I think it might make sense to file an issue about this, though in general
that conversion is deprecated anyway and gets flagged by `go vet` (and `go
test`) because it is not what's usually expected. So I'm not sure how
important it is to get this exactly right and understandable.


On Sun, Jun 11, 2023 at 5:17 PM Kamil Ziemian  wrote:

> I have some hair splitting question. In the "Conversions to and from a
> string type" we read:
> "Converting a signed or unsigned integer value to a string type yields a
> string containing the UTF-8 representation of the integer."
>
> Would it be more corrected to say, that conversion from integer to string
> gives you UTF-8 representation of code point described by value of the
> integer? Or maybe it is indeed representation of integer described by UTF-8
> specification?
>
> Best regards,
> Kamil
> czwartek, 28 października 2021 o 19:33:27 UTC+2 Kamil Ziemian napisał(a):
>
>> Hello,
>>
>> From what I understand proper Gopher read at least one time "The Go
>> Programming Language Specification" (https://golang.org/ref/spec) and
>> now I need to read it too.
>>
>> I learn something of Extended Backus-Naur Form to understand it, so if I
>> say something stupid beyond belief, I hope you will forgive me. In the
>> first part "Notation" (https://golang.org/ref/spec#Notation) I believe
>> that I understand meaning of all concepts except of "production_name". On
>> one hand "production_name" means that it is name of the production, not
>> rocket science here. On the other, after reading about EBNF I feel that I
>> should have more information about it. Can you explain it to me?
>>
>> Again I'm new to EBNF, so maybe this is stupid question.
>>
>> Best
>> 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+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/06347585-fd2c-4bfa-9527-3439389c6414n%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/CAEkBMfGE9rLy_DTSwq1rwFzUUSWHXeKa9qLvCeUzP72ihuVDzw%40mail.gmail.com.


Re: [go-nuts] Re: Amateur's questions about "Go lang spec"

2023-06-10 Thread 'Axel Wagner' via golang-nuts
If it helps, I don't think I really understand the generics parts of the
spec myself.

On Sat, Jun 10, 2023 at 7:13 PM Kamil Ziemian  wrote:

> This is not a complaint, but a reflection. I have read, as careful as I
> can, the half of the Go Spec and if I didn't learn how parametric
> polymorphism (generics; did I spell it right) should work from proposals
> and talks on YouTube, I would probably understand 30% less from it. I know
> that how parametric polymorphis works in Go and how is described in Spec is
> not in 100% identical with proposals, but it is good enough. Due to them I
> have overall picture of what type parameters and related concepts are, so I
> can guess what is the intention behind part of the Spec that mention type
> them.
>
> I think I just wouldn't be able learn parametric polymorphism from reading
> Spec. Things related to it are scattered across the text (this is not a
> complaint, I just notice a fact) and gathering them together is not a easy
> task.
>
> I should note, that I want to use parametric polymorphism as really as
> possible. For me this is a feature of the last resort, but one that you
> should know that exists.
>
> Needless to say, I will need to read Spec one more time in the future, at
> least.
>
> Best regards,
> Kamil
>
> sobota, 3 czerwca 2023 o 23:48:52 UTC+2 Sean Liao napisał(a):
>
>> It is not a typo
>>
>> https://go.dev/issue/24451
>>
>> - sean
>>
>>
>> On Sat, Jun 3, 2023 at 10:05 PM peterGo  wrote:
>>
>>> It's a simple typo. Send in a fix.
>>>
>>> peter
>>>
>>> On Saturday, June 3, 2023 at 4:07:15 PM UTC-4 Kamil Ziemian wrote:
>>>
 As burak serdar said, 9 = 3 * 3 is not a prime number, all other
 elements in the slice are prime numbers. It looks like authors of Go Spec
 want to make a joke or check how well people read examples in it.

 Best regards,
 Kamil
 sobota, 3 czerwca 2023 o 21:52:37 UTC+2 burak serdar napisał(a):

> On Sat, Jun 3, 2023 at 1:40 PM peterGo  wrote:
>
>>
>> Kamil Ziemian,
>>
>> // list of prime numbers
>> primes := []int{2, 3, 5, 7, 9, 2147483647 <(214)%20748-3647>}
>>
>> The variable prime is a list of some prime numbers starting with the
>> lowest and ending with the highest prime numbers that can safely be
>> represented an int. An int may either 32 or 64 bits.
>>
>> Please explain the joke.
>>
>
> Could it be that 9 is not prime?
>
>
>>
>>
>> Note: “Explaining a joke is like dissecting a frog. You understand it
>> better but the frog dies in the process.”
>> ― E.B. White
>>
>> peter
>> On Saturday, June 3, 2023 at 3:13:28 PM UTC-4 Kamil Ziemian wrote:
>>
>>> Is this example found in the "Composite literals" section of Go
>>> Spec a joke?
>>> // list of prime numbers
>>> primes := []int{2, 3, 5, 7, 9, 2147483647 <(214)%20748-3647>}
>>>
>>> I checked on the internet and 2147483647 <(214)%20748-3647> is a
>>> prime number (https://en.wikipedia.org/wiki/2,147,483,647), so this
>>> element is fine.
>>>
>>> Best regards
>>> Kamil
>>>
>>> czwartek, 4 maja 2023 o 16:38:50 UTC+2 Kamil Ziemian napisał(a):
>>>
 You convince me to your point Axel Wagner. At the same time if we
 look at examples in Go Spec, I think their can be improved.
 "A0, A1, and []string
 A2 and struct{ a, b int }
 A3 and int A4, func(int, float64) *[]string, and A5

 B0 and C0
 D0[int, string] and E0
 []int and []int
 struct{ a, b *B5 } and struct{ a, b *B5 }
 func(x int, y float64) *[]string, func(int, float64) (result
 *[]string), and A5"
 I mean, first we need to check that A0, A1 and []string are the
 same type and after few examples like D0[int, string] is the same as 
 E0, we
 have stated []int and []int are the same type. If you convince yourself
 that A0 is the same as A1 and both are the same as []string, checking 
 that
 []int has the same type as []int is quite trivial. I would prefer that
 examples would start from basic cases like []int is []int and []A3 is 
 []int
 (if this one is true) and progress to more convoluted like D0[int, 
 string]
 is E0.

 Best regards,
 Kamil

 czwartek, 4 maja 2023 o 14:12:25 UTC+2 Axel Wagner napisał(a):

> Personally, I'd rather add more examples of "self-evidently equal
> types". In my opinion, all the type aliases in that block confuse 
> matters
> quite a bit.
>
> "[]int and []int are identical" is not actually self-evident at
> all. It is self-evident that any sensible definition of type identity
> *should* make them identical. But it's not self-evident that the given
> definition *does*. Spelling that out in the example, 

  1   2   3   4   5   6   7   8   9   10   >