Re: [go-nuts] GO111MODULE=off go get deprecated?

2024-03-11 Thread roger peppe
It's not quite what you're after, but FWIW the gohack command (
github.com/rogpeppe/gohack) knows enough to download arbitrary Go modules
including the VCS checkout. You might find it useful, I guess.

For example:

% gohack get -vcs golang.org/x/mod
creating golang.org/x/mod@v0.16.0
golang.org/x/mod => /home/rogpeppe/gohack/golang.org/x/mod
% cd /home/rogpeppe/gohack/golang.org/x/mod
% git log -1
commit 766dc5df63e3e3e5cd6b1682f522a01c99723beb (HEAD, tag: v0.16.0)
Author: Sam Thanawalla 
Date:   Fri Feb 2 20:14:19 2024 +
... etc


Now that workspaces are a thing, it might be nice for it to add it to the
current go.work
file rather than to go.mod, I guess.


On Sun, 3 Mar 2024 at 21:25, Jeffery Carr  wrote:

> Has this been deprecated or maybe it is broken in debian sid, but:
>
> bash$ GO111MODULE=off go get -v go.wit.com/apps/test
> go: modules disabled by GO111MODULE=off; see 'go help modules'
> basj$ go version
> go version go1.22.0 linux/amd64
>
> this doesn't work anymore. Also, 'go help modules' is less than helpful.
>
> Is there some other way to download the actual sourcecode into
> ~/go/src/mything/ anymore?
>
> This functionality was _PERFECT_ in my experience. I can't even imagine
> why it would be deprecated. How in the world are you all developing
> complicated software using GO without this working? Is this why everyone
> has gazillions of internal/ packages and massive git repos?
>
> Thanks in advance for any advice,
> jcarr
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/8a3d883a-039e-4a95-8fc4-ff9fc0b874c2n%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/CAJhgacj91pUm-B9Yy6W9jBUAf_X8hk5ing%2BAmTG0PayOBuh87A%40mail.gmail.com.


Re: [go-nuts] assert library with generics?

2024-02-26 Thread roger peppe
I'm biased because I had a big hand in designing the API, but I get a lot
of pleasure from using this package:

https://pkg.go.dev/github.com/go-quicktest/qt

It does a lot more than just "equals" and "not equals" but it's still
relatively small and low-dependency.
And the error messages when it fails are decent too.

  cheers,
rog.

On Thu, 22 Feb 2024 at 08:20, Harmen  wrote:

> Hi,
>
> anyone has a tip for a nice (small) "assert" test help library which uses
> generics for the "equals" and "not equals" functions?
>
> testify is the obvious library to use for tests, which works fine, but it
> would
> be nice to have something which uses generics here.
>
> 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/ZdcDz2ULDQl02Z3R%40arp.lijzij.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/CAJhgacj5vM-RUOX-g0ibNXkBuFP%3D_5fucu%3D3ofh2yoN3G6YX%2BA%40mail.gmail.com.


Re: [go-nuts] Type parameter embedded field

2024-01-09 Thread roger peppe
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/CAJhgacgnwc3sFc%2B87tueU8m5KmC3yzWBL-vFhsGcnBKbTJMYCA%40mail.gmail.com.


Re: [go-nuts] [ANN] type-safe templates

2023-09-12 Thread roger peppe
This is very cool, thanks!

On Sun, 10 Sept 2023 at 16:20, Jonathan Amsterdam 
wrote:

> The latest version of github.com/jba/templatecheck[0]
>  supports templates that
> cannot have type errors at execution time.
>
> Once you've parsed your template `t` and all associated templates, call
>
>ct, err := templatecheck.NewChecked[MyData](t)
>
> If err == nil, then ct is a CheckedTemplate[MyData]. Its Execute method
> will only accept a MyData, and execution will not fail because your
> template tried to access a field that didn't exist, or tried to range over
> something that doesn't support range, or any other problem related to types.
>
> To make this guarantee, the type checker enforces a stricter semantics
> than the usual one for templates. For example, when you create a variable
> with a value, like this:
>
> {{$v := 1}}
>
> then all assignments to that variable must use the same type. Assignments
> that are normally valid, like
>
> {{$v = ""}}
>
> will fail this stricter check.
>
> Also, since there is no way to declare the type of a template created with
> {{define "T"}}, all calls to such templates must use the same type for dot.
>
> If you can live with these restrictions, you might like using
> CheckedTemplate[T] for the extra safety it provides.
>
> I'd like feedback on how difficult the stricter semantics is to work with.
> In particular, how painful is the restriction that all calls to associated
> templates must have the same type?
>
> I'd also consider proposing this for the standard library if a lot of
> people like it.
>
> [0] https://pkg.go.dev/github.com/jba/templatecheck
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/CAEymQsSqVjw4KXVUvz2k6s9Hup4mgjUZ-DZWcn%3DH1FmbuJUXdg%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/CAJhgache2K1R5TGTS4tnvgfcCp11EydRvJaTwHsSoL3MGZ3nkA%40mail.gmail.com.


Re: [go-nuts] Would it be possible to make this work in the future?

2023-08-29 Thread roger peppe
> We would have to have careful definitions of what kinds of code are
permitted in a case with multiple types.

ISTM that we already have such a careful definition with generics: given a
case in a `switch x.(type)` statement of the form `T1, T2, ..., Tn`, where
`x` is of type `S`, we could define the allowed operations of `x` as if it
was a parameter to a a generic function with type constraint `interface {S;
T1 | T2 | ... | Tn}`.

So your specific `[]int, map[int]int` example wouldn't be allowed, but this
would:

switch x := v.(type) {
case int32, int64:
fmt.Println(x + 1)
}

Perhaps this could be considered a natural extension of the way that the
type of `x` becomes `S` inside the default branch of the type switch
statement.


On Fri, 25 Aug 2023 at 22:02, Ian Lance Taylor  wrote:

> ‪On Fri, Aug 25, 2023 at 1:55 PM ‫محمد بومنذر‬‎
>  wrote:‬
> >
> > It's actually plain text but copied right from my editor with the theme
> styles, I'll use the playground for future examples.
>
> Thanks.  Then I guess my request is to paste as plain text without styles.
>
> Ian
>
> > Thank you for clarifying. I do see how the compiled version will need to
> be repetitive, although as you mentioned this piece of code is not a common
> case.
> > في Friday, August 25, 2023 في تمام الساعة 11:43:05 PM UTC+3، كتب Ian
> Lance Taylor رسالة نصها:
> >>
> >> ‪On Fri, Aug 25, 2023 at 7:43 AM ‫محمد بومنذر‬‎
> >>  wrote:‬
> >> >
> >> > I'm writing a parser based on Go's `encoding/xml`, I tried to use the
> following pattern but it was deemed invalid:
> >> >
> >> > ```
> >> > To me, it'd make sense if it was allowed since both types are structs
> and both of them share the field `Name` with the subsequent field `Local`.
> >>
> >>
> >> Please post code as plain text or as a link to the Go playground, not
> >> as an image. Images are much harder to read, and there is no reason
> >> to use them for plain code. Thanks.
> >>
> >> We are unlikely to implement such a language feature. We would have
> >> to have careful definitions of what kinds of code are permitted in a
> >> case with multiple types. And since in general there is no reason to
> >> expect that the fields are at the same location, we would have to
> >> compile the case differently for each type anyhow. And the code might
> >> actually behave quite differently; should we permit code like
> >>
> >> switch x := v.(type) {
> >> case []int, map[int]int:
> >> return x[1]
> >> }
> >>
> >> 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/312da70b-11c3-43b1-b53e-6d1a8e622becn%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/CAOyqgcUzp9p4dhzN%3DD-p2HsSvN%3DgsmiFX65RRdXqUhj5wJ8VRQ%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/CAJhgacj9We4OZ3ikP7ENrqwLc7g2Oosae%3Dc8WQJ0ZZ3H69t%3D3g%40mail.gmail.com.


Re: [go-nuts] Interface embedding

2023-08-29 Thread roger peppe
On Tue, 29 Aug 2023 at 13:35, Remko Tronçon  wrote:

> The Google Cloud Go library contains the following code (See
> https://github.com/googleapis/google-cloud-go/blob/38a040e213cc8af5b01b3afe422481493f54382f/datastore/client.go#L36
> )
>
> // datastoreClient is a wrapper for the pb.DatastoreClient
> type datastoreClient struct {
> // Embed so we still implement the DatastoreClient interface,
> // if the interface adds more methods.
> pb.DatastoreClient
> c  pb.DatastoreClient
> }
>
> func newDatastoreClient() pb.DatastoreClient {
> return { c: pb.NewDatastoreClient() }
> }
>
> func (dc *datastoreClient) Lookup() {
> // ...
>
> What could be the reason for both an anonymous and a named structure
> implementation, without initializing the anonymous one? As I understand it,
> this means the compiler no longer complains about missing methods from the
> `pb.DatastoreClient` interface, but it would crash with a nil pointer error
> when they are called?
>
> thanks,
> Remko
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/dfe1b583-5d79-4264-9a04-751ced59b73fn%40googlegroups.com
> 
> .
>

The comment gives at least one reason, but I'm not sure I'm entirely
convinced it's worthwhile.

I guess the reasoning could go something like:
1. We want to wrap the datastore client with our own methods, providing
specific functionality.
2. We definitely don't want any of the wrapper client's methods to be
called - we'd prefer to panic in that case.
3. We want to be resilient when other methods are added to the
DatastoreClient interface so that the code will still compile when that
happens.

Points 2 would argue against just embedding the wrapped client directly:
suppose that technique was used and a new method was added - the embedding
would cause the new method to be called on the wrapped client. In this
particular scenario, one could argue that the wrapper type is unexported,
so the package has full control of which methods are called, so this is
just defensive programming.

However in fact, there appears to be no need (*) for the datastoreClient
type to implement pb.DatastoreClient at all - IMHO it would all be simpler
and more obvious if the code was just using that type directly, perhaps
defining its own interface for testing purposes.

(*) a fact which is easy to check by removing the embedded interface,
renaming a method and checking that it still compiles.

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


Re: [go-nuts] Is it possible to switch on type T in a generic function?

2022-11-08 Thread roger peppe
If you're sure that T is an int or a string, then why not constrain it as
such? https://go.dev/play/p/1kT6EacMHco

You could go further and constrain it to allow any type with ordering
defined: https://go.dev/play/p/il5koj1RPkh

If you want to allow any kind of comparable key in your set, one could
observe that essentially you're trying to solve the same problem that the
fmt package is solving when it converts maps to string. It uses the
internal fmtsort  package, which, as
luck would have it, has been factored out into an externally available
package . So
you could do this: https://go.dev/play/p/oKTGSm_o22a

To answer the specific question you asked, there is an issue that tracks
the ability to do a switch directly on a type parameter:
https://github.com/golang/go/issues/45380

But you can also work around the lack of that feature by doing something
like this: https://go.dev/play/p/3C2a61Ojbxs

Hope this helps,

  rog.


On Tue, 8 Nov 2022 at 08:53, 'Mark' via golang-nuts <
golang-nuts@googlegroups.com> wrote:

> Given a function:
>
> func F[T comparable](a T) {
> }
>
> is it possible to check T's type inside F?
>
> My use case is that I have a function with signature G[T comparable](x
> []T) and inside G I want to sort the elements in slice x where T could be
> int or string.
>
> This arises in a tiny generic set module I've created:
> https://github.com/mark-summerfield/gset
> In the String() method I want to return a string with the elements sorted
> (for human readability and for testing convenience); but at the moment I
> can only do this by converting all elements to strings and sorting them
> which isn't good for ints.
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/e746f065-24fa-474a-90ec-2d8367bf3e3bn%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/CAJhgacibPQ%3DbgK74G4YSiyHdQQrNZJpahFph3Zz2%2BhDe_2j_0g%40mail.gmail.com.


Re: [go-nuts] How is the relationship between package version and tag, and what is the formation mechanism?

2022-09-30 Thread roger peppe
Hi,
This is documented in the Go module documentation here:
https://go.dev/ref/mod#vcs-version
  cheers,
rog.


On Thu, 29 Sept 2022 at 18:29, 'Jinchang Hu' via golang-nuts <
golang-nuts@googlegroups.com> wrote:

> When we use go list -m dependencyName@Version to get the specific
> information of the version of the dependency package, does the Version and
> the tag of the dependency in github.com correspond, which tags will be
> recognized by the go language, and allow us to pass the go list command Get
> specific information.
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/b0124d51-8a6d-4ff7-9de4-632545193a17n%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/CAJhgacgArvqaupmJrzDuFibt%3D%3D3RoJPZzaNrk6xydJHckdw_xA%40mail.gmail.com.


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

2022-08-12 Thread roger peppe
See https://github.com/golang/go/issues/45380 for a proposal for a language
feature that would allow this. In the meantime, you can convert to any, and
type switch on that:

func Foo[T allowedTypes](arg T) {
switch t := any(arg).(type) {
case int64:
...


On Fri, 12 Aug 2022, 00:40 'Matt Rosencrantz' via golang-nuts, <
golang-nuts@googlegroups.com> wrote:

> I'd really love to be able to do:
>
> type allowedTypes{
>   int64|float64|string
> }
>
> func Foo[T allowedTypes](arg T) {
> switch t := arg {
>case int64:
>// something
>case string:
>   // something completely different
>}
> }
>
> As a way of having the type checker disallow other types from being passed
> so I don't have to return an error for incorrect types.  I guess this would
> be the same as asking for typesets to be allowed in normal interfaces like:
>
> func Foo(arg allowedTypes) {...}
>
> Is there another way to achieve this? Is there a reason it is not possible?
> Thanks!
> Matt
>
>
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/870bc9bd-2fcf-4598-9287-2da7adbc524an%40googlegroups.com
> 
> .
>

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


Re: [go-nuts] Preemptive interfaces in Go

2022-08-09 Thread roger peppe
One significant argument against preemptive interfaces is that you can't
add a method to an interface type without breaking compatibility.

Also, an interface is significantly less amenable to static analysis
because it's not certain where a method call is implemented.

One concern I have about the current generics implementation is that it
does not infer types for generic interfaces, which increases the likelihood
that people will return preemptive interfaces rather than force people to
mention the type parameters explicitly (see
https://github.com/golang/go/issues/41176)

On Tue, 9 Aug 2022, 16:32 burak serdar,  wrote:

>
>
> On Mon, Aug 8, 2022 at 11:27 PM Henry  wrote:
>
>> I am sure that many of us have been on that journey. After using Go for
>> some time, we discover some practices that are not necessarily in agreement
>> with the existing "adages" but effectively solve our problems.
>>
>> For me, if the data type is mutable, I prefer returning interfaces. It
>> would be something like this:
>> ```
>> type Student interface {
>>//...
>> }
>>
>> type studentImpl struct {
>>//...
>> }
>>
>> func NewStudent(id string) Student {
>>return {
>>   //...
>>}
>> }
>> ```
>> There is a bit of history why I use this approach. For a struct with a
>> mutex, I wanted to ensure that the user did not accidentally copy the
>> struct. Nowadays we have *go vet* to give us a warning, but this was
>> before *go vet* had this functionality. So, I return a pointer to the
>> struct and hide it behind an interface. That way, it hides the
>> implementation details from the user and the user can pass the object
>> around without knowing whether it has a mutex or not.
>>
>> And then I ended up with some *constructors* returning structs and some
>> returning interfaces. To ensure consistency, my colleagues and I decided to
>> return interfaces for all mutable objects. For immutable objects, we return
>> structs.
>>
>> The nice thing about this approach is that it makes the syntax a lot
>> cleaner as you have to deal with fewer pointers.
>> ```
>> //instead of this
>> func Update(student *Student) {
>>   //...
>> }
>> func UpdateMany(students []*Student){
>>   //...
>> }
>>
>> //now you have this
>> func Update(student Student) {
>>   //...
>> }
>> func UpdateMany(students []Student){
>>   //...
>> }
>> ```
>> Some members in the team came from higher level languages and they found
>> working with pointers a bit awkward, so we made some accommodation for
>> them.
>>
>
>> There are times when I need to *upgrade* some of these mutable objects,
>> and this approach has proven to be quite flexible. It also plays nicely
>> with code generators.
>>
>> Some people may disagree with this approach, but I have been using it
>> ever since: return interface for mutable objects, return structs for
>> immutable objects.
>>
>
> I am one of those who disagrees. I have not seen any benefit from having
> interfaces for data objects other than making other developers happy. In my
> opinion, this amounts to emulating another language in Go. There are cases
> where this might make sense, but as a general principle, I think it should
> be avoided. Data is data. There are no implementation details to hide.
>
>
>
>> On Tuesday, August 9, 2022 at 3:09:10 AM UTC+7 t...@timpeoples.com wrote:
>>
>>> I can't speak to the *auto-generated swagger client* case but I believe
>>> gRPC is still doing things the right way -- in that the framework defines
>>> an interface I (the framework API consumer) then implements.  IOW: I don't
>>> see that as a "java style interface" (where the interface defines the API
>>> contract).
>>>
>>> I suspect you and I are saything the same thing.
>>>
>>> t.
>>>
>>> On Monday, August 8, 2022 at 12:51:29 PM UTC-7 bse...@computer.org
>>> wrote:
>>>
 On Mon, Aug 8, 2022 at 12:51 PM Tim Peoples 
 wrote:

> I don't necessarily consider the "multiple implementations" case as
> being truly preemptive -- if there really are multiple implementations
> (e.g. the "hash" package from the standard library).
>
> I'm much more concerned about interfaces that are defined by an API
> producer -- for one and only one impl -- and then adding a bunch of extra
> (often autogenerated) code to deal with that.
>

 Like a gRPC client/server, or auto-generated swagger client/server?

 I've had many instances where such an auto-generated client had to be
 passed down components that have no knowledge of those services. Writing
 such components using interfaces declaring only parts of those service
 implementations have benefits. An example that I can think of is an
 audit-trail service that deals with recording transaction metadata, looking
 them up, etc. It makes sense to write components that use only the writer
 part of that service, instead of requiring the whole thing. It makes
 writing tests easier. It lets you decouple services better, add
 

Re: [go-nuts] zero value for generic types?

2022-04-21 Thread roger peppe
On Wed, 20 Apr 2022 at 23:29, Arthur Comte  wrote:

> Actually, even with proper error handling, I still need to return a value.
> In some functions I can just return a variable that was defined in the
> function, but that is not always available. In those cases, the only
> solution I've found is to use `*new(E)`, which seems plain terrible. Is
> there an alternative? I'm guessing something is wrong with my angle
>

FWIW I've been using `*new(E)` throughout, on the understanding that sooner
or later there will be a proposal implemented that makes that simpler, and
when that does happen, it'll be trivial to do  `gofmt -w -r '*new(x) ->
zero` (for whatever spelling of "zero" is chosen), leaving the code exactly
as you'd have wanted to have written it in the first place with no need for
manual tidy-ups. Yes, it's crude for the time being, but at least it's
unambiguous.

-- 
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/CAP1AJ8fqT0yxd2g8gctPA%2B6Ei-fKfFQCdDM4iBMtfX%2BS-r9qgg%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/CAJhgacgUqYoJ%2Bo2fxjg_%3DUOiBgi%3DuuTuRo4qJeCN4CTim_F7eA%40mail.gmail.com.


Re: [go-nuts] Any recipe to stop a goroutine of a function other than of a channel?

2022-04-16 Thread roger peppe
I'm not sure what you think such a general feature might look like.

In general, it's not a good idea to force an arbitrary thing to stop,
because that can leave resources in an undefined state, so the only
reasonable approach AFAICS is to ask the function that's running to stop.
That functionality is provided by the language with channels and by the
standard library with the context package.

On Sat, 16 Apr 2022, 15:25 Zhaoxun Yan,  wrote:

> Thanks rog!
>
>   I already dealt with it in my project since the Listen of gorilla
> websocket did as you just mentioned - close and even throw out an error.
> But I am surprised at why golang still has not provided a general feature
> on that.
>
> Zhaoxun
>
> On Sat, Apr 16, 2022 at 10:14 PM roger peppe  wrote:
>
>> Most network functions provide a way to provide a timeout or cancellation
>> explicitly. Listen is one such: see this method - if the context that it's
>> passed is cancelled, the Listen call will return.
>> https://pkg.go.dev/net#ListenConfig.Listen
>>
>> The most general way to stop waiting on timeout or cancellation in the
>> absence of explicitly provided functionality is to start the function in a
>> separate goroutine and send notification when the function completes. This
>> is non-ideal because the goroutine will remain around even when the waiter
>> has given up, but can still be a useful technique in some circumstances.
>>
>> Hope this helps,
>>   rog.
>>
>> On Sat, 16 Apr 2022, 14:30 Zhaoxun Yan,  wrote:
>>
>>> Timeout  is quite common practice in programming. For example, Listen
>>> function in internet connection with a timeout may just close the
>>> connection and Listen thread as silence persists for some period, like 60
>>> seconds.
>>>
>>> I found it very hard to implement such a general shutdown feature of a
>>> thread/goroutine on such I/O functions, here is one unsuccessful try, which
>>> I want to stop the whole in 9 seconds but it does not function as I wanted:
>>>
>>> package main
>>>
>>> import (
>>> "fmt"
>>> "time"
>>> )
>>>
>>> func wait(){
>>> time.Sleep(5 * time.Second)
>>> fmt.Println("wait 1st signal")
>>> time.Sleep(5 * time.Second)
>>> fmt.Println("wait 2nd signal")
>>> }
>>>
>>>
>>> func main() {
>>>ticker := time.NewTicker(3 * time.Second)
>>>i := 0
>>>for{
>>>select{
>>> case <- ticker.C:
>>> i++
>>> fmt.Printf("ticker rings %d\n", i)
>>> if i==3{
>>>return
>>> }
>>>   default:
>>>   wait()
>>>   }
>>>}
>>>
>>> }
>>>
>>> The result is to wait whole 30 seconds:
>>> wait 1st signal
>>> wait 2nd signal
>>> ticker rings 1
>>> wait 1st signal
>>> wait 2nd signal
>>> ticker rings 2
>>> wait 1st signal
>>> wait 2nd signal
>>> ticker rings 3
>>>
>>> An online course suggests to wrap up the wait/Listen function with a
>>> channel (which would return something instead of nothing above)
>>>
>>> go func(){
>>>   resultChan <- Listen()
>>> }()
>>>
>>> select{
>>> case a := <- resultChan:
>>>//analyze a
>>> case <-ticker.C:
>>>//might break or return
>>> }
>>>
>>> But this recipe obviously only kill the select goroutine rather than the
>>> anonymous goroutine that actually runs Listen function. My question is -
>>> how to kill the waiting or listening goroutine from outside?
>>>
>>> --
>>> You received this message because you are subscribed to the Google
>>> Groups "golang-nuts" group.
>>> To unsubscribe from this group and stop receiving emails from it, send
>>> an email to golang-nuts+unsubscr...@googlegroups.com.
>>> To view this discussion on the web visit
>>> https://groups.google.com/d/msgid/golang-nuts/e774c5a4-ed53-43da-a1fe-0d617603e223n%40googlegroups.com
>>> <https://groups.google.com/d/msgid/golang-nuts/e774c5a4-ed53-43da-a1fe-0d617603e223n%40googlegroups.com?utm_medium=email_source=footer>
>>> .
>>>
>>

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


Re: [go-nuts] Any recipe to stop a goroutine of a function other than of a channel?

2022-04-16 Thread roger peppe
Most network functions provide a way to provide a timeout or cancellation
explicitly. Listen is one such: see this method - if the context that it's
passed is cancelled, the Listen call will return.
https://pkg.go.dev/net#ListenConfig.Listen

The most general way to stop waiting on timeout or cancellation in the
absence of explicitly provided functionality is to start the function in a
separate goroutine and send notification when the function completes. This
is non-ideal because the goroutine will remain around even when the waiter
has given up, but can still be a useful technique in some circumstances.

Hope this helps,
  rog.

On Sat, 16 Apr 2022, 14:30 Zhaoxun Yan,  wrote:

> Timeout  is quite common practice in programming. For example, Listen
> function in internet connection with a timeout may just close the
> connection and Listen thread as silence persists for some period, like 60
> seconds.
>
> I found it very hard to implement such a general shutdown feature of a
> thread/goroutine on such I/O functions, here is one unsuccessful try, which
> I want to stop the whole in 9 seconds but it does not function as I wanted:
>
> package main
>
> import (
> "fmt"
> "time"
> )
>
> func wait(){
> time.Sleep(5 * time.Second)
> fmt.Println("wait 1st signal")
> time.Sleep(5 * time.Second)
> fmt.Println("wait 2nd signal")
> }
>
>
> func main() {
>ticker := time.NewTicker(3 * time.Second)
>i := 0
>for{
>select{
> case <- ticker.C:
> i++
> fmt.Printf("ticker rings %d\n", i)
> if i==3{
>return
> }
>   default:
>   wait()
>   }
>}
>
> }
>
> The result is to wait whole 30 seconds:
> wait 1st signal
> wait 2nd signal
> ticker rings 1
> wait 1st signal
> wait 2nd signal
> ticker rings 2
> wait 1st signal
> wait 2nd signal
> ticker rings 3
>
> An online course suggests to wrap up the wait/Listen function with a
> channel (which would return something instead of nothing above)
>
> go func(){
>   resultChan <- Listen()
> }()
>
> select{
> case a := <- resultChan:
>//analyze a
> case <-ticker.C:
>//might break or return
> }
>
> But this recipe obviously only kill the select goroutine rather than the
> anonymous goroutine that actually runs Listen function. My question is -
> how to kill the waiting or listening goroutine from outside?
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/e774c5a4-ed53-43da-a1fe-0d617603e223n%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/CAJhgacgttQcggixh_VrKfFVFvAAJ7_dvX5sP7zK%2Bv23ZCLgxcw%40mail.gmail.com.


Re: [go-nuts] generics: parametric types unmarshaling

2022-04-15 Thread roger peppe
On Thu, 14 Apr 2022, 09:50 'Sebastien Binet' via golang-nuts, <
golang-nuts@googlegroups.com> wrote:

> hi there,
>
> I am playing a bit with generics.
> I am trying to implement a parametrized "Read" function that unmarshals
> bytes into some type value that implements an interface:
>
> type T1 struct {
> v string
> }
>
> func (t *T1) UnmarshalBinary(p []byte) error {
> t.v = string(p)
> return nil
> }
>
> type Unmarshaler interface {
> UnmarshalBinary(p []byte) error
> }
>
> func f1[T Unmarshaler](p []byte) (T, error) {
> var t T
> err := t.UnmarshalBinary(p)
> return t, err
> }
>
> func main() {
> p := []byte("hello")
> t1, err := f1[T1](p)
> if err != nil {
> log.Panic(err)
> }
>
> log.Printf("t1: %+v", t1)
> }
>
> my naive attempt failed like so:
>
> ./prog.go:26:16: T1 does not implement Unmarshaler (UnmarshalBinary method
> has pointer receiver)
>
> it's only when I rewrite my f1 function like so that it "works":
>
> func f2[T any](p []byte) (t T, err error) {
> switch t := any().(type) {
> case Unmarshaler:
> err = t.UnmarshalBinary(p)
> default:
> panic("boo")
> }
> return t, err
> }
>
> but it doesn't take advantage of the nice type constraints Go's generics
> provide.
>
> of course, replacing:
>  t1, err := f1[T1](p)
>
> with:
>  t1, err := f1[*T1](p)
> compiles. but fails at runtime.
>
> what am I missing?
> how do I convey the constraint "unmarshaling usually imply passing a
> pointer to some value" ?
>

This is a classic use case for structural type constraints:
https://go.dev/play/p/-stEjeeqQD0

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

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


Re: [go-nuts] Re: New edition of the Go Programming Language comming soon ?

2022-03-16 Thread roger peppe
On Tue, 15 Mar 2022 at 04:58, Rob Muhlestein  wrote:

> The essential issue is that there are a number of resources for people
> "with prior programming experience" and literally none for people learning
> Go as a first language.
>

It does have significant omissions (all programs in the book can execute in
the Go Playground), but Get Programming With Go
 is definitely
oriented towards first-time programmers. I tried a newbie programmer friend
on it recently who seemed to find it very clear.

Disclaimer: I'm a co-author of the above book.

  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/CAJhgacgSENoZmwNOx4v0Cmns0kUmkOZtP0tci5y8UhgkCWn_Ug%40mail.gmail.com.


Re: [go-nuts] Improving on unit test styles

2022-02-28 Thread roger peppe
On Fri, 25 Feb 2022, 18:46 'Markus Zimmermann' via golang-nuts, <
golang-nuts@googlegroups.com> wrote:

> Hi Gophers!
>
> We were unhappy with the common unit test styles and we think we found a
> style that has clear advantages. An in-depth comparison can be found here
> https://symflower.com/en/company/blog/2022/better-table-driven-testing.
>
> We also added support for maintaining such tests in our VS Code extension
> https://marketplace.visualstudio.com/items?itemName=symflower.symflower.
> You can either use the command or the context menu item to maintain tests.
> Here is a short introduction video
> https://www.youtube.com/watch?v=mgWLY9DDyDE_channel=Symflower
>
> There are some changes necessary to have better stack traces for
> github.com/stretchr/testify because "t.Run" calls the test function from
> another location. We are in the process of upstreaming them. Until then you
> can find them in our fork at https://github.com/symflower/testify.
>
> Would appreciate your feedback on the style and extension. Would be also
> interesting to hear other approaches and conventions that could help others
> to write better tests.
>
> Cheers,
> Markus
>

One disadvantage of your approach: the table can't be reused for different
tests. Not uncommonly I've found that it's useful to be able to plug the
same table into more than one testing function - after all, the test data
is an abstract description of some property and there can be more than one
way of testing that property.

I usually do something half way between the "standard" approach and your
suggestion. I have a struct with a "testName" field ("name" is too easily
confused with input data IMHO), and I'll use T.Run to run it as a subtest.

I've found that the lack of stack trace is much less of a problem if you
use a test name that isn't mangled by the testing package - in other words:
don't use spaces! That way a simple text search in your editor will usually
take you straight to the relevant table entry.

  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/4c52a6b6-6762-442c-b9b8-82b8f50a732dn%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/CAJhgach5KZm%2Bf3t0mktKTiY2mik6MRSPb2QAfPcYOePOnOU2yg%40mail.gmail.com.


Re: [go-nuts] No time.Duration#UnmarshalText; is there a good reason?

2022-01-19 Thread roger peppe
On Wed, 19 Jan 2022 at 04:19, Ian Lance Taylor  wrote:

> On Mon, Jan 17, 2022 at 9:53 PM Corin Lawson 
> wrote:
> >
> > It seems obvious (to me) that the encoding.TextUnmarshaler interface
> could be implemented for time.Duration (it is implemented for time.Time,
> afterall).
> >
> > The fact that it is not gives me pause... is there a good reason that
> the stdlib has not done this?  What issues am I facing if I do this:
> https://go.dev/play/p/nHBfS7TJQtJ
> >
> > ```
> > // UnmarshalText implements the encoding.TextUnmarshaler interface.
> > func (d *Duration) UnmarshalText(data []byte) error {
> > val, err := time.ParseDuration(string(data))
> > *d = Duration(val)
> > return err
> > }
> > ```
>
> A time.Duration is just an integer.  The standard text marshaling and
> unmarshaling work fine.
>

They do work fine in the technical sense, but marshalling a 1s duration as
10 doesn't make for a particularly readable specification of a
duration when found in configuration (it's so easy to misread the number of
digits). I've often wrapped a time.Duration in a type that implements
marshaling and unmarshaling so it's possible to write 1s, 500ms, etc.

Unfortunately I don't believe that's possible to add retrospectively
because marshaling using Duration.String would break any existing users
that expect a number.

  cheers,
rog.


> 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/CAOyqgcUbSaTJ15zT7ksQmDMaf2oq%2B0oY5uN-kzzKHXa-6JjnJw%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/CAJhgacjJq7Xp-JzTP4PvyVKXzFkAyRYQHWnQ%2BtgGzRaqvEFWpA%40mail.gmail.com.


Re: [go-nuts] Limits of type parameter inference in function calls

2021-11-08 Thread roger peppe
See https://github.com/golang/go/issues/41176.

On Sun, 7 Nov 2021, 12:47 Florian Weimer,  wrote:

> * Axel Wagner:
>
> > One way to fix this is to change the signatures to
> >
> > func Contains[I Iterator[T], T comparable](c I, value T) bool
> > func Contains2[I Iterator[T], T comparable](value T, c I) bool
>
> I had not realized that, thanks. The opposite order is perhaps more
> useful, [T comparable, I Iterator[T]], to simplify specifying the type
> T when necessary.
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/87v91416am.fsf%40mid.deneb.enyo.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/CAJhgach1kkh93AtdfXtoAz1Lw7-fv8maK4RRjCk-JWPcnnnHpQ%40mail.gmail.com.


Re: [go-nuts] testing if strconv.Quote() would do change a string, without calling it

2021-10-14 Thread roger peppe
On Thu, 14 Oct 2021 at 04:58, 'Tim Hockin' via golang-nuts <
golang-nuts@googlegroups.com> wrote:

> Thanks for confirming.  I wrote that function and erased a good bit of the
> overhead.
>
> bytes.Buffer for the no-escapes path and strconv.Quote otherwise.
>

Could you not use strconv.AppendQuote and get the advantage without needing
the extra scan?

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


Re: [go-nuts] Will the generics support be enabled by default in Go 1.18?

2021-10-13 Thread roger peppe
On Tue, 12 Oct 2021 at 01:42, Ian Lance Taylor  wrote:

> On Mon, Oct 11, 2021 at 2:36 AM peter.m...@gmail.com
>  wrote:
> >
> > I'm curious, was any consideration given to hiding generics behind a
> flag in 1.18?  The idea being it's such a complex feature that one could
> imagine a backwards incompatible change being desirable if some weird issue
> is found.
>
> Yes, we considered that idea, and decided against it.  Since many
> people are interested in generics, the effect would be to split the Go
> ecosystem: many projects would immediately adopt generics, and many
> wouldn't.  Then as people depended on other packages, and those
> packages started using generics, people who were otherwise not using
> generics would be forced to turn them on in a haphazard process.  It
> seems better for the ecosystem to just permit generics everywhere.
>
> Ian
>

ISTM that in a sense, generics *are* behind a flag in 1.18, on a per-module
basis at any rate - if your go.mod file doesn't declare a Go version of at
least 1.18, then you can't use type parameters.



>
>
> > On Monday, October 11, 2021 at 5:26:35 PM UTC+13 Ian Lance Taylor wrote:
> >>
> >> On Sun, Oct 10, 2021 at 2:55 AM nil...@gmail.com 
> wrote:
> >> >
> >> > We are really excited about the coming generics support in Go, our
> test drive of the generics support in 1.17 is so far pretty positive and it
> would also allow us to immediately delete tens of thousands lines of code
> from our main project.
> >> >
> >> > Our understanding is that Go team's current plan is to have the
> generics support enabled by default in the 1.18 release scheduled for Feb
> 2022. The question we are facing now is how much certainty we have on that.
> I mean if generics could get delayed until 1.19, which would be 10 months
> from now, then we should probably wait rather than switching to the full
> use of generics now.
> >> >
> >> > Could someone from the Go team provide us some guidance please? Shall
> we wait until the coming code freeze or maybe beta1 to expect more
> clarification?
> >>
> >> The current expectation is that Go 1.18 will support generics. The
> >> tip Go compiler already supports generics. There are bugs, but as
> >> they are reported they are being fixed. It is reasonably likely that
> >> some generics corner cases will not compile in Go 1.18, but the
> >> expectation is that straightforward uses of generics will work as
> >> expected. It is also likely that performance in Go 1.18 will not be
> >> as good as it will be in later releases.
> >>
> >> Of course, it's impossible to guarantee this. Something completely
> >> unexpected could happen. But that is the expectation. Hope this
> >> helps.
> >>
> >> 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/a2b05910-9cdc-4fb4-94d5-61bd12812089n%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/CAOyqgcUK64FN9%3DYuo0xFTfAz%2Ban8eq9vwgX9rkcFsAdU0P%3DkfQ%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/CAJhgacjO%2BjhB0WyV1H1vJxXxymP7gkvdNoqvZuHngkEVd3DURw%40mail.gmail.com.


Re: [go-nuts] Can generics help me make my library safer?

2021-10-09 Thread roger peppe
On Fri, 8 Oct 2021 at 15:44, mi...@ubo.ro  wrote:

>  I'm using the library with a nosql. I provided the sql example b/c it's
> part of the std library.
> I like rog's solution(especially on the generic Resource type) but to
> reduce friction and make it more idiomatic I would need to be able to
> define the select arguments in the return func (after the query string is
> parsed) instead to define them manually in a struct.
>   Defining the filters/params in a struct requires extra effort and makes
> the code more verbose instead to rely on the query parser. Also a query has
> just 1-2 filters and I don't find structs with 1-2 fields(i.e like
> `ByColor` struct) very idiomatic/nice to use instead of function parameters.
>

The only way to do that kind of thing currently AFAIK is to explicitly
enumerate variants for different numbers of arguments.
You could layer on top of the existing more generic struct-based code to do
that.
For example:

type SelectFunc[Resource, Args any] func(args Args) (Resource, error)
type Select1Func[Resource, Arg0 any] func(arg0 Arg0) (Resource, error)
type Select2Func[Resource, Arg0, Arg1 any] func(arg0 Arg0, arg1 Arg1)
(Resource, error)
// etc

func Select1[Resource, Arg0 any](q string) Select1Func[Resource, Arg0] {
f := Select[Resource, struct{ A Arg0 }](q)
return func(arg0 Arg0) (Resource, error) {
return f(struct{ A Arg0 }{arg0})
}
}

func Select2[Resource, Arg0, Arg1 any](q string) Select2Func[Resource,
Arg0, Arg1] {
f := Select[Resource, struct {
A0 Arg0
A1 Arg1
}](q)
return func(a0 Arg0, a1 Arg1) (Resource, error) {
return f(struct {
A0 Arg0
A1 Arg1
}{a0, a1})
}
}


  I assume that as Ian said that kind of "variadic generic types" is not
> possible in Go/2 generics.
>
> On Wednesday, October 6, 2021 at 4:17:43 PM UTC+3 ren...@ix.netcom.com
> wrote:
>
>> I think you can only do that if you make sql parsing a first class
>> language feature - or you need to construct the query using a syntax tree
>> of clauses which is a PITA. Sometimes a hybrid approach - not a full orm -
>> but an sql helper works best so
>>
>> sql.Query(table name, field list, where clauses, order by clauses) can
>> work but for complex sql like joins it becomes unwieldy.
>>
>> After years of doing both, I’ve settled on that using DAOs creates the
>> simplest and highest performing code.
>>
>> On Oct 6, 2021, at 8:07 AM, Brian Candler  wrote:
>>
>> FWIW, I like the idea of being able to write direct SQL and still have
>> some static type checking.  ORMs are OK for simple "get" and "put", but I
>> have been bitten so many times where I *know* the exact SQL I want for a
>> particular query, but the ORM makes it so damned hard to construct it their
>> way.
>>
>>
>> On Wednesday, 6 October 2021 at 12:45:01 UTC+1 ren...@ix.netcom.com
>> wrote:
>>
>>> Personally, I think this is overkill (the entire concept not the rog
>>> solution)
>>>
>>> Even with static checking there is no way to ensure that tablex has the
>>> needed fields. Even if you could check this at compile time - it might be
>>> different at runtime.
>>>
>>> I don’t think the juice is worth the squeeze.
>>>
>>> Either use an ORM that generates the sql, or create DAOs and rely on
>>> test cases to ensure the code is correct.
>>>
>>> Far simpler and more robust in my opinion.
>>>
>>> On Oct 6, 2021, at 6:35 AM, roger peppe  wrote:
>>>
>>> 
>>>
>>> On Wed, 6 Oct 2021 at 09:21, mi...@ubo.ro  wrote:
>>>
>>>> Hi Ian ,
>>>>
>>>> I've modified the example towards a more specific use case. The main
>>>> idea in the example below  is to make code related to database
>>>> operations(i.e SELECT queries) safer and  easier to read. A  kind of
>>>> json.Unmarshal/Marshal for databases, with validation (type checking, param
>>>> numbers etc) to avoid a class of bugs/errors such invalid param
>>>> types/numbers passed, invalid queries, invalid resource type to scan into
>>>> etc.
>>>>
>>>> Currently the function returned by *Select*  throws the validation
>>>> errors at runtime (i.e. invalid param type passed etc). It would be great
>>>> to have that class of errors checked at compile type.
>>>>
>>>> The only way I could achieve that kind of  type checking was  through
>>>> code generation

Re: [go-nuts] Can generics help me make my library safer?

2021-10-06 Thread roger peppe
On Wed, 6 Oct 2021 at 12:44, Robert Engels  wrote:

> Personally, I think this is overkill (the entire concept not the rog
> solution)
>

I tend to agree, but the bait was too irresistible :)

I do think that using reflection in combination with generics the way I
showed can be really useful. This is a nice example of how the technique
can be applied, even if the problem isn't actually a good one to solve.

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


Re: [go-nuts] Can generics help me make my library safer?

2021-10-06 Thread roger peppe
On Wed, 6 Oct 2021 at 09:21, mi...@ubo.ro  wrote:

> Hi Ian ,
>
> I've modified the example towards a more specific use case. The main idea
> in the example below  is to make code related to database operations(i.e
> SELECT queries) safer and  easier to read. A  kind of
> json.Unmarshal/Marshal for databases, with validation (type checking, param
> numbers etc) to avoid a class of bugs/errors such invalid param
> types/numbers passed, invalid queries, invalid resource type to scan into
> etc.
>
> Currently the function returned by *Select*  throws the validation errors
> at runtime (i.e. invalid param type passed etc). It would be great to have
> that class of errors checked at compile type.
>
> The only way I could achieve that kind of  type checking was  through code
> generation. I already built a tool to generate functions with the proper
> param types but it seems that code generation introduces a lot of friction
> to the point that I stopped using it.
>
> My hope is that one day a Go feature (i.e. a version of Generics) could
> help the function returned by *func* *Select* be type checked at compile
> time.
>
>
If you change your API slightly to use a single selector argument of struct
type, you could do something like this:

https://go2goplay.golang.org/p/QH1VCQFxrZS

In summary:

type Flower struct {
Color  string
Size   int
Weight int
}

type ByColor struct {
Color string
}

var FlowerByColor = Select[Flower, ByColor]("* FROM tablex WHERE Color=$
LIMIT 1")

type SelectFunc[Resource, Args any] func(args Args) (Resource, error)

// Select returns a function that executes the given SQL query,
// expecting results to contain fields matching Resource and
// using fields in Args to select rows.
//
// Both Resource and Args must be struct types; All the fields
// in Args must have matching fields in Resource.
func Select[Resource, Args any](q string) SelectFunc[Resource, Args] {


That is, we can use a combination of reflection and generics. The generics
keep the code type-safe. The reflection part does the more specific type
checking once only at init time, something I like to think of as "almost
statically typed". It's a powerful pattern in my view.

  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/CAJhgacjQGQ%2BEuGVu8%2Bp5FLDFjeE_amrU9G4zGAjderEZAUTAnA%40mail.gmail.com.


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

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

A minor variant of the existing API could be:

```
func As[E error](err error, asErr *E) bool
```
which makes the API a little clearer without changing the usage. Sadly we
can't make that change without breaking compatibility.


On Sun, 19 Sep 2021, 21:15 David Finkel,  wrote:

>
>
>
> On Sun, Sep 19, 2021 at 4:02 PM David Finkel 
> wrote:
>
>> You might be interested in the original draft proposal for errors.As:
>>
>> https://go.googlesource.com/proposal/+/master/design/go2draft-error-inspection.md#the-is-and-as-functions
>>
>> In particular, it originally specified that errors.As would take a
>> type-parameter. (the version of generics that was proposed concurrently
>> with that proposal was not accepted so they had to go with the current
>> (clunkier) interface).
>>
>
> Hmm, actually, the code in that proposal for the generic version of
> errors.As works almost unchanged:
> https://go2goplay.golang.org/p/ddPDlk00Cbl (I just had to change the
> type-parameter syntax)
>
>
>> On Sun, Sep 19, 2021 at 5:33 AM Haddock  wrote:
>>
>>>
>>> I like the way error handling is done in the xerror package. Things
>>> become more concise, but remain very easy to read and understand as in
>>> plain Go errorhandling.
>>>
>>> Here is the example of how to use xerror.As:
>>>
>>> _, err := os.Open("non-existing")
>>> if err != nil {
>>> var pathError *os.PathError
>>> if xerrors.As(err, ) {
>>> fmt.Println("Failed at path:", pathError.Path)
>>> }
>>> }
>>>
>>> My idea is to make this even shorter like this:
>>>
>>> _, err := os.Open("non-existing")
>>> myerrors.As(err, os.PathError) {
>>>  pathError -> fmt.Println("Failed at path:", pathError.Path)
>>> }
>>>
>>> Think something like that has so far not been suggested. That's why I
>>> thought it is justified to drop comment.
>>>
>>> myerrors.As would also do the check if err is nil. The code in my sample
>>> is not valid Go code, I know. It is only pseudo code to show the idea.
>>>
>>> --
>>> You received this message because you are subscribed to the Google
>>> Groups "golang-nuts" group.
>>> To unsubscribe from this group and stop receiving emails from it, send
>>> an email to golang-nuts+unsubscr...@googlegroups.com.
>>> To view this discussion on the web visit
>>> https://groups.google.com/d/msgid/golang-nuts/629e6763-36a9-4d7d-991c-fd71dd384d0en%40googlegroups.com
>>> 
>>> .
>>>
>> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/CANrC0BgsVSo0hv5UtTi%3DVXZYZODys1H-kvB63o2B3UThBMnfxQ%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/CAJhgaci_b%3DX0wn1R4gmT3Dgv3Ztbf4zb_S5X-tpMbezWgHU35A%40mail.gmail.com.


Re: [go-nuts] Still "missing" priority or ordered select in go?

2021-05-06 Thread roger peppe
On Thu, 6 May 2021 at 14:41, 'Axel Wagner' via golang-nuts <
golang-nuts@googlegroups.com> wrote:

> PS: And I'm not saying there is no argument. Maybe "select is not atomic"
> is such an argument. But if there is an argument and/or if this is that
> argument, I don't fully understand it myself.
>

One reason is that the semantics can conflict. Consider this code, for
example (assuming a hypothetical "pri select" statement that chooses the
first ready arm of the select) - the priorities conflict. I suspect Occam
doesn't encounter that issue because it only allows (or at least, it did
back when I used Occam) select on input, not output. I believe that
restriction was due to the difficulty of implementing bidirectional select
between actual distributed hardware processors, but I'm sure Øyvind knows
better.

func main() {
c1, c2, c3 := make(chan int), make(chan int), make(chan int)

go func() {
pri select {
case c1 <- 1:
case v := <-c2:
c3 <- v
}
}()
go func() {
pri select {
case c2 <- 2:
case v := <-c1:
c3 <- v
}
}()
fmt.Println(<-c3)
}

That said, I suspect that the semantics could be ironed out, and the real
reason for Go's lack is that it's not actually that useful; that it would
be one more feature; and that in practice a random choice makes sense
almost all the time.


On Thu, May 6, 2021 at 3:40 PM Axel Wagner 
> wrote:
>
>> FWIW after all this discussion I *am* curious about a more detailed
>> argument for why we can't have a priority select that guarantees that
>> *if* the high-priority case becomes ready before the low-priority one
>> (in the sense of "there exists a happens-before edge according to the
>> memory model"), the high-priority will always be chosen.
>>
>> That is, in the example I posted above
>> , we *do* know that `hi` becoming
>> readable happens-before `lo` becoming readable, so a true prioritized
>> select would always choose `hi` and never return. The construct we
>> presented *does* return.
>>
>> Now, I do 100% agree that it's not possible to have a select that
>> guarantees that `hi` will be read if both *become readable concurrently*.
>> But I don't see a *fundamental* issue with having a select that always
>> chooses `hi` if `*hi` becoming readable happens-before `lo` becoming
>> readable*.
>>
>> And to be clear, I also kinda like that we don't have that - I think the
>> value provided by the pseudo-random choice in preventing starvation is
>> worth not having an "ideal" priority select construct in the language. But
>> I couldn't really make a good case why we *can't* have it.
>>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/CAEkBMfEJNtu1i1RyZxW5FNYkD0TB73nq0WyVCCW_E9_JOAVJmw%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/CAJhgacjhgpRKqtQoyaEaFO45ZV94%2B5eAgRgoaWtyLSBVS-hAFw%40mail.gmail.com.


Re: [go-nuts] Still "missing" priority or ordered select in go?

2021-05-04 Thread roger peppe
On Mon, 3 May 2021 at 20:24, Øyvind Teig  wrote:

> I see that, which is great. But I still don't understand why
> https://go2goplay.golang.org/p/S_5WFkpqMP_H (By *rog*, 29Apr2021
> 23:52:05) seems not to print "Client 2".
>

That's because to try to emphasise the arbitrariness of the producers (and
to check that the consuming code was working as intended), the producing
code deliberately doesn't produce any values on channel 2. Instead, it
sleeps for a second and produces a "late arrival" message.

It's trivial to take out the if statement and show that it works as you'd
expect: https://go2goplay.golang.org/p/TjgiOmZtQhR

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


Re: [go-nuts] Still "missing" priority or ordered select in go?

2021-04-29 Thread roger peppe
On Thu, 29 Apr 2021, 20:05 Øyvind Teig,  wrote:

> torsdag 29. april 2021 kl. 20:22:32 UTC+2 skrev rog:
>
>> I agree with Axel's take here. It seems, Øyvind, that you are concerned
>> more with principle than practice here. Can you give an example of a real
>> world case where you think that this might actually matter?
>>
>
> Thanks, yes. I have written some about that in the *Nondeterminsim* blog
> note, referred to at the top. I admit I indicated that seeing some code
> might be interesting, but it was the principle I was after. In the end a
> "yes" or "no".
>
> Some from the chapter "*-Nondeterministic selective choice in
> implementations is not good*": (Preceeding the quote I have been telling
> about CSP's *external* nondeterministic choice in the *specfications*
> ("implement this any way you want") but in the *implementation* part we
> have to take decisions (deterministic, inner choice: "we do it *this*
> way"). I was thinking this is relevant because Why build concurrency on
> the ideas of CSP?  Here's the quote:
>
> *"The statement was that with the non-deterministic guarded choice in Go,
> what happens is up to the run-time, which is “not good”. This
> is implementation, not specification. With occam there is ALT or PRI ALT,
> always coded as PRI ALT. For a server to be “fair” I have to code it
> myself, it’s up to me, at the application level to find the best algorithm.
> Which, during my years as occam programmer was “new starting channel index
> in the ALT-set is the channel index of the served channel + 1
> modulo-divided by number of channels”. Channels are clients[0..4]
> (five) ALT‘ed in set [4,0,1,2,3] served index 4, then 4+1 rem 5 == 0 yields
> next ALT set [0,1,2,3,4]. Just served 4 and you’re at the back of the set."*
>
> The example here is a server with N clients where it is essential that
> none of clients will starve and none jam the server.
>
I have needed to do this coding several times. Go has random select which
> in theory may mean starving and jamming. I worked with safety critical fire
> detection, and it was necessary to ensure this. Or at least we didn't dare
> to take the chance. We could not just add another machine.
>
> To use select when that's fair enough (pun 1) - "fair enough" (pun 2). But
> If I want to be certain of no starving or jamming I need to code the
> fairness algorithm. I can then promise a client that may have been ready
> but wasn't served to come in before I take the previous clients that were
> allowed. This is at best very difficult if all we have is select. Having
> pri select as the starting point is, in this case, easier.
>

To start with, if you've got N clients where N isn't known in advance, it's
not possible to use Go's select statement directly because it doesn't
provide support for reading from a slice.
You can do it with reflection though. It's not too hard to code something
quite similar to your algorithm above.
For example: https://go2goplay.golang.org/p/S_5WFkpqMP_H

I think the above code should fit your definition of fairness, and it seems
to me that it's a reasonably general approach.

  cheers,
rog.

Øyvind
>
>
>>
>> On Thu, 29 Apr 2021, 15:44 'Axel Wagner' via golang-nuts, <
>> golan...@googlegroups.com> wrote:
>>
>>> FWIW, maybe this helps:
>>>
>>> Assume a read happened from lowPriority, even though highPriority was
>>> ready to read as well. That's, AIUI, the outcome you are concerned about.
>>>
>>> In that situation, how would you know that highPriority was ready to
>>> read as well?
>>>
>>> On Thu, Apr 29, 2021 at 4:39 PM Axel Wagner 
>>> wrote:
>>>
 On Thu, Apr 29, 2021 at 3:54 PM Øyvind Teig 
 wrote:

> They could still both have become ready (not in the same "cycle")
> between the two selects. Even if that probability is low, it would need
> knowledge like yours to show that this may in fact be zero. There could be
> a descheduling in between, one of those in my opinion, not relevant
> arguments.


 FTR, again: Yes, it's definitely possible, but it's irrelevant. It
 makes no observable difference. Even if we had a prioritized select, it
 would still be *de facto* implemented as a multi-step process and even
 then, you might run into exactly the same situation - you could have both
 channels becoming ready while the runtime does setup, or you could have a
 random scheduling event delaying one of the goroutines infinitesimally, or
 you could have…

 This is why we *don't* talk about the behavior of concurrent programs
 in terms of cycles and time, but instead based on causal order. We don't
 know how long it takes to park or unpark a goroutine, so all we can say is
 that a read from a channel happens after the corresponding write. In terms
 of time, between entering the `select` statement and between parking the
 goroutine might lie a nanosecond, or a million years - we don't know, so we
 

Re: [go-nuts] Still "missing" priority or ordered select in go?

2021-04-29 Thread roger peppe
I agree with Axel's take here. It seems, Øyvind, that you are concerned
more with principle than practice here. Can you give an example of a real
world case where you think that this might actually matter?

On Thu, 29 Apr 2021, 15:44 'Axel Wagner' via golang-nuts, <
golang-nuts@googlegroups.com> wrote:

> FWIW, maybe this helps:
>
> Assume a read happened from lowPriority, even though highPriority was
> ready to read as well. That's, AIUI, the outcome you are concerned about.
>
> In that situation, how would you know that highPriority was ready to read
> as well?
>
> On Thu, Apr 29, 2021 at 4:39 PM Axel Wagner 
> wrote:
>
>> On Thu, Apr 29, 2021 at 3:54 PM Øyvind Teig 
>> wrote:
>>
>>> They could still both have become ready (not in the same "cycle")
>>> between the two selects. Even if that probability is low, it would need
>>> knowledge like yours to show that this may in fact be zero. There could be
>>> a descheduling in between, one of those in my opinion, not relevant
>>> arguments.
>>
>>
>> FTR, again: Yes, it's definitely possible, but it's irrelevant. It makes
>> no observable difference. Even if we had a prioritized select, it would
>> still be *de facto* implemented as a multi-step process and even then, you
>> might run into exactly the same situation - you could have both channels
>> becoming ready while the runtime does setup, or you could have a random
>> scheduling event delaying one of the goroutines infinitesimally, or you
>> could have…
>>
>> This is why we *don't* talk about the behavior of concurrent programs in
>> terms of cycles and time, but instead based on causal order. We don't know
>> how long it takes to park or unpark a goroutine, so all we can say is that
>> a read from a channel happens after the corresponding write. In terms of
>> time, between entering the `select` statement and between parking the
>> goroutine might lie a nanosecond, or a million years - we don't know, so we
>> don't talk about it.
>>
>> The memory model is exactly there to abstract away these differences and
>> to not get caught up in scheduling and cycle discussions - so, FWIW, if
>> these arguments are not relevant, you shouldn't bring them up. Logically,
>> between the first `select` statement and the second `select` statement,
>> there is zero time happening. Arguing that there is, is using exactly those
>> irrelevant arguments about schedulers and processing time.
>>
>>
>>> torsdag 29. april 2021 kl. 15:47:42 UTC+2 skrev Jan Mercl:
>>>
 On Thu, Apr 29, 2021 at 3:23 PM Øyvind Teig 
 wrote:

 > 4c is not "correct" as I want it. In the pri select case, if more
 than one is ready, then they shall not be randomly chosen. Never. They
 should be selected according to priority.

 That's not what 4c says. Instead of "more than one ready" it says
 "both high and low _get ready at the same time_".

 Note that in the first approximation the probability of 4c happening
 is approaching zero. If we consider time "ticks" in discrete quanta,
 the probability is proportional to the size of the quantum. And
 depending on a particular implementation of the scheduler the
 probability of 4c can still be exactly zero. For example, the OS
 kernel may deliver only one signal at a time to the process etc.

 So the "Never" case may quite well never happen at all.

>>> --
>>> You received this message because you are subscribed to the Google
>>> Groups "golang-nuts" group.
>>> To unsubscribe from this group and stop receiving emails from it, send
>>> an email to golang-nuts+unsubscr...@googlegroups.com.
>>> To view this discussion on the web visit
>>> https://groups.google.com/d/msgid/golang-nuts/2460a16f-af1b-4613-ba4a-72b13e816a2bn%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/CAEkBMfFC1gtxbWZsy88gM4ymPncCjs6Q3YJpTcXym8bT1Ev6Kw%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/CAJhgachVuBduF_ucmywVKfDM4On05ekNEgxGPmHgWm0V6xFDxw%40mail.gmail.com.


Re: [go-nuts] Re: Modules... why it has to be so painfull?

2021-04-09 Thread roger peppe
On Fri, 9 Apr 2021, 16:37 'gonutz' via golang-nuts, <
golang-nuts@googlegroups.com> wrote:

> Justin Isreael said
>
> "Changes to ProjectB should be immediately available when compiling
> ProjectA."
>
> which is not true when you simply insert a replace in your go.mod file.
>
> My current problem is that I have a main module that uses a library
> module. I want to debug an issue so I insert a print statement in my main
> module. That works. But now I want to insert a print statement in the
> library. How do I do that?
>
> A replace in the go.mod file is of no help here because I still have to
> specify a require with a concrete version or commit hash for the library.
> This means I cannot just change the code in the library module, I also have
> to create a commit and check it in, then go back to my main module and
> udpate not only the replace but also the require in go.mod, every time I
> want to simply place a simple, temporary print statement for debugging
> purposes into the library.
>
> Does anybody have an easy workflow for the common use case?
>

You might find that https://github.com/rogpeppe/gohack helps you here -
it's designed for this use case.

> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/421ae2eb-fd97-46b4-ab83-979c5e63cf88n%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/CAJhgacgeBZALkxfJseC76wFwqYh1iKBBmgodQBPtx7-U0J0hwA%40mail.gmail.com.


Re: [go-nuts] Re: Update to generics proposal

2021-04-05 Thread roger peppe
On Mon, 5 Apr 2021, 21:58 yiyus,  wrote:

>  A type and its underlying type support exactly the same operations
>

FWIW I don't believe that's the case. A type may have methods (each with at
least one corresponding operation) that its underlying type does not.

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


Re: [go-nuts] Re: Update to generics proposal

2021-04-04 Thread roger peppe
On Sun, 4 Apr 2021 at 00:48, Eltjon Metko  wrote:

> I was fully expecting for floodgates of comments to open again but it
> seems we have reached a point of maturity in the generics proposal.
> The new proposal really makes the intent much clearer both on the exact vs
> underlying type match front  and the syntax gives us a more familiar union
> intent.
> So in that light this proposal is a welcome change by itself.
>
> If this would allow us then later to switch on the matched type
> (preferably without type assertion, along the lines of the comment in
> https://github.com/golang/go/issues/45346#issuecomment-812557199 )
> than it would make this implementation of  generics much more useful.
>

FYI because discussion on that was starting to disrupt the original
proposal, I created
a specific issue for the type switch construct suggested in that comment:

https://golang.org/issue/45380

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


Re: [go-nuts] Finding error type for `errors.As` and `errors.Is`

2021-03-31 Thread roger peppe
On Wed, 31 Mar 2021 at 18:05, 'Michael Schaller' via golang-nuts <
golang-nuts@googlegroups.com> wrote:

> Hi everyone,
>
> I often encounter deep error chains where errors are wrapped across
> several Go packages and that makes it often hard to find a usable error
> type to use with `errors.As` or `errors.Is`.
>
> Could it make sense to add an `errors.Chain` function to Go that returns a
> slice with tuples of error type (reflect.Type) and the respective error?
>

Unfortunately that's not possible in general because errors in the change
can implement their own `As` and `Is` methods, so an error can appear
to have some type T in the chain (i.e. errors.As(new(T)) returns true)
without *actually *having that type in the chain.

For example: https://play.golang.org/p/-IAKMrD8FlG

It's a shame in my view, but that's what we've got.

  cheers,
rog.


> Quick example:
> https://play.golang.org/p/hDW0_6P7O2Y
>
> Best,
>
> Michael
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/acab291d-21bc-4c84-a19a-7f9901cc8035n%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/CAJhgach3A0WbsbJ57CAnsGusV4OnwmLE1xWh1mJySDvzp%3DfpTA%40mail.gmail.com.


Re: [go-nuts] How to wait for HTTP server to start?

2021-03-29 Thread roger peppe
I often call net.Listen directly before calling Serve in a goroutine. That
way you can connect to the server's socket immediately even though the
server might take a while to get around to serving the request.

Look at how net/http/httptest does it.

On Sat, 27 Mar 2021, 14:13 cpu...@gmail.com,  wrote:

> The typical Go tutorials pattern for starting a server is something like
>
> log.Fatal(http.ListenAndServe(":8080"))
>
> But what if the application needs to do other things after the server is
> started? It seems there is virtually no method to wait for the server
> actually start listening to requests?
>
> I'm probably missing something and would appreciate a hint.
>
> Thanks,
> Andi
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/a40222e3-e4b3-4996-8232-045fcff43b77n%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/CAJhgaciragnS9HXQ%3Dy4MbKGDQD2k2S9ADwQt7eh9y%3DBgLJ1Ccw%40mail.gmail.com.


Re: [go-nuts] Orderly exit

2021-02-24 Thread roger peppe
On Tue, 23 Feb 2021 at 12:10, Kevin Chadwick  wrote:

> I only instigate panic manually for one thing. Perhaps that will change,
> but I doubt it.
>
> If I want to send out or write a log to disk then I will call panic rather
> than os.exit, upon a log.fatal scenario. Think buffered go routine logging.
> Saving the coder from having to think about it, once initialised.
>
> Which produces some ugly output and likely extra processing.
>
> Is it possible to call panic in a way that does not kill the process like
> os.Exit, but without log pollution?
>
> I am solely thinking of manually instigated panics, so a noop panic called
> something like terminate?
>
> Or is this bad practice, even when a program is in good operational order
> when instigated, as the OS is better at cleanup?
>

Personally, I'd advise against using panic or log.Fatal in this kind of
context - I'd just bite the bullet and return errors instead.
This makes it easy to move code between contexts if you need to without
worrying about non-local control flow.

For unexpected panics, you can still use recover to flush your log buffers,
assuming the panic happens in code that's been called by your code.

  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/3A8FA632-4991-4245-ABB3-8F4CE1164703%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/CAJhgacg0q31bn5K9SeyUmW%2BKjEg-d31xov095ixAn9Zs9VShEg%40mail.gmail.com.


Re: [go-nuts] Re: Few questions regarding Generics

2021-02-22 Thread roger peppe
On Mon, 22 Feb 2021 at 18:07, Khosrow Afroozeh 
wrote:

> aha, thanks for your help! One problem down.
>
> The error message is pretty cryptic though, I’d assumed the type inference
> would automatically take care of it, or complain about instantiation.
>

I think it should probably work, but currently I think that type inference
only works for function calls, not for type conversions.

The proposal doesn't allow closures or methods with their own type
parameters, so you'll need to define Map as a function rather than a method.

For example:  https://go2goplay.golang.org/p/8I9KPR03Kk2

>
> On Feb 22, 2021, at 6:25 PM, Volker Dobler 
> wrote:
>
> On Monday, 22 February 2021 at 15:03:53 UTC+1 Khosrow Afroozeh wrote:
>
>> type List[T any] []T
>>
>> 1. The current go2go implementation does not allow one to do this:
>>
>> func ToList[T any](v []T) List[T] {
>> return List(v)
>> }
>>
>> with the error: List(v) is not a type
>>
>> Is this a bug, shortcoming of the current implementation, or by design?
>> This would be a deal breaker if type-casting doesn't work for generics.
>>
>
> Given that there are no type casts in Go this is absolutely to be expected
> ;-)
> And type conversions need a type and List isn't (but List[T] would be one).
>
> V.
>
> --
> 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/NUDZ7gL-IIM/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/8c2a7b7d-ff11-4c8c-8dd4-2971ba6ab922n%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/2C15FD0D-933F-4CF7-AA88-686D232D38E0%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/CAJhgacjRBVZ2ru5gtxpkaMGz%2Bbmc9xCCQNjETfiQnUHyJxkmxQ%40mail.gmail.com.


Re: [go-nuts] Error handling

2021-02-20 Thread roger peppe
On Sat, 20 Feb 2021, 16:31 L Godioleskky,  wrote:

> Rust lang, very early in its evolution, saw the need to create its
> operator '?'  to more efficiently manage error handling. But the guardians
> of Go lang have resisted any changes to its clumsy method of error handling
> despite it being a major concern of Go users for a very long time.


Actually the "guardians of Go" (by which I guess you mean the Go team at
Google) tried quite hard recently to propose an improved way of handling
errors, but it was resisted by "Go users". So what you're saying is just
not true, I'm afraid.


>
> On Sunday, February 14, 2021 at 11:14:11 AM UTC-5 ohir wrote:
>
>> Dnia 2021-02-13, o godz. 17:44:47
>> Michael MacInnis  napisał(a):
>>
>> > I've been playing around with reducing error handling boilerplate
>>
>> You're not alone. Hundreds of us went into such thinking in the first
>> weeks
>> of reading/using Go - yet before we noticed how much more productive we
>> are with Go's "boilerplate" than we were in languages where handling
>> errors
>> (failures) was "a problem of others", including future-us as "others".
>>
>> Perceived consensus of the Go community is that "error handling
>> boilerplate"
>> is a strong feature. I.e. in normal production software you MUST handle
>> failures
>> and you should do it as close as possible to the source of said failure.
>>
>> Go helps with that. Even team's proposal was finally retracted:
>> https://github.com/golang/go/issues/32437 Discussion there is lengthy,
>> but worth
>> reading to sense why wider community considers "boilerplate" as asset.
>>
>> Error handling proposals umbrella:
>> https://github.com/golang/go/issues/40432
>>
>> > Michael.
>>
>> Hope this helps,
>>
>> --
>> 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+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/2b2b2ecc-18e6-4e4c-b71c-581d6ff0fc16n%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/CAJhgacim5uPaik2_QxgafB5uZ589ojWmbFdy54U6etHn4x5z0g%40mail.gmail.com.


Re: [go-nuts] big.Float.Cmp does not work as expected

2021-02-15 Thread roger peppe
Thanks for bringing this up. It surprised me too until I realised what was
going on.

The issue here is about the default precision that you're getting for those
big.Float values.
When you use big.NewFloat, the precision you get is exactly the same as
that of a base64 float (53 bits).
When you use SetString, you're getting 64 bits. If you change both float
values to use the same
precision, you'll see a difference in representation:
https://play.golang.org/p/4tBpBsPgGtE

This is documented, although arguably not that easy to find:

For the precision used by big.NewFloat:

NewFloat allocates and returns a new Float set to x, with precision 53


For the precision set by SetString:

If z's precision is 0, it is changed to 64 before rounding takes effect.


For the string output when used with fmt.Print:

The 'v' format is handled like 'g'.



> A negative precision selects the smallest number of decimal digits
> necessary to identify the value x uniquely using x.Prec() mantissa bits.


Actually I don't think the docs explicitly say that a missing precision for
%g is treated as a negative precision passed to the Text method, which
could be considered a flaw in the docs.

 One other thing to be aware of: the String method doesn't do quite what
you might expect: https://github.com/golang/go/issues/42887

  cheers,
rog.

On Sun, 14 Feb 2021 at 21:33, Santhosh Kumar T 
wrote:

> now I understand it. why they are not same
>
> but why f2 printed as 123.4139
> f2 is constructed using SetString method, so it should be accurate and
> printed as 123.4000.
>
> - Santhosh
>
> On Monday, February 15, 2021 at 2:53:45 AM UTC+5:30 kortschak wrote:
>
>> On Sun, 2021-02-14 at 13:19 -0800, Santhosh Kumar T wrote:
>> > When I print both values, they print exactly same. so I am assuming
>> > no precision lost for this specific example 123.4.
>> > but still Cmp returns non-zero.
>>
>> This is not a good assumption to make, and is refuted by the result of
>> Cmp.
>>
>> https://play.golang.org/p/ROr6cHMzWIf
>>
>>
>>
>>
>> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/b6a82206-6660-4a08-85bd-86e482b8527en%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/CAJhgacg-ZzDSupwS%2BaXdKfoCWveHvsT8NnDUVmo8NpD8sY6McA%40mail.gmail.com.


Re: [go-nuts] Possible to make base64 pick the decode encoding automatically?

2021-02-02 Thread roger peppe
In case you find it helpful, here's a clone of the base64 command that I
wrote in Go. I did it precisely because I wanted to be able to decode any
encoding scheme interchangeably.

https://github.com/rogpeppe/misc/blob/master/cmd/base64/base64.go

I agree that it might be useful to have some of this functionality
available in the standard library.

  cheers,
rog.

On Tue, 2 Feb 2021 at 09:08, hey...@gmail.com  wrote:

> Hi,
>
> I have an io.Reader whose content is encoded in base64 with encoding type
> unknown. Since there shouldn't be any ambiguity between the two, is it
> possible to make the base64 automatically pick the right one to decode?
>
> Currently I have to read everything out to pin down the encoding, which
> defeats the purpose of using an io.Reader.
>
> Is there a solution to this problem?
>
> Thanks in advance.
>
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/0ccee37d-319e-41b3-9bfd-3dc46e0fad78n%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/CAJhgacjkUUSr-dOPFU-W4vG_AXZRY_dYYe2ti-iPuu_XUL%2BNVw%40mail.gmail.com.


Re: [go-nuts] Re: Virtual time for testing

2021-02-01 Thread roger peppe
On Sat, 30 Jan 2021 at 20:12, Christian Worm Mortensen  wrote:

> Hi Mike,
>
> Thank you for your consideration. I think you exactly got the essence of
> my question: How do I wait on all go routines to finish (or be blocked on
> one or more channels) before advancing time.
>

This is an interesting problem that's not currently solved.

In the past, I've made a lot of use of this package:
https://pkg.go.dev/github.com/rogpeppe/clock
with its associated implementation for tests:
https://pkg.go.dev/github.com/rogpeppe/clock@v0.0.0-20190514195947-2896927a307a/testclock
It was originally developed as part of Canonical's Juju project.

To wait for goroutines to finish, you can use the WaitAdvance

method, which waits for at least n goroutines to block
on the clock before advancing time. This relies, of course, on all the code
under test using the Clock interface,
but that's not usually that hard to arrange.

There are a couple of deeper problems with this particular approach though:

 - in order to use WaitAdvance, you need to know the total number of
goroutines involved, but this is implementation-dependent, so someone
can break tests by making an apparently innocuous change that happens to
change goroutine count.

- it's still easy to make mistakes. It's easy to assume that when the
goroutines are blocked, the state that you're trying to observe
is static, but there may well be other goroutines still running that have
previously been triggered. This means that one
can end up polling state anyway if you're trying to test behaviour of an
independent "agent" goroutine.

In the end, I've largely given up on this fake clock approach in favour of
testing with real time (on the order of 10s of milliseconds not seconds)
and polling to wait for externally visible changes. This approach isn't
ideal either - if you make the time intervals too short, your
tests will be flaky; too long and you're waiting too long for tests to run.
But at least the tests aren't relying on details of
the internal implementation.

I'd love to see a way of fixing this in the standard Go runtime, but it's
not easy. Goroutines can be blocked in system calls (e.g. making an HTTP
call),
while still making progress, so just "wait for everything to be blocked
before advancing the clock" isn't a sufficient heuristic.
Also I'm not sure that a single clock is good enough because you might well
want to be able to time out your tests even as you're faking out
the clock for the code being tested.

  cheers,
rog.


A key thing I would like from such a solution is that it does not require
> too heavy modifications to the code to be tested or put restrictions on how
> it can do things.
>
> I think it may be possible to solve it with some explicit check in / check
> out as I think you also suggest. I guess in essence you will check out
> before you call select and check in again after select is done waiting. I
> think this will still not work if buffered channels are used. But maybe if
> buffered channels are mocked, it may be doable.
>
> I think I may want to make a feature request on this. I see several
> options:
>
> * Make a version of runtime.gosched that only returns when no other go
> routines can run
> * Make it possible to read the number of go routines that are ready to
> run. You could then make a loop where you call runtime.gosched until that
> value is 0.
> * Make it possible to start a special go routine when the system is
> deadlocked.
>
> One problem is what to do if the program is waiting on external IO such as
> the completion of an HTTP request. I guess in an ideal solution it would be
> possible for the program to decide if it will advance time in that
> situation or not.
>
> Please let me know if you have any ideas of other things to put into the
> feature request.
>
> Thanks,
>
> Christian
>
> On Fri, Jan 29, 2021 at 9:25 PM mspr...@us.ibm.com 
> wrote:
>
>> Volker: injecting sleep is a nice idea, in the general vein that Jesper
>> said of injecting time.  However, as soon as we zoom out a step and need to
>> test both that generator and the goroutine(s) consuming and acting upon
>> that channel activity, we get back to the essence of the original question:
>> how to test when we have a bunch of goroutines doing stuff and the test
>> needs to wait for them all to finish before advancing time?
>>
>> FYI, in Kubernetes we have done something similar to the Facebook clock
>> package --- but recently we have called out the narrower interface used by
>> code that only reads time.  See PassiveClock in
>> https://github.com/kubernetes/utils/blob/master/clock/clock.go and
>> https://github.com/kubernetes/apimachinery/blob/master/pkg/util/clock/clock.go
>> (yeah, we have two forked lines of development of this clock thing, sigh).
>>
>> The pattern of using channel activity to coordinate asynchronous activity
>> is inherently inimical 

Re: [go-nuts] Re: Interface arguments to generic functions

2021-01-20 Thread roger peppe
On Wed, 20 Jan 2021 at 11:04, Brian Candler  wrote:

> What do you make of this?
> https://go2goplay.golang.org/p/gN-FK2kbYK5
>
> Using interface values, it seems possible to bypass a declared constraint
> that two arguments have the same type.
>

This code is misleading. By passing the value to `reflect.TypeOf`, you're
losing the actual type of the value by
converting it to interface{} first. Contrast your example with this, where
we print the type of  and  instead
of a and b, and you'll see that actually the types are identical.

https://go2goplay.golang.org/p/CDmGFALAvCF

This all seems fine to me, tbh.

It does mean that you need to avoid invoking methods on freshly declared
instances of generic types, but
that's true for non-interface types too (the type might be a pointer). You
can also pass nil pointer values
as generic values, which can also panic when methods are invoked on them.

  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/CAJhgaciY1P0Sr_82scyEw2St5xWY1aXNQkATKwm%2BMrZy7akLXA%40mail.gmail.com.


Re: [go-nuts] [ANN] github.com/jba/codec, a fast encoder for Go

2021-01-20 Thread roger peppe
On Wed, 20 Jan 2021 at 13:31, Jonathan Amsterdam 
wrote:

> The encoding scheme is described briefly in the README[0] and the code[1].
>
> To answer your two specific questions, interfaces are represented as a
> pair (typeNumber, value) where typeNumber maps to a registered type. (Like
> gob, types must be registered.) Structs are represented as: startCode
> (fieldNumber value)* endCode. The field numbers are assigned by the
> generator.
>

It might be good to be more explicit about how the field numbers are
assigned. From a brief experiment, it seems like there's not a deterministic
relationship between a struct and its wire representation, and instead the
generated field numbers are taken from the generated code file
when it's present. So ISTM that any user of this must be very careful to
preserve that file, and realise that it's not OK to generate
the codec code for a type independently.

I'd also suggest that it would be good to fully document the syntax and
explain the trade-offs of this format and when
it might or might not be appropriate to use.

One other question: how are the type numbers maintained as stable entities
over time?

  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/CAJhgaciaEnx8r7169%3D8f9YPpFav9JmGf0wc%2BwGZEx72NTTO8tQ%40mail.gmail.com.


Re: [go-nuts] [ANN] github.com/jba/codec, a fast encoder for Go

2021-01-19 Thread roger peppe
This is interesting, thanks! Is there a full description of the encoding
somewhere? (e.g. how are structs represented? what about interface values,
etc? is the schema implicit or sent on the wire?)
  cheers,
rog.

On Tue, 19 Jan 2021 at 14:59, Jonathan Amsterdam 
wrote:

> Uses code generation for fast encoding and decoding of Go values to bytes.
> Handles sharing and cycles too.
>
> https://pkg.go.dev/github.com/jba/codec
>
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/2cc71201-ddbf-4524-88ba-7d0875072d80n%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/CAJhgachxdFvGX_WYk0t-Lw7SnhM-Hd%3DhWj2gDy191ZTaU-sQOg%40mail.gmail.com.


Re: [go-nuts] Workaround for No parameterized methods in go generics draft

2021-01-14 Thread roger peppe
FWIW I think that one possible approach to allowing methods (and
potentially function values) with type parameters might be to allow
instantiating them only with a limited set of "shapes" of data (for
example, only pointer-like types). Then I think there's the possibility
that the method or function could be compiled once for each allowed shape
but still allow instantiation with an arbitrary number of types, without
the necessity to statically enumerate all the possible types for that
function.

We need to instantiate p1.S.Identity[int] somewhere, but how?


If one did something like the above, I guess you'd look up the
implementation by shape (8 bytes, non pointer) from the type info in the
interface value, then call the compiled function with the appropriate meta
information based on that. Details left as an exercise for the reader :)

I don't see that reflection per se would need to be involved, any more than
reflection is involved when doing a dynamic type conversion.

  cheers,
rog.

On Wed, 13 Jan 2021 at 20:38, Marcus Manning  wrote:

>
> Regarding the the section of No parameterized methods in go generics
> draft:
>
> package p1 // S is a type with a parameterized method Identity. type S
> struct{} // Identity is a simple identity method that works for any type.
> func (S) Identity[T any](v T) T { return v } package p2 // HasIdentity is
> an interface that matches any type with a // parameterized Identity method.
> type HasIdentity interface { Identity[T any](T) T } package p3 import "p2"
> // CheckIdentity checks the Identity method if it exists. // Note that
> although this function calls a parameterized method, // this function is
> not itself parameterized. func CheckIdentity(v interface{}) { if vi, ok :=
> v.(p2.HasIdentity); ok { if got := vi.Identity[int](0); got != 0 {
> panic(got) } } } package p4 import ( "p1" "p3" ) // CheckSIdentity passes
> an S value to CheckIdentity. func CheckSIdentity() { p3.CheckIden
>
> But package p3 does not know anything about the type p1.S. There may be no
> other call to p1.S.Identity elsewhere in the program. We need to
> instantiate p1.S.Identity[int] somewhere, but how?
>
> The natural way would be to fetch instance sets (sets containing method
> implementations for any specified interface, here HasIdentity) as a matter
> of reflection.
>
> However, solving instance resolution over reflection alludes to the
> following questions:
>
>- Does reflection support generic instantiation?
>- Are generic types/functions are part of the runtime type information
>selectable for runtime reflection?
>- Are type to interface conformance relationships are part of the
>runtime type information?
>
> If all these questions can be answered by yes, then the case highlighted
> above is solvable.
>
> Alternatively, modulating the "CheckIdentity" function by the compiler to:
> func CheckIdentity(v interface{},
> hiddenHasIdentityInstanceContainingPointerToIdentityMethod) { if vi, ok :=
> v.(p2.HasIdentity); ok { if got := vi.Identity[int](0); got != 0 {
> panic(got) } } }
>
> serves providing an instance automatically by calling "CheckIdentity"
> function. This hidden parameter needs to be up-propagated to all callers
> passing p1.S down the caller-callee hierarchy.
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/420e8a74-d9f8-4df9-9d7b-efffb642fbe8n%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/CAJhgaci2EutMD9dxpeiW%3DrKapyHUad7mSL7VxMjLVFt7NQXamA%40mail.gmail.com.


Re: [go-nuts] Workaround for No parameterized methods in go generics draft

2021-01-14 Thread roger peppe
On Wed, 13 Jan 2021 at 20:38, Marcus Manning  wrote:

>
> Regarding the the section of No parameterized methods in go generics
> draft:
>
> package p1 // S is a type with a parameterized method Identity. type S
> struct{} // Identity is a simple identity method that works for any type.
> func (S) Identity[T any](v T) T { return v } package p2 // HasIdentity is
> an interface that matches any type with a // parameterized Identity method.
> type HasIdentity interface { Identity[T any](T) T } package p3 import "p2"
> // CheckIdentity checks the Identity method if it exists. // Note that
> although this function calls a parameterized method, // this function is
> not itself parameterized. func CheckIdentity(v interface{}) { if vi, ok :=
> v.(p2.HasIdentity); ok { if got := vi.Identity[int](0); got != 0 {
> panic(got) } } } package p4 import ( "p1" "p3" ) // CheckSIdentity passes
> an S value to CheckIdentity. func CheckSIdentity() { p3.CheckIden
>

This code seems corrupted (no newlines) and incomplete. It's hard to
understand what your question is about without seeing the motivational code.

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


Re: [go-nuts] Generics and constraints question

2021-01-05 Thread roger peppe
You can do this with type-list interfaces:
https://go2goplay.golang.org/p/wfHnVHOMcyK

This is one of the harder parts of the proposal to understand IMHO, but
perhaps it will become easier with familiarity.

On Tue, 5 Jan 2021, 17:32 Brian Candler,  wrote:

> Question: how to make a generic function which takes a type T where the
> constraint is "*T satisfies a given interface"?
>
> func (m *MyMap[KT, VT]) init() {
> m.data = make(map[KT]VT)
> }
>
> type Initializer interface {
> init()
> }
>
> func mynew[T Initializer]() *T {
> t := new(T)
> t.init()
> return t
> }
>
> /* or:
> func mynew[T Initializer]() *T {
> var t T
> t.init()
> return 
> }
> */
>
> func main() {
> m := mynew[MyMap[string, int]]()
> }
>
> gives:
>
> type checking failed for main prog.go2:34:13: MyMap[string, int] does not
> satisfy Initializer: wrong method signature
> got func (*MyMap[KT, VT]).init()
> want func (Initializer).init()
>
> Full code: https://go2goplay.golang.org/p/INcenfcInSl
>
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/13dcb9b5-da98-49b9-abf7-05c95b1d4ebdn%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/CAJhgacgvJ%3D6eoH_Uh%2B69SdDk3C0nMep35SUhpv4QnsgAQw3kcA%40mail.gmail.com.


Re: [go-nuts] Generics - please provide real life problems

2021-01-03 Thread roger peppe
FWIW I'm certain that the lack of tuples in Go was a very deliberate
decision - one of Go's more significant ancestors, Limbo, had tuples.
Anonymous product types have their disadvantages too (you don't get to name
the members, so code can end up significantly harder to understand), which
I suspect is why Go didn't get them.

> People will even realize that when you compile this, you don't have to
pass a pointer to said tuple but can make a choice on calling convention
which passes such tuples in registers to speed up the system and be as fast
as any other language.

I believe that the new register calling convention will do this for structs
FWIW.


On Sun, 3 Jan 2021 at 13:25, Jesper Louis Andersen <
jesper.louis.ander...@gmail.com> wrote:

>
> On Thu, Dec 31, 2020 at 9:45 PM da...@suarezhouse.net <
> da...@suarezhouse.net> wrote:
>
>> Real use cases have been provided it appears for both why generics can be
>> good and how they can be used negligently (love the sextuple example BTW).
>
>
> Some future language will invent the idea that you should be able to
> create anonymous product types on the fly and use those as return values
> when you want multiple return values. They'll even realize once you have
> anonymous product types, every function just needs to take a single
> argument and return a single argument, since you can just use an anonymous
> product type (i.e., a tuple) if you want to pass multiple things. People
> will even realize that when you compile this, you don't have to pass a
> pointer to said tuple but can make a choice on calling convention which
> passes such tuples in registers to speed up the system and be as fast as
> any other language.
>
> Then people will have reinvented Standard ML from 1991.
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/CAGrdgiVJe_2L5QZ13v-SBZq2C7_e6nX8JDCAE23BcpWqGyH99Q%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/CAJhgaci-M2iL%3DjPL2KB3BbhzRahBz4pjDUPjkiTAF_jjza6FAw%40mail.gmail.com.


Re: [go-nuts] Generics Error - How to fix?

2021-01-01 Thread roger peppe
On Fri, 1 Jan 2021, 17:49 da...@suarezhouse.net, 
wrote:

> First of all --  awesome, thanks!!!
>
> Question 1:  the need for the additional typeOf function you added at the
> end, would that be needed in a future implementation or would that be
> deduced in the existing reflect.TypeOf in the future?
>

It's not needed even now - I just included it because I think it's neat,
and works correctly even when the type parameters are interface types.

>
> Question 2:  this experience has shown me a bit better that anything is
> possible but will take some getting used to.  Do you think having an
> "import generics" similar to unsafe as a separate in the actual "library"
> part of the code would resolve the concerns on user cleanliness?  This
> example I think shows me that if the library writer is careful the end user
> of the library would have a very minimal impact.  As a side note, I started
> playing with this to understand the other generics long thread going on :-)
>

Personally, my main concerns about cleanliness are not about when packages
are trying to minimise the generic API, but that people with experience in
other languages bring a lot of the patterns they've previously used until
Go.

Pervasive use of iterators is one such - I can easily see a future where
people are criticising the Go compiler because it can't optimise some
iterator-based solution enough.

Another concern is that people will use type parameters instead of
interfaces for their efficiency properties rather than for correctness (for
example by using a type parameter as an argument to a constructor rather
than using an interface value, making the type harder to use because of the
need to reference the type parameter every time the generic type is used).
Many people seem to be aiming that the Go compiler will monomorphise all
generic instances. I'm not sure that that's a good idea because it is
likely to increase the pressure to use generic types even when there are
sufficient usability disadvantages.

Instead, I am hoping that the cost of invoking a method on a generic value
will be roughly comparable with that of invoking a method on an interface
value, thus hopefully making it easier for people to choose to use the
simpler non-generic solution without incurring too much relative
performance overhead.


> Thanks again for solving this so quickly!!!
> David
> On Friday, January 1, 2021 at 10:50:57 AM UTC-6 rog wrote:
>
>> You need to declare the type parameters in the method definitions too.
>> Something like this works OK:
>>
>> https://go2goplay.golang.org/p/ZUAVncRrmZW
>>
>>   cheers,
>> rog.
>>
>> On Fri, 1 Jan 2021 at 15:06, da...@suarezhouse.net 
>> wrote:
>>
>>> I thought I read the generics doc well but.. :-)  Help is appreciated:
>>>
>>> I instantiate a generic table example here in line 41:
>>> https://go2goplay.golang.org/p/SadxA0khqx7
>>>
>>> Then I use it in lines 42 and 43.
>>>
>>> The errors I get are below:
>>> prog.go2:67:10: cannot use generic type Table[colA, colB, colC
>>> fmt.Stringer] without instantiation
>>> prog.go2:72:10: cannot use generic type Table[colA, colB, colC
>>> fmt.Stringer] without instantiation
>>>
>>> I am using the same table.  The method belongs to the struct so I would
>>> think should be considered instantiated and that I wouldn't have to repeat
>>> in lines 42 and 43 the types.
>>>
>>> Is this a bug and it should infer since created in line 41 or what did I
>>> misunderstand in the doc?
>>>
>>> Thanks in advance for the help!
>>> David
>>>
>>> --
>>> You received this message because you are subscribed 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/9c999eee-3887-4d64-a41d-9402a1103a47n%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/c0c30a34-af6f-4f32-8965-c84853d58377n%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/CAJhgachPJ0Xt6E%2B54iatZaGVg2FWWk0i4E1%3DfomK%2B%2BaDCLitqw%40mail.gmail.com.


Re: [go-nuts] Generics Error - How to fix?

2021-01-01 Thread roger peppe
You need to declare the type parameters in the method definitions too.
Something like this works OK:

https://go2goplay.golang.org/p/ZUAVncRrmZW

  cheers,
rog.

On Fri, 1 Jan 2021 at 15:06, da...@suarezhouse.net 
wrote:

> I thought I read the generics doc well but.. :-)  Help is appreciated:
>
> I instantiate a generic table example here in line 41:
> https://go2goplay.golang.org/p/SadxA0khqx7
>
> Then I use it in lines 42 and 43.
>
> The errors I get are below:
> prog.go2:67:10: cannot use generic type Table[colA, colB, colC
> fmt.Stringer] without instantiation
> prog.go2:72:10: cannot use generic type Table[colA, colB, colC
> fmt.Stringer] without instantiation
>
> I am using the same table.  The method belongs to the struct so I would
> think should be considered instantiated and that I wouldn't have to repeat
> in lines 42 and 43 the types.
>
> Is this a bug and it should infer since created in line 41 or what did I
> misunderstand in the doc?
>
> Thanks in advance for the help!
> David
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/9c999eee-3887-4d64-a41d-9402a1103a47n%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/CAJhgacjt4f9FEa%3DGtyGUJ3fh2LFvQ64iijOYZECLDEDvP_xcyA%40mail.gmail.com.


Re: [go-nuts] Generics - please provide real life problems

2020-12-31 Thread roger peppe
Here's one real life example that I came across recently.

I have a CRUD API that supports a bunch of different entity types. They all
support a superset of the same operations.
Each method represents a single HTTP call.

If the generics proposal was implemented, I'd be able to define a common
interface between them all.
Something like this:

type CRUD[Entity any] interface {
Find(ctx context.Context, filter Filter) ([]Entity, error)
FindOne(ctx context.Context, filter Filter) ([]Entity,
error)
Create(ctx context.Context, entity Entity) (Entity, error)
Update(ctx context.Context, entity Entity) (Entity, error)
Delete(ctx context.Context, id string) error
}

The Find operation allows the specification of a start-count window of
results to return.
It would be really nice to be able to define a generic function like this:

func FindAll[Entity any](api CRUD[Entity], filter Filter) ([]Entity,
error)

which would iterate return a slice of all the entities regardless of how
many underlying
calls to Find are needed.

Currently I can't easily do that. I could change the methods so that they
just returned interface
values instead of the respective entity types, but that would make the API
harder and more
error-prone to use. I could use reflection, but that code would be even
harder to read and maintain.

Currently I might end up using code generation, but that has its own issues
(I'd have to write
a code generator, or use some kind of template scheme, in which case the
actual source wouldn't
be amenable to gofmt and static checking).

  cheers,
rog.

On Thu, 24 Dec 2020 at 06:15, Martin Hanson 
wrote:

> I have been arguing passionately against adding generics to Go because
> I truly believe that it is going against the simplicity of Go and the
> philosophy behind the design of Go.
>
> I believe that the resilience of Go against unnecessary change is of
> vital importance. The experience provided by Ken Thompson, Rob Pike and
> Robert Griesemer in designing Go the way they did speaks for itself.
>
> I feel and believe it is of imperative importance to avoid adding things
> to Go that doesn't present a true and real life day-to-day problem
> and so far none of the examples the pro-generics camp has provided has
> been more than minor theoretical examples that do not present any real
> life problems.
>
> I therefore propose that the pro-generics camp provide real examples of
> problems they have faced that was such a big issue that it justifies
> adding generics to Go.
>
> If all we're presented are these small theoretical examples of sorting
> lists, etc., then clearly this is nothing but hype that needs to go
> away.
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/19560461608790506%40sas1-75175cadc2b3.qloud-c.yandex.net
> .
>

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


Re: [go-nuts] How to set the "godebug" environment variable from the go file?

2020-12-20 Thread roger peppe
On Wed, 16 Dec 2020, 21:29 Ian Lance Taylor,  wrote:

> On Wed, Dec 16, 2020 at 8:49 AM Sean  wrote:
> >
> > hi all,
> > i have a project I have to work with CGo. I want to disable some
> > controls as they are not good enough right now.
> > It works when I write "set godebug=cgocheck=0" on Windows in console.
> > However, this is a GUI program. Console should not open.
> >
> > I tried this with "os.Setenv". I define it in "func init" it doesn't
> work.
> >
> > Something like this:
> >
> > func init() {
> >  os.Setenv("godebug", "cgocheck=0")
> > }
> >
> > What should I do?
>
> At present I believe that the best you can do is something like, in
> main (untested):
>
> if os.Getenv("GODEBUG") == "" {
> cmd := exec.Command(os.Args[0], os.Args[1:]...)
>

It's probably better to use https://golang.org/pkg/os/#Executable rather
than os.Args[0] here.

cmd.Env = append(os.Environ(), "GODEBUG=cgocheck=0")
> if err := cmd.Run(); err != nil {
> os.Exit(1)
> }
> os.Exit(0)
> }
>
> 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/CAOyqgcXVReo%2BbBf5ZawwO3QcMUEkRMy5QFxgUbG%2BuOjmmyCT5A%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/CAJhgacibQ%3DfUsntDDZYAfQAn%3D2%2Bf-yFjXtzKccjG%3D1rTu7PwEg%40mail.gmail.com.


Re: [go-nuts] [generics] combining different instances of the same generic type

2020-12-02 Thread roger peppe
On Wed, 2 Dec 2020 at 09:15, roger peppe  wrote:

> Also your delayed blocks don't wait for the preceding set of futures to be
>> exhausted before proceeding, I think they're all triggered once the initial
>> set is completed
>
>
> Each delayed block is triggered when its associated delay has elapsed.
> Once the initial set is completed, it returns immediately. Isn't that what
> you want? As I said, I'm finding it hard to imagine a scenario where these
> particular semantics are useful, so it's not easy to decide how to treat
> the edge cases.
>
> I think my issue comes down to being unsure about how to
>> easily/consistently perform mappings between generic types (like F[A] ->
>> F[B]).
>
>
> I assume that by "perform mappings" you're wondering how to write a
> function like this:
>
> // Map returns a future that yields fn(r) where r is the result value of f.
> func Map[A, B any](f *F[A], fn func(A) B) *F[B]
>
> I don't believe that's possible with your existing package.
>

I'm talking rubbish there, I'm afraid. It's entirely possible to do this,
albeit at the cost of an extra goroutine:

func Map[A, B any](f *F[A], fn func(A) B) *F[B] {
return Start(func() (B, error) {
a, err := f.Result()
if err != nil {
return *new(B), err
}
return fn(a), nil
})
}

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


Re: [go-nuts] [generics] combining different instances of the same generic type

2020-12-02 Thread roger peppe
appings between generic
> types (like F[A] -> F[B]). A second thing that's not clear is how to handle
> the type F when I don't care about what type it's been instantiated with
> (say I wanted to retain the existing code, but I know that if F is in the
> original map[F[struct{}]struct{}] timeouts that it's a F[struct{}],
> otherwise it's F[T] (and I'm happy to type-assert at that point)). It's
> clearly not F[interface{}], for lack of better notation, I'll call it F[*].
>
> On Wed, 2 Dec 2020 at 10:07, roger peppe  wrote:
>
>> And again (no need to make a cancelable context)
>> https://go2goplay.golang.org/p/3UFUaXijuX9
>>
>> On Tue, 1 Dec 2020 at 22:59, roger peppe  wrote:
>>
>>> Slightly simpler again: https://go2goplay.golang.org/p/mKdishv4nhT
>>>
>>> On Tue, 1 Dec 2020 at 18:44, roger peppe  wrote:
>>>
>>>> I'm having difficulty understanding exactly what your code is trying to
>>>> do (and why), and that makes it hard to understand what
>>>> generic solution might be appropriate.
>>>>
>>>> However, here's one alternative implementation that doesn't seem to run
>>>> into the same kind of issues that you did.
>>>> It changes the contract a little bit, but it's still within the spirit,
>>>> I think and it's somewhat simpler:
>>>>
>>>> https://go2goplay.golang.org/p/cEWEUrvfZBl
>>>>
>>>> FWIW when I've implemented this kind of logic in the past, the aim is
>>>> usually to obtain at most one result. I don't really understand the use
>>>> case being implemented here.
>>>>
>>>> To address the actual question you raised:
>>>>
>>>> I ran into the situation where I need to "map" the futures of type
>>>>> *F[int], and *F[T] to *F[timeoutOrResult[T]].
>>>>
>>>>
>>>> There's no reason why interface types won't still play a large role in
>>>> the future where Go has generics, and that's
>>>> how I'd probably represent timeoutOrResult there, with a dynamic type
>>>> switch to decide which one you've got.
>>>>
>>>>   cheers,
>>>> rog.
>>>>
>>>> On Mon, 30 Nov 2020 at 02:09, Matt Joiner  wrote:
>>>>
>>>>> I had a muck around with go2 generics with my toy-ish futures package
>>>>> https://github.com/anacrolix/futures. The go1 implementation is in
>>>>> master, and a working go2 implementation in the go2 branch (using channels
>>>>> of different types instead of the attempt that follows). The package
>>>>> provides one function AsCompletedDelayed, that allows to favour futures
>>>>> over others with timeouts. The timeouts are implemented using the future
>>>>> type *F[int], where as the futures the user provides as arguments are
>>>>> *F[T]. In the implementation for AsCompletedDelayed I need to pass both
>>>>> types of futures to another function AsCompleted[T](fs ...*F[T]) <-chan
>>>>> *F[T], then differentiate them when they're returned: I could get back a
>>>>> "timeout" future, or a user/argument future. To do this I created another
>>>>> type timeoutOrResult[T] struct { timeout bool; timeoutIndex int; result T
>>>>> }, however now I ran into the situation where I need to "map" the futures
>>>>> of type *F[int], and *F[T] to *F[timeoutOrResult[T]]. This seems
>>>>> non-trivial: I believe in another language I would make F a Functor, and
>>>>> map the timeouts to something like `Either int T`. It is possible to write
>>>>> an Fmap on my *F type, but now I need to create new types, and break out 
>>>>> an
>>>>> interface, and the implementation quickly increases in complexity.
>>>>>
>>>>> This seems like a situation where the go1 style of doing this was
>>>>> easier albeit without enforcing the result types of the futures in the
>>>>> return chan for AsCompleted and AsCompletedDelayed: I could pass arbitrary
>>>>> *Fs to AsCompleted, and then compare the returning *F against a
>>>>> map[*F]struct{} that tracked which ones were timeouts.
>>>>>
>>>>> --
>>>>> You received this message because you are subscribed to the Google
>>>>> Groups "golang-nuts" group.
>>>>> To unsubscribe from this group and stop receiving emails from it, send
>>>>> an email to golang-nuts+unsubscr...@googlegroups.com.
>>>>> To view this discussion on the web visit
>>>>> https://groups.google.com/d/msgid/golang-nuts/adb04bb6-bdda-41a9-a168-2541dd912171n%40googlegroups.com
>>>>> <https://groups.google.com/d/msgid/golang-nuts/adb04bb6-bdda-41a9-a168-2541dd912171n%40googlegroups.com?utm_medium=email_source=footer>
>>>>> .
>>>>>
>>>>

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


Re: [go-nuts] [generics] combining different instances of the same generic type

2020-12-01 Thread roger peppe
And again (no need to make a cancelable context)
https://go2goplay.golang.org/p/3UFUaXijuX9

On Tue, 1 Dec 2020 at 22:59, roger peppe  wrote:

> Slightly simpler again: https://go2goplay.golang.org/p/mKdishv4nhT
>
> On Tue, 1 Dec 2020 at 18:44, roger peppe  wrote:
>
>> I'm having difficulty understanding exactly what your code is trying to
>> do (and why), and that makes it hard to understand what
>> generic solution might be appropriate.
>>
>> However, here's one alternative implementation that doesn't seem to run
>> into the same kind of issues that you did.
>> It changes the contract a little bit, but it's still within the spirit, I
>> think and it's somewhat simpler:
>>
>> https://go2goplay.golang.org/p/cEWEUrvfZBl
>>
>> FWIW when I've implemented this kind of logic in the past, the aim is
>> usually to obtain at most one result. I don't really understand the use
>> case being implemented here.
>>
>> To address the actual question you raised:
>>
>> I ran into the situation where I need to "map" the futures of type
>>> *F[int], and *F[T] to *F[timeoutOrResult[T]].
>>
>>
>> There's no reason why interface types won't still play a large role in
>> the future where Go has generics, and that's
>> how I'd probably represent timeoutOrResult there, with a dynamic type
>> switch to decide which one you've got.
>>
>>   cheers,
>> rog.
>>
>> On Mon, 30 Nov 2020 at 02:09, Matt Joiner  wrote:
>>
>>> I had a muck around with go2 generics with my toy-ish futures package
>>> https://github.com/anacrolix/futures. The go1 implementation is in
>>> master, and a working go2 implementation in the go2 branch (using channels
>>> of different types instead of the attempt that follows). The package
>>> provides one function AsCompletedDelayed, that allows to favour futures
>>> over others with timeouts. The timeouts are implemented using the future
>>> type *F[int], where as the futures the user provides as arguments are
>>> *F[T]. In the implementation for AsCompletedDelayed I need to pass both
>>> types of futures to another function AsCompleted[T](fs ...*F[T]) <-chan
>>> *F[T], then differentiate them when they're returned: I could get back a
>>> "timeout" future, or a user/argument future. To do this I created another
>>> type timeoutOrResult[T] struct { timeout bool; timeoutIndex int; result T
>>> }, however now I ran into the situation where I need to "map" the futures
>>> of type *F[int], and *F[T] to *F[timeoutOrResult[T]]. This seems
>>> non-trivial: I believe in another language I would make F a Functor, and
>>> map the timeouts to something like `Either int T`. It is possible to write
>>> an Fmap on my *F type, but now I need to create new types, and break out an
>>> interface, and the implementation quickly increases in complexity.
>>>
>>> This seems like a situation where the go1 style of doing this was easier
>>> albeit without enforcing the result types of the futures in the return chan
>>> for AsCompleted and AsCompletedDelayed: I could pass arbitrary *Fs to
>>> AsCompleted, and then compare the returning *F against a map[*F]struct{}
>>> that tracked which ones were timeouts.
>>>
>>> --
>>> You received this message because you are subscribed to the Google
>>> Groups "golang-nuts" group.
>>> To unsubscribe from this group and stop receiving emails from it, send
>>> an email to golang-nuts+unsubscr...@googlegroups.com.
>>> To view this discussion on the web visit
>>> https://groups.google.com/d/msgid/golang-nuts/adb04bb6-bdda-41a9-a168-2541dd912171n%40googlegroups.com
>>> <https://groups.google.com/d/msgid/golang-nuts/adb04bb6-bdda-41a9-a168-2541dd912171n%40googlegroups.com?utm_medium=email_source=footer>
>>> .
>>>
>>

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


Re: [go-nuts] [generics] combining different instances of the same generic type

2020-12-01 Thread roger peppe
Slightly simpler again: https://go2goplay.golang.org/p/mKdishv4nhT

On Tue, 1 Dec 2020 at 18:44, roger peppe  wrote:

> I'm having difficulty understanding exactly what your code is trying to do
> (and why), and that makes it hard to understand what
> generic solution might be appropriate.
>
> However, here's one alternative implementation that doesn't seem to run
> into the same kind of issues that you did.
> It changes the contract a little bit, but it's still within the spirit, I
> think and it's somewhat simpler:
>
> https://go2goplay.golang.org/p/cEWEUrvfZBl
>
> FWIW when I've implemented this kind of logic in the past, the aim is
> usually to obtain at most one result. I don't really understand the use
> case being implemented here.
>
> To address the actual question you raised:
>
> I ran into the situation where I need to "map" the futures of type
>> *F[int], and *F[T] to *F[timeoutOrResult[T]].
>
>
> There's no reason why interface types won't still play a large role in the
> future where Go has generics, and that's
> how I'd probably represent timeoutOrResult there, with a dynamic type
> switch to decide which one you've got.
>
>   cheers,
> rog.
>
> On Mon, 30 Nov 2020 at 02:09, Matt Joiner  wrote:
>
>> I had a muck around with go2 generics with my toy-ish futures package
>> https://github.com/anacrolix/futures. The go1 implementation is in
>> master, and a working go2 implementation in the go2 branch (using channels
>> of different types instead of the attempt that follows). The package
>> provides one function AsCompletedDelayed, that allows to favour futures
>> over others with timeouts. The timeouts are implemented using the future
>> type *F[int], where as the futures the user provides as arguments are
>> *F[T]. In the implementation for AsCompletedDelayed I need to pass both
>> types of futures to another function AsCompleted[T](fs ...*F[T]) <-chan
>> *F[T], then differentiate them when they're returned: I could get back a
>> "timeout" future, or a user/argument future. To do this I created another
>> type timeoutOrResult[T] struct { timeout bool; timeoutIndex int; result T
>> }, however now I ran into the situation where I need to "map" the futures
>> of type *F[int], and *F[T] to *F[timeoutOrResult[T]]. This seems
>> non-trivial: I believe in another language I would make F a Functor, and
>> map the timeouts to something like `Either int T`. It is possible to write
>> an Fmap on my *F type, but now I need to create new types, and break out an
>> interface, and the implementation quickly increases in complexity.
>>
>> This seems like a situation where the go1 style of doing this was easier
>> albeit without enforcing the result types of the futures in the return chan
>> for AsCompleted and AsCompletedDelayed: I could pass arbitrary *Fs to
>> AsCompleted, and then compare the returning *F against a map[*F]struct{}
>> that tracked which ones were timeouts.
>>
>> --
>> You received this message because you are subscribed to the Google Groups
>> "golang-nuts" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to golang-nuts+unsubscr...@googlegroups.com.
>> To view this discussion on the web visit
>> https://groups.google.com/d/msgid/golang-nuts/adb04bb6-bdda-41a9-a168-2541dd912171n%40googlegroups.com
>> <https://groups.google.com/d/msgid/golang-nuts/adb04bb6-bdda-41a9-a168-2541dd912171n%40googlegroups.com?utm_medium=email_source=footer>
>> .
>>
>

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


Re: [go-nuts] [generics] combining different instances of the same generic type

2020-12-01 Thread roger peppe
I'm having difficulty understanding exactly what your code is trying to do
(and why), and that makes it hard to understand what
generic solution might be appropriate.

However, here's one alternative implementation that doesn't seem to run
into the same kind of issues that you did.
It changes the contract a little bit, but it's still within the spirit, I
think and it's somewhat simpler:

https://go2goplay.golang.org/p/cEWEUrvfZBl

FWIW when I've implemented this kind of logic in the past, the aim is
usually to obtain at most one result. I don't really understand the use
case being implemented here.

To address the actual question you raised:

I ran into the situation where I need to "map" the futures of type *F[int],
> and *F[T] to *F[timeoutOrResult[T]].


There's no reason why interface types won't still play a large role in the
future where Go has generics, and that's
how I'd probably represent timeoutOrResult there, with a dynamic type
switch to decide which one you've got.

  cheers,
rog.

On Mon, 30 Nov 2020 at 02:09, Matt Joiner  wrote:

> I had a muck around with go2 generics with my toy-ish futures package
> https://github.com/anacrolix/futures. The go1 implementation is in
> master, and a working go2 implementation in the go2 branch (using channels
> of different types instead of the attempt that follows). The package
> provides one function AsCompletedDelayed, that allows to favour futures
> over others with timeouts. The timeouts are implemented using the future
> type *F[int], where as the futures the user provides as arguments are
> *F[T]. In the implementation for AsCompletedDelayed I need to pass both
> types of futures to another function AsCompleted[T](fs ...*F[T]) <-chan
> *F[T], then differentiate them when they're returned: I could get back a
> "timeout" future, or a user/argument future. To do this I created another
> type timeoutOrResult[T] struct { timeout bool; timeoutIndex int; result T
> }, however now I ran into the situation where I need to "map" the futures
> of type *F[int], and *F[T] to *F[timeoutOrResult[T]]. This seems
> non-trivial: I believe in another language I would make F a Functor, and
> map the timeouts to something like `Either int T`. It is possible to write
> an Fmap on my *F type, but now I need to create new types, and break out an
> interface, and the implementation quickly increases in complexity.
>
> This seems like a situation where the go1 style of doing this was easier
> albeit without enforcing the result types of the futures in the return chan
> for AsCompleted and AsCompletedDelayed: I could pass arbitrary *Fs to
> AsCompleted, and then compare the returning *F against a map[*F]struct{}
> that tracked which ones were timeouts.
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/adb04bb6-bdda-41a9-a168-2541dd912171n%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/CAJhgacj5PFtT6P-CCBTQXgs%3DasU2TBW-xW88ikNL_9e5-xBotg%40mail.gmail.com.


Re: [go-nuts] Go modules replace statements referencing legacy codebases

2020-11-07 Thread roger peppe
I don't quite understand why you're using replace directives here rather
than just declaring the pseudo-version as a requirement.

Why wouldn't that work?

On Fri, 6 Nov 2020, 14:19 Jim Minter,  wrote:

> Hi,
>
> Using Go 1.14, I'm working on a parent codebase which, in its go.mod
> file, has a number of replace statements referencing legacy child
> codebases which have not yet converted to Go modules.
>
> At this stage the legacy child codebases handle versioning by branch,
> rather than using semantic versioning, so my go.mod file has a number of
> statements like these:
>
> > replace github.com/foo/bar => github.com/foo/bar
> v0.0.0-2020xx- // should track branch baz
> > replace github.com/foo/bar1 => github.com/foo/bar1
> v0.0.0-2020yy- // should track branch baz
>
> My goal is to be confident that if I update dependencies in the parent
> codebase (go get -u ./...), I'll be pulling in HEAD on the relevant
> branch of all the legacy child dependencies.
>
> My expectation is that this is a transitional use case because
> eventually the child codebases will migrate to Go modules, but until
> then, it's important to me to know I will pull in critical fixes from
> the child dependencies if they happen.
>
> The difficulty I've got is ensuring that the replace stanzas are valid
> and up-to-date.  I'm not finding a great way to do this with the Go
> module tooling and I wonder if I'm missing anything.  Here are the
> feasible ugly alternatives I've found so far:
>
> 1. Child by child, abuse the fact that `go mod tidy` rightly or wrongly
> seems to tolerate a single legacy branch reference in the file at a time
> and rewrites it to the v0.0.0-2020xx- format:
>
> > go mod edit -replace github.com/foo/bar=github.com/foo/bar@baz
> > go mod tidy
> > go mod edit -replace github.com/foo/bar1=github.com/foo/bar1@baz
> > go mod tidy
> > ...etc...
> > go get -u ./...
>
> 2. A script to be run manually (or via go generate? yikes!) before
> running go get -u ./..., containing abominations like this:
>
> > go mod edit -replace github.com/foo/bar=$(go list -mod=mod -m
> github.com/foo/bar@baz | sed -e 's/ /@/')
> > go mod edit -replace github.com/foo/bar1=$(go list -mod=mod -m
> github.com/foo/bar1@baz | sed -e 's/ /@/')
> > ...etc...
> > go get -u ./...
>
> 3. Alternative abominations like this:
>
> > go mod edit -replace github.com/foo/bar=github.com/foo/bar $(curl -s
> https://proxy.golang.org/github.com/foo/bar/@v/baz.info | jq -r .Version)
> > go mod edit -replace github.com/foo/bar1=github.com/foo/bar1 $(curl -s
> https://proxy.golang.org/github.com/foo/bar1/@v/baz.info | jq -r .Version)
> > ...etc...
> > go get -u ./...
>
> I'm wondering: is there a better way?  Should there be?
>
> Many thanks!
>
> Jim Minter
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/922448f0-00cf-7f7e-efdc-50965aefc6d4%40minter.uk
> .
>

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


Re: [go-nuts] Table driven tests and error/output testing

2020-10-20 Thread roger peppe
It looks like you're testing a top level command. You might want to
consider using the testscript package, which provides a very concise way of
end-to-end testing this kind of thing.

e.g.

mycommand -h
cmp stdout expect-stdout

-- expect-stdout --
Expected output

See https://pkg.go.dev/github.com/rogpeppe/go-internal/testscript for more
details.

On Tue, 20 Oct 2020 at 05:02, Amit Saha  wrote:

> Hi all, Consider the following test configuration:
>
>
> func TestHandleCommand(t *testing.T) {
>
> type expectedResult struct {
> output string
> errerror
> }
> type testConfig struct {
> args   []string
> result expectedResult
> }
>
> testConfigs := []testConfig{
> testConfig{
> args: []string{"-h"},
> result: expectedResult{
> err: nil,
> output: `Expected output`,
> },
> },
> }
>
> Then, I do this:
>
>
> for _, tc := range testConfigs {
> byteBuf := new(bytes.Buffer)
> w := bufio.NewWriter(byteBuf)
>
> err := handleCommand(w, tc.args)
> if tc.result.err == nil && err != nil {
> t.Errorf("Expected nil error, got %v", err)
> }
>
> if tc.result.err != nil && err.Error() != tc.result.err.Error() {
> t.Errorf("Expected error %v, got %v", tc.result.err, err)
> }
>
> if len(tc.result.output) != 0 {
> w.Flush()
> gotOutput := byteBuf.String()
> if tc.result.output != gotOutput {
> t.Errorf("Expected output to be: %v, Got: %v",
> tc.result.output, gotOutput)
> }
> }
> }
> }
>
> The above pattern works for me since the function may return an error
> and/or it may have something it writes to the provided writer, w.
>
> Is there a more concise way to write this?
>
>
>
> Thanks,
> Amit.
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/CANODV3%3DsOA4FKakaQ0mrcC%3D-BnVNq8SdnvDHgXShmrRt-_upHw%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/CAJhgacjCaCOq%2BYHFmcoH7At30H%2Bmn7t2fSvw%2B_Av4%2BhqDeHQhg%40mail.gmail.com.


Re: [go-nuts] global goroutine data / thread local storage?

2020-09-26 Thread roger peppe
On Sat, 26 Sep 2020, 02:36 Alex Besogonov,  wrote:

> On Friday, September 25, 2020 at 4:43:45 PM UTC-7 Ian Lance Taylor wrote:
>
>> On Fri, Sep 25, 2020 at 10:35 AM Alex Besogonov
>>  wrote:
>> >
>> > Inheritable goroutine-locals would actually work just fine in Go.
>> Moreover, Go actually has them in the form of pprof labels.
>> What should happen if one goroutine changes an inherited
>> goroutine-local variable?
>>
> A Go-style goroutine-local system can be thought as a context.Context that
> is transparently assigned to a goroutine and its children. Thus if you want
> to change the value, you'd do something like "c :=
> magic.GetCurrentContext(); c = c.WithValue(...); magic.SetContext(c);".
>
> This would affect only the current goroutine going forward, but not its
> children.
>

What happens if you want to invoke an operation by passing its arguments to
an existing goroutine that does work on the current goroutine's behalf (aka
a worker pool)?

I don't think this pattern is that uncommon, and it would break the
inheritable-variables model.

>
>
>> > On Wednesday, September 23, 2020 at 5:55:50 PM UTC-7 Ian Lance Taylor
>> wrote:
>> >>
>> >> On Wed, Sep 23, 2020 at 5:46 PM Alex Mills 
>> wrote:
>> >> >
>> >> > There appears to be a way to get a reference on the goroutine id:
>> >> >
>> >> > http://blog.sgmansfield.com/2015/12/goroutine-ids/
>> >>
>> >> But as you can see by reading that blog article, that is almost a
>> joke.
>> >>
>> >> Go considers these things to be better handled explicitly, which is
>> >> why people are telling you to use a context.Context value. And, yes,
>> >> you'll want to use a Context aware logging package.
>> >>
>> >> In Go it's trivial to create new goroutines, and as soon as you do
>> >> that any goroutine-local-variable scheme falls apart. So Go has
>> >> consistently chosen to not provide that capability, and similarly to
>> >> not provide goroutine IDs. It's an intentional choice by the
>> >> language. There have been a number of discussions about this in the
>> >> past on this mailing list.
>> >>
>> >> 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...@googlegroups.com.
>> > To view this discussion on the web visit
>> https://groups.google.com/d/msgid/golang-nuts/f78f2d12-89d2-494d-983a-a462f0124d82n%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/7bc62278-5cbc-47fe-abd2-36172e4e8520n%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/CAJhgacifKxQVzq%3Dak%2BCzR_5GX-1C5_%3DdV6awwkbaDNrn40MVYA%40mail.gmail.com.


Re: [go-nuts] Find n-th root of a big number

2020-09-22 Thread roger peppe
Relevant issue: https://golang.org/issue/14102


On Tue, 22 Sep 2020 at 08:54, Nasir Hussain 
wrote:

> The Amazing Rob Pike :D
>
> On Tue, Sep 22, 2020 at 12:13 PM Rob Pike  wrote:
>
>> I'm not going to debug you program for you - you'll learn more doing it
>> yourself, but I glanced at it and saw immediately that you're missing an
>> easy optimization. Raising a number to an integer power can be done much
>> faster by repeated squaring according to the bit pattern of the exponent.
>> I'll leave that cryptic comment alone to let you puzzle it out yourself.
>> (Don't look it up; it's much more fun to figure out.)
>>
>> -rob
>>
>>
>> On Tue, Sep 22, 2020 at 3:11 AM Hau Phan  wrote:
>>
>>> i can't find get n-th root in document of go big package so i decided to
>>> do it myself using newton's method. i found a solution at
>>> https://www.geeksforgeeks.org/n-th-root-number/ and start to implement
>>> in go. but my code only work fine for base 2. other base result gone too
>>> far from correct.
>>>
>>> Anyone could show me where am i wrong.
>>>
>>> Here's my code
>>>
>>> ```go
>>> package main
>>>
>>> import (
>>> "fmt"
>>> "math/big"
>>> "math/rand"
>>> )
>>>
>>> // PowFloat return x^n
>>> func PowFloat(x *big.Float, n int64) *big.Float {
>>> result := new(big.Float).SetInt64(1)
>>> for i := 0; i < int(n); i++ {
>>> result.Mul(result, x)
>>> }
>>> return result
>>> }
>>>
>>> // GetNthRoothFloat get nth root of a using newton's method
>>> func GetNthRoothFloat(a *big.Float, n int64) *big.Float {
>>> N := new(big.Float).SetInt64(n)
>>> xPre := new(big.Float).SetInt64(int64(rand.Intn(10) + 1))
>>> eps := new(big.Float).SetFloat64(0.001)
>>> delX := new(big.Float).SetInt64(2147483647)
>>> xK := new(big.Float).SetInt64(0)
>>>
>>> for delX.Cmp(eps) > 0 {
>>> t1 := new(big.Float).Sub(N, new(big.Float).SetFloat64(1.0)) // t1 = n-1
>>> t1 = t1.Mul(t1, xPre)   // t1 =
>>> (N-1) * xPre
>>> t2 := new(big.Float).Quo(a, PowFloat(xPre, n-1))// t2 = a/(
>>> xPre^(n-1) )
>>> t3 := new(big.Float).Add(t1, t2)// t3 = t1 +
>>> t2
>>> xK.Quo(t3, N)
>>> delX = new(big.Float).Sub(xK, xPre)
>>> delX.Abs(delX)
>>> xPre = xK.Copy(xK)
>>> }
>>> return xK
>>> }
>>>
>>> func main() {
>>> t := new(big.Float).SetInt64(64)
>>> fmt.Println(GetNthRoothFloat(t, 3))
>>> }
>>> ```
>>>
>>> --
>>> You received this message because you are subscribed to the Google
>>> Groups "golang-nuts" group.
>>> To unsubscribe from this group and stop receiving emails from it, send
>>> an email to golang-nuts+unsubscr...@googlegroups.com.
>>> To view this discussion on the web visit
>>> https://groups.google.com/d/msgid/golang-nuts/5a38a7fe-426b-4f94-905e-79b42dcaa611n%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/CAOXNBZQrjBjT-dDEK1Atu7R32aT1mgTsSAYhXAF7hXmj35BjuQ%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/CAG9C_MeG0P%3DSy5732WvW-EfsreSObQve%3DLsEUms%3DdWdRenvZ4Q%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/CAJhgachbaTaxkWv66ktuPz1RPSnAm7zgc1r0kqEb2T4hUWEt3A%40mail.gmail.com.


Re: [go-nuts] unit test for function which has goroutine

2020-09-11 Thread roger peppe
On Thu, 10 Sep 2020 at 08:15, Yvonne Zhang  wrote:

> Hi,
> I have a function streaming a zipreader to browser. It is like this.
> func functionA()(body io.ReadCloser, err error){
>
>// some logic to get a zipreader
>
>body, pipeWriter := io.Pipe()
>zipWriter := zip.NewWriter(pipeWriter)
>
>go func(){
>   // err := functionB(zipReader, zipWriter)call another function to
> prepare files and write to zipwriter
>If err != nil{
>zipWriter.Close()
> _ = pipeWriter.CloseWithError(err)
> return
>}
>   zipWriter.Close()
>pipeWriter.Close()
>}()
>return
> }
>
> My question is about unit test about this functionA. I have mock for
> functionB. How do I write unit test for functionA with the mock functionB.
> It seems my unit test does not work well when it goes into the goroutine.
> Many thanks!
>

For the record, my usual response to this, assuming that function A and
function B are not exported functions, is that you'd be better off not
writing unit tests for the individual functions, but testing (as far as
possible) against the publicly exported interface. I tend to think about
what the overall contract is (the contract that really matters from the
external consumer's point of view) and test that.

If you do that, then your tests will remain useful even if you decide to
refactor the code. That is a significant part of the value of automated
tests in my view.

In this particular case ISTM that the goroutine is just an implementation
detail. If you set up the stream source somehow, you could use the net/http
package to hit the endpoint that does the streaming and check that you're
seeing the correct result. Depending on what the source is, you *might* need
to fake it up somehow, but I'd always be inclined to use the lowest
available level to do that, so you're testing as much of the stack as you
can (and thus giving yourself most confidence in the code and most freedom
to refactor later).

I'm aware that in saying this, I'm going directly against unit-testing
advice available elsewhere. :) YMMV. And it's worth noting: when testing,
there are no absolutes and context is crucial for making a decision as to
what and how to test.

  hope this helps,
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/4ca0817a-f1f7-44a9-be3d-3584bcb61b8an%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/CAJhgachcE4wpSos7rt8tELi0P3xwKyL-SKrbo6R%2BQSFbwDF2rw%40mail.gmail.com.


Re: [go-nuts] [generics] Allowing interfaces with type constraints

2020-09-10 Thread roger peppe
You can definitely use parametric interfaces in type assertion expressions,
but you can't use interfaces with type lists.
I'm not sure exactly what you're trying to do in your example, but ISTM
that it could be somewhat simpler. You
only need one type parameter: https://go2goplay.golang.org/p/4E0ZnVxJwL9


On Thu, 10 Sep 2020 at 15:54, Viktor Kojouharov 
wrote:

>
> Would using parametric interfaces be allowed in type assertion expressions
> / type switches?
>
> The current behavior in the go2go playground is for the compiler to return
> the error: "interface contains type constraints (T)" (
> https://go2goplay.golang.org/p/O1Un2Vm9Dh0)
> I was under the impression that since the outer function is already
> parametrised with the same type, this should work without a problem.
>
> Perhaps I'm missing something, but I currently don't see how one can check
> for optional interface implementations of generic types, since this error
> will pretty much stop them.
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/fbe50aaf-1794-4a17-9321-2b923f546d13n%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/CAJhgach9vJ_6Tcu8vceMBGyE9L26e20skKQykybuawY7az5Prg%40mail.gmail.com.


Re: [go-nuts] Dynamic composition of interfaces at runtime?

2020-09-02 Thread roger peppe
On Wed, 2 Sep 2020 at 10:56, Jesper Louis Andersen <
jesper.louis.ander...@gmail.com> wrote:

> Usually, my experience is that these highly dynamic interfaces is an
> indication you want to approach the problem from a different angle. You
> will converge on something that gets closer and closer to having an
> interface{}, and this means you are converging toward a world of dynamic
> typing. It often happens because you spot an initial pattern and try to
> hoist out common code. But there are situations where taking a completely
> different route yields far simpler code which is easier to handle.
>
> Code will have to branch based on the data you have available. This is the
> primary reason why languages add sum-types. Go doesn't have sum-types, so
> you'll have to build your own variant, usually by having an indicator in a
> struct what you are looking at. However, this means you have no
> exhaustiveness checks, and no automatic optimization, which is the price
> you pay for this simplification.
>

An alternative approach is to use a struct containing function fields
rather than an interface, which allows easy inspection of capabilities too.
That's the approach that Nick Craig-Wood ended up using for rclone; see
this type for an example:
https://pkg.go.dev/github.com/rclone/rclone/fs?tab=doc#Features


> On Wed, Aug 26, 2020 at 7:10 PM cpu...@gmail.com 
> wrote:
>
>> Great post, thank you! Found you Wrap method looks exactly like my
>> decorate :).
>>
>> While not entirely satisfying it does solve the problem and the set of
>> optional methods in my case is always below 5 so the effort is manageable.
>> Since the optional interfaces are really narrow (always 1 method) I guess I
>> can proceed with this approach...
>>
>> Kind regards,
>> Andi
>>
>> On Wednesday, August 26, 2020 at 5:59:13 PM UTC+2
>> axel.wa...@googlemail.com wrote:
>>
>>> Hi,
>>>
>>> no, there isn't really a solution to this. I've blogged about this:
>>>
>>> https://blog.merovius.de/2017/07/30/the-trouble-with-optional-interfaces.html
>>> A combination of generics and embedding can help. So, you can do
>>>
>>> type Wrapper[T] struct {
>>> T
>>> otherFields
>>> }
>>>
>>> func (w *Wrapper) SomeNewMethod() {
>>> }
>>>
>>> But even then, you need to know the static type of what you're wrapping
>>> (so http Middleware, for example, couldn't use this).
>>>
>>> I'm also not super sure if it's a good idea to do this even if you
>>> could. An interface might contain multiple, interdependent methods. As an
>>> example, `http.ResponseWriter` implicitly calls `WriteHeader` the first
>>> time you call `Write`. So, if you wrap a `ResponseWriter` and overwrite
>>> `WriteHeader`, that overwritten method has to be called explicitly (the
>>> underlying `ResponseWriter` will call its own `WriteHeader`). So if you
>>> don't know what the methods of the wrapped type are and do, you might
>>> introduce very hard to find bugs.
>>>
>>> On Wed, Aug 26, 2020 at 5:49 PM cpu...@gmail.com 
>>> wrote:
>>>
 Hi All,

 using interfaces for behavioural testing seems a common pattern in go:

 if typed, hasCapability := d.(Capability); hasCapability...

 I have the requirement to dynamically compose interfaces at runtime,
 i.e. I cannot know upfront which set of interfaces a resulting type will
 support:

 type resultingType interface {
 basicCapability
 ...any combination of additional capabilities
 }

 If there is only a single additional/optional capability to implement
 that is simple to solve, e.g. by implementing a wrapping struct that embeds
 the basic capability and adds an additional capability. Applying this
 pattern across multiple layers (stack of wrapping structs does not work as
 the embedded interfaces don't bubble up).

 However, the number of additional capabilities that a type might have
 to support could be bigger (think of physical meters which could supply
 power, energy, currents, frequency etc).

 I'm solved this by using go:generate which is fed the basic and set of
 optional types and generates additional types for any _combination_ of
 additional types, an example is attached (and source at
 https://github.com/andig/evcc/pull/310/files#diff-fa40c05651b4682eb25a198f8a4a98f0).
 This is similar to the "old" pattern of simulation generics via generated
 code.

 I'm wondering if using a pattern of dynamic composition is sound, if
 the the go:generate approach is a good one or if there are better ways?

 Kind regards,
 Andi

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

Re: [go-nuts] Re: [ generics] Moving forward with the generics design draft

2020-08-24 Thread roger peppe
On Mon, 24 Aug 2020 at 12:57, 'Richard Oudkerk' via golang-nuts <
golang-nuts@googlegroups.com> wrote:

>
> Applying the same rule to type lists and type switches you should be able
> to write
>
> type Comparer[T any] interface {
> Compare(T) int
> }
>
> type CompareConstraints interface {
> type int, int8, …, float64, string, Comparer
> }
>
> func Min[T CompareConstraints](x, y T) bool {
> switch T {
> case int:
> …
> …
> case Comparer:
> if x.Compare(y) < 0 {
> return x
> }
> return y
> }
> }
>
> But the current proposal does not allow interfaces in type lists.
>

FWIW, even if the proposal did allow interfaces in type lists, you wouldn't
be able to invoke the Compare method on x, because both:
a) the allowed operations on T are the intersection of all the operations
in the type list, and only one of those types has a Compare method
and
b) according to the first post in this thread, methods are specifically
excluded from the operations allowed by a type list.


> On Monday, 24 August 2020 at 07:09:15 UTC+1 rog wrote:
>
>> On Mon, 24 Aug 2020 at 06:35, Denis Cheremisov 
>> wrote:
>>
>>> I probably didn't read what you have wrote in the first message carefuly
>>> enough. Does it mean something like that will work
>>>
>>> type SomeTypes interface {
>>> type int, float32, float64
>>> }
>>>
>>> func Min[T SomeTypes](x, y T) T {
>>> switch T {
>>> case int:
>>> if x < y {
>>> return x
>>> }
>>> return y
>>> case float32:
>>> return math.Min(float64(x), float64(y))
>>> case float64:
>>> return math.Min(x, y)
>>> }
>>> }
>>>
>>
>> This was discussed above.
>>
>> I don't believe you can do that. I didn't see any suggestion that knowing
>> the type implies the ability
>> to convert from the generic type to the known underlying type.
>>
>>>
>>> Would something like below work as well?
>>>
>>> type Compare[T any] interface {
>>> Compare(x, y T) int
>>> }
>>>
>>> type CompareConstraints[T any] {
>>> type int, int8, …, float64, string, Compare[T]
>>> }
>>>
>>> func Min[T CompareConstraints]Min(x, y T) bool {
>>> switch T {
>>> case int:
>>> …
>>> …
>>> case Compare[T]:
>>> return x.Compare(y) < 0
>>> }
>>> }
>>>
>>
>> No. As proposed, the type switch doesn't change anything about the type T.
>>
>> Also, AIUI that type list wouldn't be very useful in practice, because
>> using that interface type in the type list would only allow types whose
>> underlying type is exactly Compare[T], which doesn't include any
>> non-interface types or interface types that have more methods than just
>> Compare.
>>
>>   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/03342d1f-5c82-40e6-98fc-18e95bfd183cn%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/CAJhgacgSS%2B1p9Z3r7iCm8jDGgVyEW0zA2La%3DwBJkZaGz%2BsuWew%40mail.gmail.com.


Re: [go-nuts] Re: [ generics] Moving forward with the generics design draft

2020-08-24 Thread roger peppe
On Mon, 24 Aug 2020 at 06:35, Denis Cheremisov 
wrote:

> I probably didn't read what you have wrote in the first message carefuly
> enough. Does it mean something like that will work
>
> type SomeTypes interface {
> type int, float32, float64
> }
>
> func Min[T SomeTypes](x, y T) T {
> switch T {
> case int:
> if x < y {
> return x
> }
> return y
> case float32:
> return math.Min(float64(x), float64(y))
> case float64:
> return math.Min(x, y)
> }
> }
>

This was discussed above.

I don't believe you can do that. I didn't see any suggestion that knowing
the type implies the ability
to convert from the generic type to the known underlying type.

>
> Would something like below work as well?
>
> type Compare[T any] interface {
> Compare(x, y T) int
> }
>
> type CompareConstraints[T any] {
> type int, int8, …, float64, string, Compare[T]
> }
>
> func Min[T CompareConstraints]Min(x, y T) bool {
> switch T {
> case int:
> …
> …
> case Compare[T]:
> return x.Compare(y) < 0
> }
> }
>

No. As proposed, the type switch doesn't change anything about the type T.

Also, AIUI that type list wouldn't be very useful in practice, because
using that interface type in the type list would only allow types whose
underlying type is exactly Compare[T], which doesn't include any
non-interface types or interface types that have more methods than just
Compare.

  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/CAJhgachjLex%3DUNP_trPy55mNcn3iXNePYE8pFOuA1oLa2GJ9Xw%40mail.gmail.com.


Re: [go-nuts] [ generics] Moving forward with the generics design draft

2020-08-21 Thread roger peppe
On Fri, 21 Aug 2020 at 23:12, jimmy frasche  wrote:

> I don't want a generic min unless it looks like this:
>
> func Min[T constraints.Ordered](a, b T) T {
>   switch T {
>   case float32:
> return T(math.Min(float32(a), float32(b)))
>   case float64:
> return T(math.Min(float64(a), float64(b)))
>   }
>   if a < b {
> return a
>   }
>   return b
> }
>

I'd really like to be able to write that as:

func Min[T constraints.Ordered](a, b T) T {
  switch T {
  case float32:
return math.Min(float64(a), float64(b))
  case float64:
return math.Min(a, b)
  }
  if a < b {
return a
  }
  return b
}

But then there is the difficulty that the original T is no longer the same
as the T inside the type switch.
So this code would print false not true, which would be... somewhat
unexpected: https://go2goplay.golang.org/p/d0cJBfYObAY

Perhaps the type switch* should *allow declaring a new name for the
switched type, making it clear that a new type was being declared inside
the switch.

Something like:

switch T1 := T {
}

but the ":=" operator doesn't seem quite right there, and that still
doesn't solve the original problem, because T1 is still incompatible with
all the argument values. I guess that one could allow conversion or
assignment compatibility between types involving T and T1, but that might
complicate the spec too much.


On Fri, 21 Aug 2020 at 23:12, jimmy frasche  wrote:

> I don't want a generic min unless it looks like this:
>
> func Min[T constraints.Ordered](a, b T) T {
>   switch T {
>   case float32:
> return T(math.Min(float32(a), float32(b)))
>   case float64:
> return T(math.Min(float64(a), float64(b)))
>   }
>   if a < b {
> return a
>   }
>   return b
> }
>
> On Fri, Aug 21, 2020 at 3:03 PM Axel Wagner
>  wrote:
> >
> > On Fri, Aug 21, 2020 at 11:46 PM Ian Lance Taylor 
> wrote:
> >>
> >> Yes, there are various such possibilities.
> >>
> >> What jimmy frasche said above is correct: nothing changes in the case
> >> of a type switch of a type parameter.  The code now knows the type
> >> list element that the type argument matched, but it can't do anything
> >> that it couldn't do anyhow.
> >
> >
> > I think there are two reasonable things that it could be allowed to do
> in the case, that aren't allowed outside:
> > 1. Convert to the matched type. We have a guarantee that the matched
> type is either identical or has the same underlying type, both of which
> would allow a conversion in the language as-is. I feel allowing this
> conversion would be sufficiently useful (e.g. passing things to
> `strconv.Itoa` or functions from `math` can be very useful).
> > 2. If the type is not a predeclared type, we could even take this a step
> further, as the types must be identical - so we might allow treating them
> as such. This feels natural when viewed from the "type lists are
> essentially sum types" POV. However, it would treat predeclared types more
> special than other declared types and so it may be too elaborate to put
> into the spec. It would also allow what rog suggest - but only in certain
> corner cases, which feels weird.
> >
> > The more I think about it, the less I understand the intention behind
> the type-switch construct introduced. I tend to agree that 1. at least
> should be possible to make it useful. But even then, it seems like kind of
> a big change for relatively limited use. What was the motivation behind
> that change? Is there discussion somewhere, of interesting use-cases this
> enables?
> >
> >
> >>
> >>
> >> Ian
> >>
> >> On Fri, Aug 21, 2020 at 2:43 PM Axel Wagner
> >>  wrote:
> >> >
> >> > also, of course, you could still use operators with them, while now
> also knowing the exact semantics of those operators (e.g. in regards to
> overflow), which might also be useful.
> >> >
> >> > On Fri, Aug 21, 2020 at 11:42 PM Axel Wagner <
> axel.wagner...@googlemail.com> wrote:
> >> >>
> >> >>
> >> >>
> >> >> On Fri, Aug 21, 2020 at 11:30 PM roger peppe 
> wrote:
> >> >>>
> >> >>> On Fri, 21 Aug 2020 at 22:10, jimmy frasche <
> soapboxcic...@gmail.com> wrote:
> >> >>>>
> >> >>>> I'd assume that would fail to compile as you're returning a []T
> not a []int
> >> >>>
> >> >>>
> >> >>> If that's the case, then I'm not sure that such a type switch would
> be very useful. It would tell you what type the values are, but you 

Re: [go-nuts] [ generics] Moving forward with the generics design draft

2020-08-21 Thread roger peppe
On Fri, 21 Aug 2020 at 23:03, Axel Wagner 
wrote:

> On Fri, Aug 21, 2020 at 11:46 PM Ian Lance Taylor  wrote:
>
>> Yes, there are various such possibilities.
>>
>> What jimmy frasche said above is correct: nothing changes in the case
>> of a type switch of a type parameter.  The code now knows the type
>> list element that the type argument matched, but it can't do anything
>> that it couldn't do anyhow.
>>
>
> I think there are two reasonable things that it could be allowed to do in
> the case, that aren't allowed outside:
> 1. Convert to the matched type. We have a guarantee that the matched type
> is either identical or has the same underlying type, both of which would
> allow a conversion in the language as-is. I feel allowing this conversion
> would be sufficiently useful (e.g. passing things to `strconv.Itoa` or
> functions from `math` can be very useful).
>

Yes. Without this, I can't see that the type switch is useful for anything
at all other than unsafe operations.

2. If the type is not a predeclared type, we could even take this a step
> further, as the types must be identical - so we might allow treating them
> as such.
>
This feels natural when viewed from the "type lists are essentially sum
> types" POV. However, it would treat predeclared types more special than
> other declared types and so it may be too elaborate to put into the spec.
> It would also allow what rog suggest - but only in certain corner cases,
> which feels weird.
>
> The more I think about it, the less I understand the intention behind the
> type-switch construct introduced. I tend to agree that 1. at least should
> be possible to make it useful. But even then, it seems like kind of a big
> change for relatively limited use. What was the motivation behind that
> change? Is there discussion somewhere, of interesting use-cases this
> enables?
>

As one motivating example, imagine that we had some highly optimized
machine code that sums a slice of 32 bit numbers, but we want to provide a
generic version: https://go2goplay.golang.org/p/0YvkOcc-eBs

I suspect that kind of scenario is one significant use case for using a
type switch in a generic function, and I don't think that the type switch
proposed is sufficient for 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/CAJhgacjn8dOOXU1%2BYZSM7nLDR4fqoCRHTJx3JRy20nN7fb44UA%40mail.gmail.com.


Re: [go-nuts] [ generics] Moving forward with the generics design draft

2020-08-21 Thread roger peppe
On Fri, 21 Aug 2020 at 22:46, Ian Lance Taylor  wrote:

> Yes, there are various such possibilities.
>
> What jimmy frasche said above is correct: nothing changes in the case
> of a type switch of a type parameter.  The code now knows the type
> list element that the type argument matched, but it can't do anything
> that it couldn't do anyhow.
>

I suspect that this would make the new type switch construct very much less
useful.
For example, it wouldn't be possible to specialize a vector operation to
use machine-specific operations on a vector without using unsafe.

It might be interesting to do a survey of some of the reasons that people
would wish to use a type switch on a type parameter and see if the proposed
construct would be sufficient.

Have you got an example of how it might be used?

  cheers,
rog.



>
> Ian
>
> On Fri, Aug 21, 2020 at 2:43 PM Axel Wagner
>  wrote:
> >
> > also, of course, you could still use operators with them, while now also
> knowing the exact semantics of those operators (e.g. in regards to
> overflow), which might also be useful.
> >
> > On Fri, Aug 21, 2020 at 11:42 PM Axel Wagner <
> axel.wagner...@googlemail.com> wrote:
> >>
> >>
> >>
> >> On Fri, Aug 21, 2020 at 11:30 PM roger peppe 
> wrote:
> >>>
> >>> On Fri, 21 Aug 2020 at 22:10, jimmy frasche 
> wrote:
> >>>>
> >>>> I'd assume that would fail to compile as you're returning a []T not a
> []int
> >>>
> >>>
> >>> If that's the case, then I'm not sure that such a type switch would be
> very useful. It would tell you what type the values are, but you can't do
> anything with them because all the values would still be of the original
> type.
> >>
> >>
> >> You can reasonably convert them to their underlying type and *then* use
> them as such.
> >> That would make it useful while not allowing what you posit.
> >>
> >>> I had assumed that the intention was that within the arm of the type
> switch, the switched type would take on the specified type.
> >>> That would allow (for example) specialising to use underlying machine
> operations on []T when T is a known type such as byte.
> >>
> >>
> >> It would, however, prevent you from calling methods on the type or pass
> it to a function taking an interface compatible with the constraint.
> >> Also, I shudder to even imagine how this could be put into a spec.
> >>
> >>>
> >>>
> >>>
> >>>> On Fri, Aug 21, 2020 at 2:07 PM roger peppe 
> wrote:
> >>>> >
> >>>> >
> >>>> > On Fri, 21 Aug 2020 at 01:28, Ian Lance Taylor 
> wrote:
> >>>> >>
> >>>> >> After many discussions and reading many comments, we plan to move
> >>>> >> forward with some changes and clarifications to the generics design
> >>>> >> draft.
> >>>> >>
> >>>> >> 1.
> >>>> >>
> >>>> >> We’re going to settle on square brackets for the generics syntax.
> >>>> >> We’re going to drop the “type” keyword before type parameters, as
> >>>> >> using square brackets is sufficient to distinguish the type
> parameter
> >>>> >> list from the ordinary parameter list.  To avoid the ambiguity with
> >>>> >> array declarations, we will require that all type parameters
> provide a
> >>>> >> constraint.  This has the advantage of giving type parameter lists
> the
> >>>> >> exact same syntax as ordinary parameter lists (other than using
> square
> >>>> >> brackets).  To simplify the common case of a type parameter that
> has
> >>>> >> no constraints, we will introduce a new predeclared identifier
> “any”
> >>>> >> as an alias for “interface{}”.
> >>>> >>
> >>>> >> The result is declarations that look like this:
> >>>> >>
> >>>> >> type Vector[T any] []T
> >>>> >> func Print[T any](s []T) { … }
> >>>> >> func Index[T comparable](s []T, e T) { … }
> >>>> >>
> >>>> >> We feel that the cost of the new predeclared identifier “any” is
> >>>> >> outweighed by the simplification achieved by making all parameter
> >>>> >> lists syntactically the same: as each regular parameter always has
> a
> >>>> &g

Re: [go-nuts] [ generics] Moving forward with the generics design draft

2020-08-21 Thread roger peppe
On Fri, 21 Aug 2020 at 22:10, jimmy frasche  wrote:

> I'd assume that would fail to compile as you're returning a []T not a []int
>

If that's the case, then I'm not sure that such a type switch would be very
useful. It would tell you what type the values are, but you can't do
anything with them because all the values would still be of the original
type.

I had assumed that the intention was that within the arm of the type
switch, the switched type would take on the specified type.
That would allow (for example) specialising to use underlying machine
operations on []T when T is a known type such as byte.


On Fri, Aug 21, 2020 at 2:07 PM roger peppe  wrote:
> >
> >
> > On Fri, 21 Aug 2020 at 01:28, Ian Lance Taylor  wrote:
> >>
> >> After many discussions and reading many comments, we plan to move
> >> forward with some changes and clarifications to the generics design
> >> draft.
> >>
> >> 1.
> >>
> >> We’re going to settle on square brackets for the generics syntax.
> >> We’re going to drop the “type” keyword before type parameters, as
> >> using square brackets is sufficient to distinguish the type parameter
> >> list from the ordinary parameter list.  To avoid the ambiguity with
> >> array declarations, we will require that all type parameters provide a
> >> constraint.  This has the advantage of giving type parameter lists the
> >> exact same syntax as ordinary parameter lists (other than using square
> >> brackets).  To simplify the common case of a type parameter that has
> >> no constraints, we will introduce a new predeclared identifier “any”
> >> as an alias for “interface{}”.
> >>
> >> The result is declarations that look like this:
> >>
> >> type Vector[T any] []T
> >> func Print[T any](s []T) { … }
> >> func Index[T comparable](s []T, e T) { … }
> >>
> >> We feel that the cost of the new predeclared identifier “any” is
> >> outweighed by the simplification achieved by making all parameter
> >> lists syntactically the same: as each regular parameter always has a
> >> type, each type parameter always has a constraint (its meta-type).
> >>
> >> Changing “[type T]” to “[T any]” seems about equally readable and
> >> saves one character.  We’ll be able to streamline a lot of existing
> >> code in the standard library and elsewhere by replacing “interface{}”
> >> with “any”.
> >>
> >> 2.
> >>
> >> We’re going to simplify the rule for type list satisfaction.  The type
> >> argument will satisfy the constraint if the type argument is identical
> >> to any type in the type list, or if the underlying type of the type
> >> argument is identical to any type in the type list.  What we are
> >> removing here is any use of the underlying types of the types in the
> >> type list.  This tweaked rule means that the type list can decide
> >> whether to accept an exact defined type, other than a predeclared
> >> type, or whether to accept any type with a matching underlying type.
> >>
> >> This is a subtle change that we don’t expect to affect any existing
> >> experimental code.
> >>
> >> We think that this definition might work if we permit interface types
> >> with type lists to be used outside of type constraints.  Such
> >> interfaces would effectively act like sum types. That is not part of
> >> this design draft, but it’s an obvious thing to consider for the
> >> future.
> >>
> >> Note that a type list can mention type parameters (that is, other type
> >> parameters in the same type parameter list).  These will be checked by
> >> first replacing the type parameter(s) with the corresponding type
> >> argument(s), and then using the rule described above.
> >>
> >> 3.
> >>
> >> We’re going to clarify that when considering the operations permitted
> >> for a value whose type is a type parameter, we will ignore the methods
> >> of any types in the type list.  The general rule is that the generic
> >> function can use any operation permitted by every type in the type
> >> list.  However, this will only apply to operators and predeclared
> >> functions (such as "len" and "cap").  It won’t apply to methods, for
> >> the case where the type list includes a list of types that all define
> >> some method.  Any methods must be listed separately in the interface
> >> type, not inherited from the type list.
> >>
> >> This rule seems genera

Re: [go-nuts] [ generics] Moving forward with the generics design draft

2020-08-21 Thread roger peppe
On Fri, 21 Aug 2020 at 01:28, Ian Lance Taylor  wrote:

> After many discussions and reading many comments, we plan to move
> forward with some changes and clarifications to the generics design
> draft.
>
> 1.
>
> We’re going to settle on square brackets for the generics syntax.
> We’re going to drop the “type” keyword before type parameters, as
> using square brackets is sufficient to distinguish the type parameter
> list from the ordinary parameter list.  To avoid the ambiguity with
> array declarations, we will require that all type parameters provide a
> constraint.  This has the advantage of giving type parameter lists the
> exact same syntax as ordinary parameter lists (other than using square
> brackets).  To simplify the common case of a type parameter that has
> no constraints, we will introduce a new predeclared identifier “any”
> as an alias for “interface{}”.
>
> The result is declarations that look like this:
>
> type Vector[T any] []T
> func Print[T any](s []T) { … }
> func Index[T comparable](s []T, e T) { … }
>
> We feel that the cost of the new predeclared identifier “any” is
> outweighed by the simplification achieved by making all parameter
> lists syntactically the same: as each regular parameter always has a
> type, each type parameter always has a constraint (its meta-type).
>
> Changing “[type T]” to “[T any]” seems about equally readable and
> saves one character.  We’ll be able to streamline a lot of existing
> code in the standard library and elsewhere by replacing “interface{}”
> with “any”.
>
> 2.
>
> We’re going to simplify the rule for type list satisfaction.  The type
> argument will satisfy the constraint if the type argument is identical
> to any type in the type list, or if the underlying type of the type
> argument is identical to any type in the type list.  What we are
> removing here is any use of the underlying types of the types in the
> type list.  This tweaked rule means that the type list can decide
> whether to accept an exact defined type, other than a predeclared
> type, or whether to accept any type with a matching underlying type.
>
> This is a subtle change that we don’t expect to affect any existing
> experimental code.
>
> We think that this definition might work if we permit interface types
> with type lists to be used outside of type constraints.  Such
> interfaces would effectively act like sum types. That is not part of
> this design draft, but it’s an obvious thing to consider for the
> future.
>
> Note that a type list can mention type parameters (that is, other type
> parameters in the same type parameter list).  These will be checked by
> first replacing the type parameter(s) with the corresponding type
> argument(s), and then using the rule described above.
>
> 3.
>
> We’re going to clarify that when considering the operations permitted
> for a value whose type is a type parameter, we will ignore the methods
> of any types in the type list.  The general rule is that the generic
> function can use any operation permitted by every type in the type
> list.  However, this will only apply to operators and predeclared
> functions (such as "len" and "cap").  It won’t apply to methods, for
> the case where the type list includes a list of types that all define
> some method.  Any methods must be listed separately in the interface
> type, not inherited from the type list.
>
> This rule seems generally clear, and avoids some complex reasoning
> involving type lists that include structs with embedded type
> parameters.
>
> 4.
>
> We’re going to permit type switches on type parameters that have type
> lists, without the “.(type)” syntax.  The “(.type)” syntax exists to
> clarify code like “switch v := x.(type)”.  A type switch on a type
> parameter won’t be able to use the “:=” syntax anyhow, so there is no
> reason to require “.(type)”.  In a type switch on a type parameter
> with a type list, every case listed must be a type that appears in the
> type list (“default” is also permitted, of course).  A case will be
> chosen if it is the type matched by the type argument, although as
> discussed above it may not be the exact type argument: it may be the
> underlying type of the type argument.


Here's one interesting implication of this: it allows us to do type
conversions that were not previously possible.

For example, if we have "type I int", we can use a type switch to convert
some type []I to type []int:
https://go2goplay.golang.org/p/-860Zlz7-cn

func F[type T intlike](ts []T) []int {
switch T {
case int:
return ts
}
return nil
}

It seems to me that this kind of thing will allow us to perform a similar
conversion (convert some part of the type to its underlying type) on any
type.

In the early days of Go, the spec allowed this kind of conversion
 as a normal type conversion. I
wonder if it might be reasonable to revert to those more relaxed semantics.
I think they're potentially useful, 

Re: [go-nuts] [ generics] Moving forward with the generics design draft

2020-08-21 Thread roger peppe
On Fri, 21 Aug 2020 at 18:30, Axel Wagner 
wrote:

> My one concern with making it an alias is error messages.
> If the source code says "any", I think so should the error messages.
> Currently, the compiler forgets aliases too early
> <https://play.golang.org/p/m8o9JiOyy9z>.
>

I agree that's a concern, but I think that should be a reason to fix error
messages when aliases are used, not to use a named type.


> On Fri, Aug 21, 2020 at 7:08 PM roger peppe  wrote:
>
>>
>>
>> On Fri, 21 Aug 2020 at 15:24, Ian Lance Taylor  wrote:
>>
>>> On Fri, Aug 21, 2020, 12:37 AM 'Axel Wagner' via golang-nuts <
>>> golang-nuts@googlegroups.com> wrote:
>>>
>>>> Just to clarify, the intent is to make the declaration in the spec
>>>> `type any = interface{}`, not `type any interface{}`, correct? The latter
>>>> would be more analogous to `error`. Either has certain advantages and
>>>> disadvantages, I'm not sure which I prefer, but I just want to make sure I
>>>> understand the plan :)
>>>>
>>>
>>> I've been thinking of a type alias rather than a defined type, but I'm
>>> not sure which is best.  It would be interesting to hear whether anybody
>>> has a clear preference, and why.
>>>
>>
>> My vote is for a type alias. Using a named type doesn't make any
>> difference for type parameter constraints, and I'd prefer it if
>> "[]interface{}" and "[]any" (or other types involving interface{}) weren't
>> incompatible types. "interface{}" is currently a nice universally
>> understood type - I don't think it's worth splitting it into two distinct
>> types.
>>
>>   cheers,
>> rog.
>>
>>
>>
>>
>>> 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/CAOyqgcUFU_Lz0c%3D-6V6N9X2Ku2Hx-9%2BDeHequ0oLX9Soyo_3GQ%40mail.gmail.com
>>> <https://groups.google.com/d/msgid/golang-nuts/CAOyqgcUFU_Lz0c%3D-6V6N9X2Ku2Hx-9%2BDeHequ0oLX9Soyo_3GQ%40mail.gmail.com?utm_medium=email_source=footer>
>>> .
>>>
>>

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


Re: [go-nuts] [ generics] Moving forward with the generics design draft

2020-08-21 Thread roger peppe
On Fri, 21 Aug 2020 at 15:24, Ian Lance Taylor  wrote:

> On Fri, Aug 21, 2020, 12:37 AM 'Axel Wagner' via golang-nuts <
> golang-nuts@googlegroups.com> wrote:
>
>> Just to clarify, the intent is to make the declaration in the spec `type
>> any = interface{}`, not `type any interface{}`, correct? The latter would
>> be more analogous to `error`. Either has certain advantages and
>> disadvantages, I'm not sure which I prefer, but I just want to make sure I
>> understand the plan :)
>>
>
> I've been thinking of a type alias rather than a defined type, but I'm not
> sure which is best.  It would be interesting to hear whether anybody has a
> clear preference, and why.
>

My vote is for a type alias. Using a named type doesn't make any difference
for type parameter constraints, and I'd prefer it if "[]interface{}" and
"[]any" (or other types involving interface{}) weren't incompatible types.
"interface{}" is currently a nice universally understood type - I don't
think it's worth splitting it into two distinct types.

  cheers,
rog.




> 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/CAOyqgcUFU_Lz0c%3D-6V6N9X2Ku2Hx-9%2BDeHequ0oLX9Soyo_3GQ%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/CAJhgacgfGtxA4u3qrB3qpGowFqMBBHCOS%3DcN1NdUmgaiZpZrYw%40mail.gmail.com.


Re: [go-nuts] [ generics] Moving forward with the generics design draft

2020-08-21 Thread roger peppe
On Fri, 21 Aug 2020 at 01:28, Ian Lance Taylor  wrote:

> After many discussions and reading many comments, we plan to move
> forward with some changes and clarifications to the generics design
> draft.
>
> 1.
>
> We’re going to settle on square brackets for the generics syntax.
> We’re going to drop the “type” keyword before type parameters, as
> using square brackets is sufficient to distinguish the type parameter
> list from the ordinary parameter list.  To avoid the ambiguity with
> array declarations, we will require that all type parameters provide a
> constraint.  This has the advantage of giving type parameter lists the
> exact same syntax as ordinary parameter lists (other than using square
> brackets).  To simplify the common case of a type parameter that has
> no constraints, we will introduce a new predeclared identifier “any”
> as an alias for “interface{}”.
>
> The result is declarations that look like this:
>
> type Vector[T any] []T
> func Print[T any](s []T) { … }
> func Index[T comparable](s []T, e T) { … }
>
> We feel that the cost of the new predeclared identifier “any” is
> outweighed by the simplification achieved by making all parameter
> lists syntactically the same: as each regular parameter always has a
> type, each type parameter always has a constraint (its meta-type).
>
> Changing “[type T]” to “[T any]” seems about equally readable and
> saves one character.  We’ll be able to streamline a lot of existing
> code in the standard library and elsewhere by replacing “interface{}”
> with “any”.
>

This is great. I like the fact that the type parameter list is just a
normally formed parameter list now.
I did quite like the fact that you could see defined types with a grep for
"type", but that's
not always the case anyway with type blocks, so I'll put that feeling aside.

2.
>
> We’re going to simplify the rule for type list satisfaction.  The type
> argument will satisfy the constraint if the type argument is identical
> to any type in the type list, or if the underlying type of the type
> argument is identical to any type in the type list.  What we are
> removing here is any use of the underlying types of the types in the
> type list.  This tweaked rule means that the type list can decide
> whether to accept an exact defined type, other than a predeclared
> type, or whether to accept any type with a matching underlying type.
>
> This is a subtle change that we don’t expect to affect any existing
> experimental code.
>
> We think that this definition might work if we permit interface types
> with type lists to be used outside of type constraints.  Such
> interfaces would effectively act like sum types. That is not part of
> this design draft, but it’s an obvious thing to consider for the
> future.
>
> Note that a type list can mention type parameters (that is, other type
> parameters in the same type parameter list).  These will be checked by
> first replacing the type parameter(s) with the corresponding type
> argument(s), and then using the rule described above.
>

This is also a great forward-looking change.


>
> 3.
>
> We’re going to clarify that when considering the operations permitted
> for a value whose type is a type parameter, we will ignore the methods
> of any types in the type list.  The general rule is that the generic
> function can use any operation permitted by every type in the type
> list.  However, this will only apply to operators and predeclared
> functions (such as "len" and "cap").  It won’t apply to methods, for
> the case where the type list includes a list of types that all define
> some method.  Any methods must be listed separately in the interface
> type, not inherited from the type list.
>
> This rule seems generally clear, and avoids some complex reasoning
> involving type lists that include structs with embedded type
> parameters.
>

Ditto.


>
> 4.
>
> We’re going to permit type switches on type parameters that have type
> lists, without the “.(type)” syntax.  The “(.type)” syntax exists to
> clarify code like “switch v := x.(type)”.  A type switch on a type
> parameter won’t be able to use the “:=” syntax anyhow, so there is no
> reason to require “.(type)”.  In a type switch on a type parameter
> with a type list, every case listed must be a type that appears in the
> type list (“default” is also permitted, of course).  A case will be
> chosen if it is the type matched by the type argument, although as
> discussed above it may not be the exact type argument: it may be the
> underlying type of the type argument.  To make that rule very clear,
> type switches will not be permitted for type parameters that do not
> have type lists.  It is already possible to switch on a value “x”
> whose type is a type parameter without a type list by writing code
> like “switch (interface{})(x).(type)” (which may now be written as
> “switch any(x).(type)”).  That construct is not the simplest, but it
> uses only features already present in the language, and we 

Re: [go-nuts] Generics: after type lists

2020-08-15 Thread roger peppe
On Sat, 15 Aug 2020 at 04:57, Patrick Smith  wrote:

> On Thu, Aug 13, 2020 at 11:25 PM Patrick Smith 
> wrote:
> > I tried out a few different implementations, evaluating the polynomial
> > instead of finding roots,
> > at https://go2goplay.golang.org/p/g8bPHdg5iMd . As far as I can tell,
> > there is no sensible way to
> > do it with an interface that is implemented directly by *big.Float; we
> > need to wrap *big.Float
> > in a wrapper type in any case.
>
> After looking at the draft again, and seeing the Settable example
> there, I realized we can do it using big.Float directly, but it needs
> two interfaces, one matching big.Float and one matching *big.Float. I
> have updated my examples at https://go2goplay.golang.org/p/auSkvhWSNHn


I think that works pretty well, and seems to be the direction that things
are going in.
Here's your example cleaned up a bit to show just that latest example, and
also
showing how it looks when adapting a built-in type:

https://go2goplay.golang.org/p/eFIvHocOC75

It's possible to build a generic adaptor type from the value-style
interface to the pointer-style interface, which you might find interesting:

  https://go2goplay.golang.org/p/NiQY_-kWvu8

This could *almost* work on image.Point, except that Point.Mul has the
wrong signature.

  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/CAADvV_vxU7nUJ16X5xwBYhiOPVrzp%3DzrX%3DU4UTgBsOQJ2RnMuQ%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/CAJhgacgn3maKUvpRV8U1Pe7K2RrOiDBgHVvu6DYwAgNgYs%2BCNA%40mail.gmail.com.


Re: [go-nuts] [ generics ] Concrete example of comparables and generic function types

2020-08-14 Thread roger peppe
Nice example! Presumably if you wanted to do actual Porter-Duff though,
you'd want some arithmetic rather than just comparison.

One observation: you don't actually need the "comparable" constraint on
many of the core entities there (e.g. Rect and Op) because they don't
actually use any compare operations. The code works just fine if you omit
them: https://go2goplay.golang.org/p/dKGOaN_v3He

Technically, the "z" argument to Op isn't necessary either AFAICS - you
could just use a zero value instead (unless you actually want to be able to
have a non-zero "zero" value, I guess).

  cheers,
rog.


On Fri, 14 Aug 2020 at 04:37, Beka Westberg  wrote:

> Hello! I just ran into a problem that is solved really nicely with the new
> generics proposal and I thought someone might find it interesting :D
>
> I was trying to implement a library for doing ascii art programmatically.
> The main struct is basically an image.Image except it works with bytes
> instead of colors. As such you /should/ be able to create functions (like a
> flood fill algorithm) that are abstracted over both of these types, but
> without "generics" this cannot be done (with compile time type safety).
>
> I sketched a little project 
> in the go2go playground that implements generic functions for doing 
> Porter-Duff
> compositions  on any types
> that fulfill the following constraint:
>
> ```
> type Rect(type T comparable) interface {
> At(x, y int) T
> Set(x, y int, t T)
> }
> ```
>
> Type defs on lines [8, 13]. Porter-Duff implementation [15, 99] Main [101,
> 108] ByteImg implementation [110, 185]
>
> I liked this example because it requires passing a generic function (the
> Porter-Duff func) to another generic function (Merge) :D I hope someone
> else finds it interesting as well!
> --Beka
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/dbc90697-e276-437b-ab39-b52564fc6d5an%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/CAJhgacjmxWC361xC-W4zTrw%3D6nO-%2BhRi0UVRAWSYKqRBkHfw2w%40mail.gmail.com.


Re: [go-nuts] [ generics ] Added constraint type inference to the design draft

2020-08-14 Thread roger peppe
On Thu, 13 Aug 2020 at 23:30, Ian Lance Taylor  wrote:

> On Thu, Aug 13, 2020 at 3:09 PM roger peppe  wrote:
> >
> > I do feel that the "all or nothing" nature of type parameter lists (if
> you specify one type parameter, you must explicitly specify all of the
> others too, even if they could otherwise be inferred) is likely to get in
> the way here. I'd like to see a way to specify some type parameters and not
> others, so that constraint type inference can work even when, for example,
> there's a generic return type parameter that can't be inferred from the
> arguments. We could potentially use an underscore for that.
>
> If I understand you correctly, we changed that when we added the
> constraint type inference section.  See the updated
>
> https://go.googlesource.com/proposal/+/refs/heads/master/design/go2draft-type-parameters.md#type-inference
> section.
>

Ah, that's useful and interesting, thanks. I suspect that being able to
selectively omit type parameters could be useful though - for when there's
no obvious ordering to the parameters and you want to infer some of the
earlier types in the list while specifying some later ones. Maybe in
practice it'll always be possible to use an explicit type conversion in a
value parameter to do this though, especially if Steven
Blenkinsop's ordering suggestions are followed (perhaps that could be a `go
vet` checki).

  cheers,
rog.

> 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/CAJhgacjPfoUp%2Bkhb4csuF%2Bz%3DTEWchZuSri94yTP4%2BtRvtnK5Ng%40mail.gmail.com.


Re: [go-nuts] [ generics ] Added constraint type inference to the design draft

2020-08-13 Thread roger peppe
That's interesting; thanks for the heads up.

My initial reaction is that this perhaps feels a bit "clever", but perhaps
this feeling will go away in time.

Constraint type inference is useful when a function wants to have a type
> name for an element of some other type parameter, or when a function wants
> to apply a constraint to a type that is based on some other type parameter.


I found this initial sentence describing the motivation behind the feature
a bit abstract and hence hard to understand:

Perhaps a tiny example might help at that point to orient the reader in the
right direction?

 Constraint type inference can only infer types if some type parameter has
> a constraint that has a type list with exactly one type in it.


When I first read the above, my first thought was: but it's not very useful
then because when would you have a type list with only one type in?
Of course, it becomes clear later that you'd define this kind of constraint
precisely to use this feature, but perhaps the phrasing could be changed a
little to make that more obvious?

Overall, I like the fact that this feature uses the existing semantics of
type lists and only extends the type-inference algorithm.

I do feel that the "all or nothing" nature of type parameter lists (if you
specify one type parameter, you must explicitly specify all of the others
too, even if they could otherwise be inferred) is likely to get in the way
here. I'd like to see a way to specify some type parameters and not others,
so that constraint type inference can work even when, for example, there's
a generic return type parameter that can't be inferred from the arguments.
We could potentially use an underscore for that.

So, for example:

   var f = DoubleDefined[MySlice, _]

would be valid. f would be a function value of type func(MySlice) MySlice.

  cheers,
rog.




On Thu, 13 Aug 2020 at 03:31, Ian Lance Taylor  wrote:

> I just added a new section to the generics design draft describing
> constraint type inference.  This is a generalization and
> simplification of the earlier pointer method approach, which has now
> been removed.  I would be happy to hear any comments.  Thanks.
>
>
> https://go.googlesource.com/proposal/+/refs/heads/master/design/go2draft-type-parameters.md#constraint-type-inference
>
> 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/CAOyqgcX6AcGUt4e6JTMrxXkAtMRq%2Bo6zSVnjqchEroheYBP%2BBw%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/CAJhgaciL%3D0p3rwMOmXW3oxNFhKVWFa6bT6-SsBi-E5iaeFxYqQ%40mail.gmail.com.


Re: [go-nuts] "Interfaces" with type lists are a strange beast

2020-08-13 Thread roger peppe
On Wed, 12 Aug 2020 at 16:43, 李晓辉  wrote:

> Maybe `type list` equals to `sum type`
>
> type SignedInteger interface {
>type int, int8, int16, int32, int64
> }
>
> can replaced by
>
> type SignedInteger int|int8|int16|int32|int64
>

Yes, I've had that thought too (and mentioned it as feedback), but there's
one wrinkle: what about the "underlying type" behaviour of generics?
That is, although matching on the underlying type instead of the actual
type is useful for type parameters, it's less intuitive and/or useful
when used as a normal type. I think I'd be surprised if a value of type
"int|uint" was not exactly one of those two types.

For the record, I've made a somewhat detailed suggestion for sum types
along these lines here
.

  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/CAJhgacj7sQxzCeG26B9ShiirxtEQ7x%2BPSoUVBJ2rUr259m%2BT4Q%40mail.gmail.com.


Re: [go-nuts] Non-alphanumerics in template field names?

2020-08-01 Thread roger peppe
You could use the "index" built-in function instead of the dot operator:

{{index . "foo:bar"}}

On Fri, 31 Jul 2020, 17:16 Bob DuCharme,  wrote:

> I have seen that a map key name of "foo:bar" works just fine... unless I
> reference it in a template. {{.foo:bar}} gives me a segmentation violation
> at runtime, but works fine if there was no colon in the map key name. I
> have tried various ways to escape the colon or quote the field name (e.g.
> {{."foo:bar"}}, {{.foo%3Abar}} ) with no luck.
>
> Does anyone know a way to allow non-alphanumeric characters (besides the
> underscore, which I know works) in names that get referenced in templates?
>
> Thanks,
>
> Bob
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/ec64bc07-52a8-429d-bf13-7853da959925n%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/CAJhgaciaZhVn4fYmm8GGr-56qA0t_HS4iSpAXEcBPR%3DSvo4tgQ%40mail.gmail.com.


Re: [go-nuts] json.Unmarshal with disallowUnknownFields

2020-07-30 Thread roger peppe
You could write a function to do that for you.

On Thu, 30 Jul 2020, 09:45 Brian Candler,  wrote:

> I want to do a json.Unmarshal of []byte data whilst also getting the
> disallowUnknownFields behaviour.  Is there any tidier way than this
> ?
>
> dec := json.NewDecoder(bytes.NewReader(data))
> dec.DisallowUnknownFields()
> var v mystruct
> err := dec.Decode()
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/5c1c7101-8ead-46b2-9e58-8b7f26203be0o%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/CAJhgaciA82muYrh4-rK2HRjP6CdG75uDvo3QaovgHMm6YVs93A%40mail.gmail.com.


Re: [go-nuts] Generics and parentheses

2020-07-18 Thread roger peppe
On Sat, 18 Jul 2020, 13:25 Jan Mercl, <0xj...@gmail.com> wrote:

> On Sat, Jul 18, 2020 at 1:39 PM roger peppe  wrote:
>
> > I didn't say there was exactly one construct for each kind of name
> definition. In current Go, when a name is defined, it's defined inside a
> construct that is explicitly about defining that name. By contrast, in your
> proposal, we take an arbitrary type and add a dollar qualifier on a name
> somewhere inside it, and that turns the construct into a definition. That
> doesn't feel very Go-like to me.
>
> I think about type parameters in the same way as variables. We don't
> list all the variables in a function in a special list.


The variables in a function aren't part of its publicly visible API.

A _value_
> variable holds a number, for instance. A type parameter holds a
> _type_. Both variable and type parameters are declared where
> necessary, not upfront. Well, the parameter list of a function is an
> upfront list, but that's the only place.
>

It's an important distinction to make: the parameter list of a function is
part of its type definition the same way that the type parameter list of a
generic function is part of its type definition.

Another way to think about type parameters, let me call them also type
> variables, is that value variables are a run time thing while type
> variables exist only at compile time. Otherwise they seem pretty
> similar to me.


> > It's an arbitrary place because it's somewhere buried inside the generic
> type
> > or function. ISTM that it's not great that the form of the types or code
> should
> > directly determine the order of the type parameters. To take an example,
> > say I have some code that uses some generic container defined externally:
>
> Ok, I think now I understand better.
>
> > type S struct {
> > container *external.Container@T1@T2
> > }
>
> Note this would be invalid under the alternative proposal. The correct
> form would have to be:
>
> type S struct {
> container *external.Container@$T1@$T2
> }
>
> And with the order fixing hack (Types is an example. Whatever name
> works, even _, but making  it exported enables it to be shown in
> godocs):
>
> type S struct {
> Types [0]struct{$T1, $T2}
>

I think you'd need a semicolon there, not a comma, for the record (and I
think that gofmt would format this differently).

   container *external.Container@T1@T2
> }
>

What if S isn't a struct type?


>
> > Now what if we want to change the private field to use some alternative
> container implementation that happens to take
> > its type arguments in a different order?
> >
> > type S struct {
> > container *other.Container@T2@T1
> > }
>
> type S struct {
> Types [0]struct{$T1, $T2}
> container *other.Container@T2@T1
> }
>
> IOW, the type parameter list will in some cases appear as it does in
> the original proposal, just not in the prominent position. In other,
> possibly most cases the type parameter list is no longer needed. And
> let's not forget that the original draft also has its "hacks", kind
> of. It requires writing interface{} constraint in some cases


That's just an omission of convenience - all type parameters without
constraints are implicitly "interface{}", so really is the case without
that qualification which is the "hack" (or syntax sugar if you prefer).

, it
> requires parenthesis in other places to resolve parsing ambiguities.
> Both of which the alternative draft does not seem to suffer from.
> Compromises...
>

Which compromises are you referring to here?


> >> I guess that type parameters will in practice appear most often right
> >> in the signature anyway.
> >
> >
> > I'm not keen on this rationalisation. It feels like working around
> something that could have been done correctly from the outset.
>
> It's just my guess. A corpus of real existing generic Go2 code is
> needed to get some real numbers.
>
> > Here's another example:
> >
> > type S struct {}
> >
> > func (s S) Bz() $B {
> > var b B
> > return b
> > }
> >
> > func (s S) Az() $A {
> > var a A
> > return a
> > }
> >
> > AFAICS in this case the ordering of the methods of S influences the
> order of the type parameters required to instantiate S.
> > If we reorder the Az and Bz methods, then we're breaking compatibility.
> What if they're in different files?!
>
> You're right and this hadn't occurred to me before. The only solution
> I can see is:
>
> type S struct { Types [0]

Re: [go-nuts] Generics and parentheses

2020-07-18 Thread roger peppe
On Sat, 18 Jul 2020 at 11:05, Jan Mercl <0xj...@gmail.com> wrote:

> On Sat, Jul 18, 2020 at 11:12 AM roger peppe  wrote:
>
> Thanks for taking time to think about it.
>
> > A few reasons that I'm not keen on your $, @ proposal:
> >
> > - elsewhere in Go, when a name is defined, there is one clear construct
> that defines it, not an arbitrary place within a type expression. That's
> not the case in your proposal.
>
> I don't think variables are declared in just one construct.


I didn't say there was exactly one construct for each *kind* of name
definition. In current Go, when a name is defined, it's defined inside a
construct that is explicitly about defining that name. By contrast, in your
proposal, we take an arbitrary type and add a dollar qualifier on a name
somewhere inside it, and that turns the construct into a definition. That
doesn't feel very Go-like to me.

The term "type expression" does not appear in [1], so let me now
> assume you meant "type literal" and/or just "type" as that includes
> defined types.
>

Yes, just "type" is sufficient, although that term has two purposes - it
can refer both to the program text that declares the type and to the actual
type itself once defined. I was using "type expression" in an attempt to
say the former.

The alternative proposal makes names starting with $ to mean a type
> parameter right at the tokenizer. In the same way as variable
> declaration is accepted by the grammar only in certain contexts, type
> parameters are accepted in the alternative proposal only in the
> context of a type literal, where a type name is allowed. Nowhere else.
>
> var a T
> var a $T
>
> var a map[T]U
> var a map[$T]U
> var a map[$T]$U
> var a map[T]$U
>
> In the original proposal a new place where type can appear is the
> instantiation of a generic type. Same for the alternative draft:
>
> foo(int)(42) // original, predeclared type
> foo@int(42) // alternative
>
> func foo(type T)(x T) { // original
> bar(T)(x) // instantiate bar with type parameter T
> }
>
> func foo(x $T) { // alternative
> bar@T(x) // instantiate bar with type parameter T, the $ sign
> is optional as T was already declared above
> }
>
> So I'm not sure where "arbitrary place" comes from. Note that the
> alternative draft specifies the type parameter declaration must occur
> at its first lexical occurrence.
>

It's an arbitrary place because it's somewhere buried inside the generic
type
or function. ISTM that it's not great that the form of the types or code
should
directly determine the order of the type parameters. To take an example,
say I have some code that uses some generic container defined externally:

type S struct {
container *external.Container@T1@T2
}

To make an instance of S, we need to mention the types in the same order
that we gave them to the external.Container type:

S@string@int

Now what if we want to change the private field to use some alternative
container implementation that happens to take
its type arguments in a different order?

type S struct {
container *other.Container@T2@T1
}

This is an API-breaking change, but it's both non-obvious and not entirely
trivial to work around (we'll need to define our own wrapper type for
other.Container that has the same type parameter order).


> func f(x $T) T { ... } // Is valid in the alternative draft
> func f(x T) $T { ... } // Is not valid in the alternative draft
>
> > - the ordering of the type parameters is important, but is implicit in
> the ordering of the type expressions rather than explicit. The order of the
> type parameters may not even be visible to an external consumer of an API
> (for example, consider a function that returns a generic struct where the
> only generic elements are private fields). Reordering fields within a
> struct could affect the type parameter order - something that should be
> possible to do backwardly compatibly.
>
> This is true and to an extent was mentioned in the alternative draft.
> There's a possible hack for fixing the order in a function and/or a
> struct by listing the prefered order using blank (underscore) variable
> declarations or zero sized fields, but that's ugly. Wait, is it
> really? Firstly, the need for that will probably not be common,
> secondly `var _ myInterface = (*myType)(nil)` etc. is a common idiom
> and it's rather similar to var _ $T; var _ $U, isn't it?


> I guess that type parameters will in practice appear most often right
> in the signature anyway.
>

I'm not keen on this rationalisation. It feels like working around
something that could have been done correctly from the outset.

>
> > - it's strictly less general than the

Re: [go-nuts] Generics and parentheses

2020-07-18 Thread roger peppe
On Thu, 16 Jul 2020, 14:38 Jan Mercl, <0xj...@gmail.com> wrote:

> On Thu, Jul 16, 2020 at 3:12 PM 'Axel Wagner' via golang-nuts
>  wrote:
>
> > I dislike the idea of using $ and @ because I don't want to add new
> symbols to the language, if it can be avoided. In general I'd argue that Go
> tends to use keywords instead of symbols to convey meaning - e.g. we don't
> write `a -> b`, but `func(a) b`. There are exceptions (pointers are a big
> one) of course, but Go is still pretty light on symbols.
> > I think the overuse of symbols to convey semantics is a huge reason that
> I find perl and Haskell so unreadable, personally.
>
> There are 31 printable, non blank, non-digit, non-letter ASCII
> symbols. Go (lexical grammar) currently uses 27 of them. I'm not sure
> if using 27 of 31 vs using 29 out 31 makes a notable difference. (I
> have not counted smybol groups like ":=" ">=", "<-" etc., but that
> makes the number of symbols used in Go only bigger, not smaller.)
>
> But of course, a keyword would work as well. For example, $ can be
> replaced with no semantic change with 'type'. And @ can be dropped
> while keeping the original draft syntax for type instantiation - and
> the original parsing ambiguities. Then we can have something like
>
> Original:
>
> func Keys(type K comparable, V interface{})(m map[K]V) []K { ... }
> s := Keys(int, string)(m)
>
> Alternative-AW:
>
> func Keys(m map[type K comparable]type V) []K
> s := Keys(int, string)(m)
>
> FTR: In the alternative draft I missed the `~` (tilde) character, so
> there are not 3 but actually 4 ASCII symbols not used by Go.
>
> But I like the $, @ option because the language change is pushed
> "down" to be based mainly in the lexer grammar.


A few reasons that I'm not keen on your $, @ proposal:

- elsewhere in Go, when a name is defined, there is one clear construct
that defines it, not an arbitrary place within a type expression. That's
not the case in your proposal.

- the ordering of the type parameters is important, but is implicit in the
ordering of the type expressions rather than explicit. The order of the
type parameters may not even be visible to an external consumer of an API
(for example, consider a function that returns a generic struct where the
only generic elements are private fields). Reordering fields within a
struct could affect the type parameter order - something that should be
possible to do backwardly compatibly.

- it's strictly less general than the original proposal. There's no way to
write a generic function that doesn't mention the generic type as part of
its signature. For example, you couldn't write this function:

func zeroPtrInterface[type T]() interface{} {
return new(T)
}

- I'm not keen on the @, $ syntax. It co-opts not just one but two new
symbols into the Go syntax, and I suspect that the merging of reference and
definition will make the resulting code hard to read.

For the record, I support the [] syntax. The analogy between generic
functions and maps makes sense to me, and I think it's sufficiently
syntactically distinct to avoid the issues with round brackets. My main
reservation is about backward compatible evolution of generic types. It's
not possible to add a new type parameter in a backwardly compatible way. In
larger systems, I wonder if that might turn out to be a significant issue.

  cheers,
rog.

I haven't made any
> attempt to write a parser for the alternative draft, but I think this
> makes the changes on top of the existing parser pretty minimal. The
> original draft, on the other hand, needs IMO much more changes.
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/CAA40n-VwE2URengdE0Cd7sPQNCm5%3DTm5%3DaUS8kMwOpEw%3DXjJyg%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/CAJhgach5eUJvZ6ek5SZzoLW%3Dgi7axXRUbtz3-ukbLLSCVLAiOw%40mail.gmail.com.


Re: [go-nuts] [generics] Issues with identifying the matched predeclared type

2020-07-08 Thread roger peppe
On Wed, 8 Jul 2020 at 00:33, Steven Blenkinsop  wrote:

> On Tue, Jul 7, 2020 at 10:44 AM, roger peppe  wrote:
>
>>
>> In my description, there's no assumption that doing it over the type
>> parameter implies a refinement of the previously set type constraints. In
>> fact it definitely implies otherwise because (for example) if you know that
>> a generic type parameter has the known type "string", then it's a loosening
>> rather than a tightening of the constraint - you can now do more things
>> with values of that type than you could previously.
>>
>
> I think this is speaking at cross purposes. The identity of the type is
> more constrained (it must be string  as opposed to any other type
> satisfying a particular interface), but you can do more with it in your
> generic code. You're refining the constraint on the identity of the type
> while at the same time expanding its capabilities. An unconstrained type
> parameter can be any type but supports the fewest operations.
>

Fair point.


>
> I don't think it's sufficient. Consider this program:
>> https://go2goplay.golang.org/p/wO0JHIuHH2l. If "string" matches both
>> "myString" and "string" itself, then the type checker would allow the
>> assignment of a function of type "func(string) uint64" to a function of
>> type "func(myString) uint64" with no explicit type conversion, which breaks
>> an important safety constraint in the language. Worse, if we let an
>> interface type match any concrete type that happens to implement that
>> interface, then there's a serious issue because those types probably don't
>> have the same shape, so can't be used interchangeably. For example, this
>> program would be valid, but isn't possible to compile because io.Stringer
>> and string have different representations:
>> https://go2goplay.golang.org/p/_uLjQxb-z-b
>>
>
> I would think that in the second case, the assignment to xx wouldn't type
> check because T is only known to implement io.Stringer rather than being
> identical to io.Stringer.
>

That depends on the semantics of the type switch. In my suggestion, it
would type check because the case would only be chosen if the argument type
is *exactly* that type (but the xx slice wouldn't be assigned to). You'd
need to add a "type" qualifier to match on any type that implements
io.Stringer.

Perhaps this would be more clear if it was written as
>
> type switch {
> case T io.Stringer:
>   // Code here can treat the type parameter T
>   // as though the generic type list defining
>   // it was `(type T io.Stringer)`
> }
>

That's another interesting syntax. I'm not sure whether there's any
particular advantage in mentioning the type parameter in each case,
although I guess it does mean that the syntax for multiple matches is
straightforward and can allow an "any" match.

type switch {
case T1 string, T2 string:
case T1 []byte, T2 string:
case T1 string:
}

If my syntax were to support multiple type parameters, that might look like

   switch T1, T2 {
   case (string, string):
   case ([]byte, string):
   case (string, type interface{}):
   }

One could define _ to be a synonym for "type interface{}", I guess.


Of course, this wouldn't allow you to write either of your examples. But
> then, your stringHash example could be written using:
>
> func stringHash(type S interface{type string})(s S) uint64 {
> return 1
> }
>

That doesn't seem ideal to me. There are many potentially useful
non-generic functions out there and I think it would be nice to be able to
use them in this way.

>
> https://go2goplay.golang.org/p/FAaqnFalYCL
>
> I think the key tension with allowing you to match on the specific type
> passed in is that, if you actually need to do this, then that means your
> function can't handle certain type parameters which are permitted by its
> signature, i.e. it's not total over its type parameter domain.
>

ISTM that technically the function is still total over the type parameter
domain (assuming you don't panic in the default case) - it just has
different behaviour depending on the type parameters, which is exactly what
the type switch is for. Also, you can *already* do this in a slightly more
limited way, by converting to interface{} and type switching on that,
although that's restrictive because it doesn't allow you to assign back to
generic values - the types aren't unified - which is why we're talking
about this feature here.


> If interfaces allowed you to restrict the type parameters passed in to the
> specific ones you can handle, then you would necessarily also be able to
> handle each specific case by matching on interface satisfaction 

Re: [go-nuts] [generics] Issues with identifying the matched predeclared type

2020-07-07 Thread roger peppe
On Tue, 7 Jul 2020 at 21:05, Tobias Gustafsson <
tobias.l.gustafs...@gmail.com> wrote:

> Den tisdag 7 juli 2020 kl. 16:45:21 UTC+2 skrev rog:
>>
>> On Tue, 7 Jul 2020 at 10:36, Tobias Gustafsson 
>> wrote:
>>
>>> Hi all,
>>>
>>> Thanks for the response on this subject!
>>>
>>> Yes, a kind of type switch over generic types is probably what I
>>> envision. There is a potentially nice symmetry with the current runtime
>>> type switches and type annotations that caught my eye (being aware of the
>>> fact that finding false patterns and symmetries may lead you astray...).
>>>
>>> If we do manage to set the semantics for a type switch over a generic
>>> type I'd expect that to also spill over to type assertions over generic
>>> types. Perhaps it would also be easier to start with at type assertion to
>>> explore the problem space a bit more before heading directly for the type
>>> switch.
>>>
>>
>> That's not technically needed AFAICS, given that you can already convert
>> to interface{} and then type switch, but it's potentially nice as syntax
>> sugar.
>>
>
> Not sure I completely understand what you mean by this, what I meant is
> basically that I would find it good to be able to do things like this:
>
> var x T  // Generic type T
> s := x.(string)  // s is a string or compile time error
>
> s, ok := x.(string) // s is the string x represents if T is of type string,
> // otherwise a zero value string.
> // Any code relying on ok to be true can be eliminated
> // during compilation if type assertion fails and vice
> // versa.
>

By  "convert to interface{}", I meant using "interface{}(x)" to convert to
a type-switchable value. For example:
https://go2goplay.golang.org/p/txdvJauonEu
It might be nice to be able to do that without the conversion to
interface{}, but it's not technically *necessary*.

  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/CAJhgachiRNc1X0oZW0BATuL7Y1uoWMmmKm5bzhiVpCKW77PgYQ%40mail.gmail.com.


Re: [go-nuts] [generics] Issues with identifying the matched predeclared type

2020-07-07 Thread roger peppe
e specified type. By wrapping the specified type in a
>> type qualifier, the matching is not exact, but *matches* the kind of
>> type instead. For some non-interface type X, type(X) matches any type
>> with an underlying type of X. When X is an interface type, type(X) matches
>> any type that implements the interface. Type-list interfaces are allowed.
>>
>> func F(type T, U)() {
>>  switch T {
>>  case int:
>>  // T is exactly the type int.
>>  case error:
>>  // T is exactly error, not some type that happens to satisfy 
>> the error inferface.
>>  case type(string):
>>  // T is any type with an underlying type of string
>>  case type(io.ReadCloser):
>>  // T is any type that satisfies the io.ReadCloser interface.
>>  case type(interface{
>>  type int, int64
>>  }):
>>  // T has an underlying type of either int or int64.
>>  case string:
>>  // Compile error: duplicate case (matched by generic(string) 
>> above).
>>  case type(io.Reader):
>>  // Compile error: duplicate case (matched by 
>> generic(io.ReadCloser) above).
>>  case U:
>>  // Both type parameters are exactly the same type.
>>  }
>> }
>>
>>
>> *Discussion*
>>
>> It might be a good idea to allow a type switch to specify a list of types
>> rather than a single type, so several generic parameters can be specialized
>> at the same time. For example:
>>
>> switch T, U {
>> case int, string:
>> }
>>
>>
>> This is syntactically rather more useful than in a normal type switch,
>> because there's no way to avoid nesting type switches (in a normal type
>> switch, it's possible to assign the specialized value to another variable
>> with wider scope, but that's not possible in general with generic type
>> switches). However, it may be too confusing syntactically with the normal
>> comma-list in a type switch statement which means "any of these types". A
>> possible way of avoiding confusion that might be to require brackets:
>>
>> switch T, U {
>> case (int, string):
>> }
>>
>>
>> The ability to use a concrete type directly in a  type(X) case is just
>> syntax sugar for type(interface{type X}) and could be omitted. It
>> depends how commonly used this might be.
>>
>>
>> On Tue, 7 Jul 2020 at 04:51, Steven Blenkinsop  wrote:
>>
>>> On Mon, Jul 6, 2020 at 6:29 PM, roger peppe  wrote:
>>>
>>>>
>>>> I've also been playing around in this area. I've been trying something
>>>> similar to this approach: https://go2goplay.golang.org/p/sHko_EMhJjA
>>>> But this isn't ideal - note that we lose type safety when assigning
>>>> back to the generic hash function, because there's no way to let the
>>>> compiler know that the actual type of the generic type parameter is known
>>>> at that point.
>>>>
>>>> I also noticed an interesting wrinkle to doing a type switch on a value
>>>> of the type:
>>>>
>>>> We can't do this:
>>>>
>>>>   case Hasher:
>>>>   hi = func(t Hasher) uintptr {
>>>>   return t
>>>>   }
>>>>
>>>> because the actual type probably isn't Hasher - it's the actual type,
>>>> not the interface type.
>>>>
>>>> If a type switch on a type argument was implemented (and I definitely
>>>> support it) we'd have to think carefully about what semantics would be
>>>> desired in this case - if one of the types is an interface type, would one
>>>> get the usual interface-subtype rules for matching or not?
>>>>
>>>> For the record, I quite like the idea of using a separate syntax for
>>>> type-based checking:
>>>>
>>>>type switch T {
>>>>case int:
>>>>case string:
>>>>}
>>>>
>>>> That way, we could use exact-match rules for that construct without
>>>> risk of confusion with the normal type switch rules, and perhaps the
>>>> difference might make it clearer that T would change its type inside the
>>>> body of the switch.
>>>>
>>> If the idea is to be able to refine the constraints on a type parameter,
>>> then you need to be able to match based on "T satisfies this
>>> interface". If you want to be able to

Re: [go-nuts] [generics] Issues with identifying the matched predeclared type

2020-07-07 Thread roger peppe
How about something like this?

Type switches

A *generic type switch* allows a generic function to provide specialized
behaviour based on its type arguments (for example to use a more efficient
implementation for some types).

A type switch refines the type of a type parameter. Cases match actual
types against the generic type parameter in turn. Within the body of a
case, the named type parameter has the actual type. A single case may not
list more than one type.

By default, matching is exact: for a case to match, the type parameter must
be exactly the specified type. By wrapping the specified type in a
type qualifier,
the matching is not exact, but *matches* the kind of type instead. For some
non-interface type X, type(X) matches any type with an underlying type of X.
When X is an interface type, type(X) matches any type that implements the
interface. Type-list interfaces are allowed.

func F(type T, U)() {
switch T {
case int:
// T is exactly the type int.
case error:
// T is exactly error, not some type that happens to satisfy the
error inferface.
case type(string):
// T is any type with an underlying type of string
case type(io.ReadCloser):
// T is any type that satisfies the io.ReadCloser interface.
case type(interface{
type int, int64
}):
// T has an underlying type of either int or int64.
case string:
// Compile error: duplicate case (matched by generic(string) 
above).
case type(io.Reader):
// Compile error: duplicate case (matched by 
generic(io.ReadCloser) above).
case U:
// Both type parameters are exactly the same type.
}
}


*Discussion*

It might be a good idea to allow a type switch to specify a list of types
rather than a single type, so several generic parameters can be specialized
at the same time. For example:

switch T, U {
case int, string:
}


This is syntactically rather more useful than in a normal type switch,
because there's no way to avoid nesting type switches (in a normal type
switch, it's possible to assign the specialized value to another variable
with wider scope, but that's not possible in general with generic type
switches). However, it may be too confusing syntactically with the normal
comma-list in a type switch statement which means "any of these types". A
possible way of avoiding confusion that might be to require brackets:

switch T, U {
case (int, string):
}


The ability to use a concrete type directly in a  type(X) case is just
syntax sugar for type(interface{type X}) and could be omitted. It depends
how commonly used this might be.


On Tue, 7 Jul 2020 at 04:51, Steven Blenkinsop  wrote:

> On Mon, Jul 6, 2020 at 6:29 PM, roger peppe  wrote:
>
>>
>> I've also been playing around in this area. I've been trying something
>> similar to this approach: https://go2goplay.golang.org/p/sHko_EMhJjA
>> But this isn't ideal - note that we lose type safety when assigning back
>> to the generic hash function, because there's no way to let the compiler
>> know that the actual type of the generic type parameter is known at that
>> point.
>>
>> I also noticed an interesting wrinkle to doing a type switch on a value
>> of the type:
>>
>> We can't do this:
>>
>>   case Hasher:
>>   hi = func(t Hasher) uintptr {
>>   return t
>>   }
>>
>> because the actual type probably isn't Hasher - it's the actual type, not
>> the interface type.
>>
>> If a type switch on a type argument was implemented (and I definitely
>> support it) we'd have to think carefully about what semantics would be
>> desired in this case - if one of the types is an interface type, would one
>> get the usual interface-subtype rules for matching or not?
>>
>> For the record, I quite like the idea of using a separate syntax for
>> type-based checking:
>>
>>type switch T {
>>case int:
>>case string:
>>}
>>
>> That way, we could use exact-match rules for that construct without risk
>> of confusion with the normal type switch rules, and perhaps the difference
>> might make it clearer that T would change its type inside the body of the
>> switch.
>>
> If the idea is to be able to refine the constraints on a type parameter,
> then you need to be able to match based on "T satisfies this interface".
> If you want to be able to match based on underlying type, you could match
> against e.g. interface { type int }.
>
> I'm not sure how useful matching on a precise type is in this context.
> Interfaces can't express exact type constraints as currently designed, so
> exact type matchin

Re: [go-nuts] [generics] Issues with identifying the matched predeclared type

2020-07-06 Thread roger peppe
On Mon, 6 Jul 2020 at 17:46,  wrote:

> Hi!
>
> I've spent some time lately to try out the go2go tool and the new generics
> proposal by converting a small hack I did some years ago for immutable data
> structures (https://github.com/tobgu/peds) which, in it's current shape,
> depends on code generation.
>
> There is nothing really mind bending to this since it's a pretty
> mainstream collections case of generics and overall the conversion process
> was quite pleasant. So, good job on the generics proposal so far!
>
> I did run up against one issue though that I've not really been able to
> cope with in an elegant, and decently performant, way so far. That of
> providing different implementations depending on the underlying type. For
> my particular case I would like to use differnt hash functions for the map
> depending on the type of the map key. In addition to this I would also like
> the user of the library to be able to provide their own hash function,
> should they want to, by implementing a Hasher interface.
>
> I've provided some example code to illustrate what I would like to be able
> to do here: https://go2goplay.golang.org/p/HQcSZj_nfaF
>
> I've read the discussion in the draft on the limitations related to this
> here:
>
> https://go.googlesource.com/proposal/+/refs/heads/master/design/go2draft-type-parameters.md#identifying-the-matched-predeclared-type
>
>
> But from that it's not entirly clear to me if:
> - This is a fix limitation that has been set to prevent bad design,
> unintended behaviour (compile time turing completness, language
> inconsistencies, etc.) or if it's a issue that should/will be fixed before
> the final implementation?
> - The limitations presented in the last paragraph of the above linked
> document are there for soundness of the implementation or if there are
> technical reasons for them? To me they seem unnecessarily restrictive.
> Since a type switch over a parametrized type could be evaluated at compile
> time it should be possible to use it in a fully type safe manner while it
> would provide the same type of flexibility at compile time that the current
> type switch provides at runtime.
>
> I'm also open to the fact that there may be entirely differnt ways to go
> about solving my particular problem (in a clean and efficient manner)
> within the bounds of the current spec. If so I'd be super happy to take
> suggestions!
>

I've also been playing around in this area. I've been trying something
similar to this approach: https://go2goplay.golang.org/p/sHko_EMhJjA
But this isn't ideal - note that we lose type safety when assigning back to
the generic hash function, because there's no way to let the compiler know
that the actual type of the generic type parameter is known at that point.

I also noticed an interesting wrinkle to doing a type switch on a value of
the type:

We can't do this:

  case Hasher:
  hi = func(t Hasher) uintptr {
  return t
  }

because the actual type probably isn't Hasher - it's the actual type, not
the interface type.

If a type switch on a type argument was implemented (and I definitely
support it) we'd have to think carefully about what semantics would be
desired in this case - if one of the types is an interface type, would one
get the usual interface-subtype rules for matching or not?

For the record, I quite like the idea of using a separate syntax for
type-based checking:

   type switch T {
   case int:
   case string:
   }

That way, we could use exact-match rules for that construct without risk of
confusion with the normal type switch rules, and perhaps the difference
might make it clearer that T would change its type inside the body of the
switch.

  cheers,
rog.

>
> Thanks a lot!
> // Tobias
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/1e5a294f-ea3a-42a5-97ed-32471a2ed9a6o%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/CAJhgacgHKMoKNhoWs%3DF_LdpELVNsA3kT3UbXitxG4do%2B41FUPA%40mail.gmail.com.


Re: [go-nuts] Re: [generics] Generics pave the way to some kind of polymorphism implementation?

2020-07-04 Thread roger peppe
When you say "polymorphism", I think you might mean "inheritance"?
(Go-with-generics already has two kinds of polymorphism)

I don't really understand what you're trying to accomplish here. Perhaps
you could explain your motivation a bit more?


On Fri, 3 Jul 2020, 21:22 Aleksandar Milovanović, 
wrote:

> If someone is interested I simplified the code, commented some more and
> added the unmarshall json in the example -
> https://go2goplay.golang.org/p/I_ezQ9wyWVx.
>
> Still, I don't know how to type the BuildEmptySpec() in BoxBaseI better
> than to return a simple interface{}... If it would
> return BoxSpecI(BoxBaseI) it would not be enough.
>
> Aleksandar
>
>
>
> On Fri, Jul 3, 2020 at 1:54 PM Aleksandar Milovanović <
> aleksan...@videobolt.net> wrote:
>
>> Hi guys,
>>
>> Thanks for the effort, it is much needed for quite some time. I really
>> appreciate the way of introducing the changes, go2go tool and open
>> discussion, so I wanted to review them and participate with feedback so you
>> can do the best job of understanding the world. With proposed changes, I
>> think extending language to support something similar to polymorphism might
>> be cheap.
>>
>> Consider this go playground: https://go2goplay.golang.org/p/jqA4ccWeAKD.
>>
>> Syntax is awkward currently (some syntax sugar is definitively needed),
>> but the point in the test below stands - you do have polymorphic slice, you
>> can use base fields and methods, and you can cast to the child structure
>> (which contains all the fields and methods from the base). json marshaling
>> was added to the example, json unmarshal could be implemented similarly,
>> but in that case we need provided mapping from base structure to the
>> specialized one, which can't be typed with current generics (for some of
>> it, interface{} and reflect would be needed). Could provide that example as
>> well, if needed.
>>
>> Sending this idea as I think it might be interesting, and I think you
>> might get some more ideas out of it.
>>
>> Aleksandar
>>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/CAG9NSAWtK%3DeUR9%2B_vCb0X5yun6VF3SB6WOkfq5%2B-cX7KXNQ9vg%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/CAJhgacjHm8b0K%3DZ8Urspgu1P1a0%2BUhWPK-vXzkA4An%3D-rRDTKg%40mail.gmail.com.


Re: [go-nuts] draft design for // +build replacement

2020-06-30 Thread roger peppe
LGTM. This is a welcome change. I often need to look up how to spell
"// +build" currently :)

One thing I'd really like to see is the eventual deprecation of
filename-based build constraints (e.g. file_linux.go).
They make it hard for users (not everyone knows the name of all
architectures), hard for tooling (tools
need to maintain a list of current architectures) and potentially
compatibility-breaking (adding
a new architecture can change the meaning of existing files). Could we
eventually mandate
in-file build constraints instead?

  cheers,
rog.


On Tue, 30 Jun 2020 at 21:04, Russ Cox  wrote:

> Hi all,
>
> I've posted a draft design for replacing // +build lines with //go:build
> lines that support standard boolean expression syntax. It is a draft design
> I'm circulating for feedback, not an official proposal. (I certainly hope
> it will be well received and can be made into a proposal, but that's not
> where we are today.)
>
> If you are interested, there is a doc and a video, linked below. As an
> experiment, I'd like to try using Reddit for the discussion, also linked
> below. The idea is that proper threading support should scale better than
> GitHub or a single large mail thread here would. But for those who don't do
> Reddit, I will keep an eye on this thread and reply as best I can.
>
> Video: https://golang.org/s/go-build-video
> Design: https://golang.org/s/go-build-design
> Q: https://golang.org/s/go-build-reddit
>
> Thanks!
>
> Best,
> Russ
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/CAA8EjDTO1NX%3DacOTqEfD%3D6pumUWzNNcGO%2BsPMrQVYdO0cmWsvQ%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/CAJhgacjXjt%2BhKVOLadcRxvwMnWRMJS%2BPwnKt8GdCa%2Bc77GUmRQ%40mail.gmail.com.


Re: [go-nuts] [Generics] Concise generics with package level types

2020-06-24 Thread roger peppe
The draft proposal does not support generic function values. Doing so would
make the compiler's code generation job much harder (or maybe not possible)
because it would be considerably more difficult to enumerate all the
possible instantiation parameters at compile time.

On Wed, 24 Jun 2020, 07:38 ,  wrote:

> My code  shows that returning
> a generic function might be desirable.
>
> The Filter function in my code  is as follows:
>
> func Filter(
> type T interface{},
> Source Observable(T),
> )(pred func(T) bool) Operator(T, T, Source, FilterObservable(T,
> Source)) {
> return func(source Source) ((FilterObservable(T, Source)))
> {
> return FilterObservable(T, Source){source, pred}
> }
> }
>
> Despite the truth that Source is a type parameter of Filter function, the
> Filter function is actually returning a generic function. Source cannot be
> deduced by only looking at the input parameter of Filter function.
>
> 在 2020年6月24日星期三 UTC+8上午12:56:48,rog写道:
>>
>>
>>
>> On Tue, 23 Jun 2020 at 17:33,  wrote:
>>
>>> Imagine the following function definition, under the current proposal (I
>>> believe this is correct):
>>>
>>>
>>> func (s MyMap(K, V)) DoSomething(k K, v V) (func(type K Hashable) (k K) (V, 
>>> error)) {...}
>>>
>>>
>> I don't think that's quite right. You can't have function values with
>> type parameters.
>>
>> So I think your example could look more like this in practice:
>>
>> func (s MyMap(K, V)) DoSomething(k K, v V) func(K) (V, error) { ... }
>>
>> That doesn't seem too unreasonable to me FWIW. It reads nicely from left
>> to right, and everything except that first (K, V) declaration is just as
>> things are today.
>>
>>   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/2863cb7a-4ba9-46b3-86e7-2043dfa1c9a7o%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/CAJhgacjo_cgYTHqjUKYrYenHnYBe2y1tSupAHUoiMogrz%2Bi7jA%40mail.gmail.com.


Re: [go-nuts] [Generics] Concise generics with package level types

2020-06-23 Thread roger peppe
On Tue, 23 Jun 2020 at 17:33,  wrote:

> Imagine the following function definition, under the current proposal (I
> believe this is correct):
>
>
> func (s MyMap(K, V)) DoSomething(k K, v V) (func(type K Hashable) (k K) (V, 
> error)) {...}
>
>
I don't think that's quite right. You can't have function values with type
parameters.

So I think your example could look more like this in practice:

func (s MyMap(K, V)) DoSomething(k K, v V) func(K) (V, error) { ... }

That doesn't seem too unreasonable to me FWIW. It reads nicely from left to
right, and everything except that first (K, V) declaration is just as
things are today.

  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/CAJhgachc9jF8R7H5TuA5v2OZMpVCd53v7HsNQ9fAJ_%2Bb6XNv8g%40mail.gmail.com.


Re: [go-nuts] Why not use F in generic?

2020-06-23 Thread roger peppe
On Tue, 23 Jun 2020 at 03:04, Ian Lance Taylor  wrote:

> On Mon, Jun 22, 2020 at 6:19 PM 移库海牙客  wrote:
> >
> > I agree the syntax should be more readable and easier to understand. But
> I think the current syntax is less readable.
> > For example:
> >
> > type I2 interface {
> > (I1(int))
> > }
> >
> >
> > type S2 struct {
> > (S1(int))
> > }
> >
> >
> > We must use redundant brackets to keep the syntax right. I don't think
> this is readable and syntax consistent.
> >
> > The new syntax begin with < .It suggests the next name is generic. I
> think that's more readable.
>
> I agree that the syntax for embedding an instantiated type is not great.
>
> But I also think that embedding an instantiated type is a an unusual
> thing to do.  It's not so bad if the syntax for an unusual operation
> doesn't look that great.  It will rarely be seen.
>
> Is there some reason to think that people will often want to embed
> instantiated types?
>

It might not be as uncommon as you think. It'll happen any time that
someone wishes
to embed a container type and add some extra domain-specific methods.

I understand the necessity for the extra bracket in interface types, but I
don't really see that it's needed in struct types. Couldn't we use a
similar approach as for unnamed function parameter types

by
changing gofmt to rewrite:

 type T struct {
F(int)
 }

to:

 type T struct {
 F int
 }

and then later dropping the requirement for the extra brackets?
How many instances of the former are out there in the wild, I wonder.

  cheers,
rog.

> .
> Ian
>
>
> > On Tuesday, June 23, 2020 at 1:53:56 AM UTC+8, Ian Lance Taylor wrote:
> >>
> >> On Mon, Jun 22, 2020 at 10:09 AM James L  wrote:
> >> >
> >> > Have you read other thread which have been answered many times?
> >>
> >> In fairness, this idea is different, because the type comes first.
> >> Since the '<' character will always be the start of an expression, I
> >> think it may be unambiguous.  I think this has been suggested before
> >> also, though I'm not sure where.
> >>
> >> I don't personally like this syntax because it seems to put the cart
> >> before the horse.  In a function call, I would expect to see the Print
> >> function with a type argument int.  This flips the order so that we
> >> see int first, then we see that we are talking about the Print
> >> function.  Even if it could work syntactically, it seems to me to be
> >> less readable.
> >>
> >> The goal in any syntax suggestion should be more than just "this might
> >> work."  It should be "this is more readable and easier to understand."
> >>  And personally I don't think this specific suggestion meets that
> >> goal.
> >>
> >> Thanks for the comment, though.
> >>
> >> Ian
> >>
> >>
> >> > On Tue, 23 Jun 2020 at 12:46 AM,  wrote:
> >> >>
> >> >> I read the new generic draft. And I know F,F[T],F《T》 is
> discarded. I think put the type paremeter in front of the function name may
> be better. No ambiguous and more readable code.
> >> >>
> >> >> func Print(type T)(s []T) {
> >> >>
> >> >> }
> >> >>
> >> >> Print(int)([]int{1, 2, 3})
> >> >>
> >> >> func Print(s []T) {
> >> >>
> >> >> }
> >> >>
> >> >> Print([]int{1, 2, 3})
> >> >>
> >> >>
> >> >>
> >> >> --
> >> >> You received this message because you are subscribed to the Google
> Groups "golang-nuts" group.
> >> >> To unsubscribe from this group and stop receiving emails from it,
> send an email to golan...@googlegroups.com.
> >> >> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/c55ab443-4333-4def-9d9c-6657463a4a75o%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 golan...@googlegroups.com.
> >> > To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/CAHo5hB6-myagSyixYPfghVYBE3DUpQMYSj88%2BjB74hbJvzQApQ%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/9297b725-7fc2-4e23-bd55-763d9bf691f7o%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/CAOyqgcWraiNkaqi5cpTsW4%3D_SZDTOaX7RObd5b6hWYaMVN%3DEQA%40mail.gmail.com
> .
>

-- 

Re: [go-nuts] [generics] constraint for nillable types?

2020-06-23 Thread roger peppe
FWIW I also came across this issue recently in a different context and
similarly wondered if a nillable constraint might be a good idea.

There is a kinda workaround although you won't like it :)

https://go2goplay.golang.org/p/-nDAUVYWuxo



On Tue, 23 Jun 2020 at 05:43, 'Bryan C. Mills' via golang-nuts <
golang-nuts@googlegroups.com> wrote:

> I tried writing a generic “FirstNonNil” function, but got stuck at the "==
> nil" part.
>
> First I thought to maybe add a type list enumerating all of the nillable
> types, but I don't have a way to enumerate all of the possible interface
> types as part of that list, and there is no constraint for “any interface
> type”.
>
> Then I thought I could use a `var zero T` variable and compare `== zero`
> instead of `== nil`. But that doesn't work either: I need the `comparable`
> constraint to get `==`, but not every nillable type is comparable with an
> arbitrary variable (slices, maps, and functions are not).
>
> So it seems that the best I can do is to write a generic `First` function
> and make the caller write out `func (x T) bool { return x != nil }`
> explicitly at every call site. Did I miss a better option?
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/CAKWVi_SED7FvqerjhzX8OBss3MHzbb3aw%2BLOcRcC3Lf3GUZCfw%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/CAJhgacirMen54vZw7SnUHvM2DtADm9fnjF3dMziATnC4WvcmaQ%40mail.gmail.com.


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

2020-06-22 Thread roger peppe
On Mon, 22 Jun 2020 at 22:49, Andrew Werner  wrote:

>
>
> On Monday, June 22, 2020 at 5:42:12 PM UTC-4, rog wrote:
>>
>>
>> Thanks for pointing this out. I'm cool with this approach. I'll update my
 library to utilize it (and consider also adopting the list.List, though I
 do like my freedom to pool list nodes).

>>>
>> Personally, I'd start by re-using list.List, and only use pools if there
>> really is a significant performance benefit to be gained there.
>> If you just need zero-valued elements, I could imagine that sync.Pool
>> might end up slower than just using the GC.
>>
>
> Fair.
>
>
>> Hopefully with aggressive inlining of the specialized type the compiler
 will be able to make the optimizations that it would be able to make if the
 slicing were performed directly on an array.

>>>
>> What optimisations are you thinking of here? Are you concerned that slice
>> operations are too slow?
>>
>
>
> * Bound check elimination
>

I'm not sure how it could do that, given that it's inevitable that an index
is stored in a field with no range limits on it (i guess if you used a
256-element array and a uint8 index, it could, but then it wouldn't work
for other array sizes).

* Avoiding an indirection through the pointer in the slice header would be
> nice
>

Isn't it going to have to indirect through a pointer regardless of whether
it's a slice or an array? The array isn't stored inside the Dequeue struct
itself.

* Compile-time evaluation of len and cap
>

Isn't that just a one-word load of memory that's very likely in the same
cache line as the array-pointer member?
I can't see that this is likely to make a significant performance
difference, but I'd love to see some numbers.

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


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

2020-06-22 Thread roger peppe
> Thanks for pointing this out. I'm cool with this approach. I'll update my
>> library to utilize it (and consider also adopting the list.List, though I
>> do like my freedom to pool list nodes).
>>
>
Personally, I'd start by re-using list.List, and only use pools if there
really is a significant performance benefit to be gained there.
If you just need zero-valued elements, I could imagine that sync.Pool might
end up slower than just using the GC.

Hopefully with aggressive inlining of the specialized type the compiler
>> will be able to make the optimizations that it would be able to make if the
>> slicing were performed directly on an array.
>>
>
What optimisations are you thinking of here? Are you concerned that slice
operations are too slow?

  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/CAJhgacgOFb5ohxCkkJExTcVYKb%2Buf9ZzqDQcUEBymPuKo%2BpO-w%40mail.gmail.com.


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

2020-06-22 Thread roger peppe
On Mon, 22 Jun 2020 at 15:57, Andrew Werner  wrote:

> On Monday, June 22, 2020 at 10:17:01 AM UTC-4, rog wrote
>>
>> On Mon, 22 Jun 2020 at 14:59, Andrew Werner  wrote:
>>
>>> Oh! It’s saying that *B implements the constraint, nifty. Is this idea
>>> in the current proposal?
>>>
>>
>> Yes. See
>> https://go.googlesource.com/proposal/+/refs/heads/master/design/go2draft-type-parameters.md#pointer-methods
>>
>>
>>> I agree that it’ll do the trick in the same way as your second proposal
>>> and my proposal and is even a bit cleaner. That being said, it still seems
>>> worse than having a mechanism to indicate that a type really is an array
>>> and can be syntactically used as such, no?
>>>
>>
>> I'm not sure. ISTM that there is a reasonable workaround and that the
>> alternative might significantly complicate the generics proposal. The
>> authors aren't trying to address every possible generics use case,
>> especially when it's possible to work around the problem, and I like that
>> approach :)
>>
>
> Cool, I'm on board with this view. I'll adopt this approach and see how it
> feels. Hopefully with aggressive inlining the trip through the compiler
> will be able to optimize the access as though the array were being indexes
> directly.
>

I wouldn't necessarily expect aggressive inlining of generic calls. This
isn't C++, and the direct corollary of aggressive inlining is code bloat
from excessive specialisation. I'm expecting performance somewhat better
than interface values because the calls can be direct, but not necessarily
as fast as if everything was fully specialised. All this is still to be
decided though, of course.


> I think this is already addressed in the current design
 .
 You are allowed to directly embed type-parameters, and they have the 
 name
 of the template argument (rather than its instantiated value).

>>> Cool, I'll try it out. I found it not compiling with `go tool go2go`
>>> in my first pass. Maybe I was holding it wrong.
>>>
>>
> I'm just re-visiting this now and I wonder if it's what I want. While
> indeed you can embed a type parameter, it's not clear that you can embed a
> type that is parameterized on a type-parameter. For example the following
> example is definitely kosher but the one after it is not as obviously
> kosher. I don't think I was clear enough in my problem statement but I'm
> requesting that the latter be allowed and that the embedded field in that
> case be `List`. Am I still misunderstanding something?
>
> type Foo(type T) struct {
>T // Ok
>// ...
> }
>
> type Foo(type T) struct {
>list.List(T) // Seemingly not ok
>// ...
> }
>
> This issue is addressed here
> .
> Because of a grammatical ambiguity, you have to do:
>

 type Foo(type T) struct{
 (list.List(T))
 ...
 }

  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/CAJhgacjGRiVDwMmTLh_6Jw0EMR1%2B%2B3MQ-QAEDDFJAhA2bApgQg%40mail.gmail.com.


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

2020-06-22 Thread roger peppe
On Mon, 22 Jun 2020 at 14:59, Andrew Werner  wrote:

>
>
> On Mon, Jun 22, 2020 at 9:45 AM roger peppe  wrote:
>
>>
>>
>> On Mon, 22 Jun 2020 at 14:26, Andrew Werner  wrote:
>>
>>> Hey Rog,
>>>
>>> I think I sent you a private reply earlier. My bad. I now see what
>>> you're proposing in the first proposal think it makes a lot of sense.
>>>
>>> The thing that I think I had missed was this piece of magic:
>>> // New returns a new Dequeue instance using B as the block storage
>>> backing.
>>> func New(type T interface{}, *B Block(T))() *Dequeue(T) {
>>>
>>> One concern I have here is that the `Slice` method is on the array
>>> itself so it's possible that invoking it will copy the entire array to the
>>> stack. Does that concern you?
>>>
>>
>> It won't copy the array because it's a pointer method (that's what the
>> "*B" means).
>> In fact it *must not* copy the array because then it couldn't return a
>> reference to it.
>>
>
> Oh! It’s saying that *B implements the constraint, nifty. Is this idea in
> the current proposal?
>

Yes. See
https://go.googlesource.com/proposal/+/refs/heads/master/design/go2draft-type-parameters.md#pointer-methods


> I agree that it’ll do the trick in the same way as your second proposal
> and my proposal and is even a bit cleaner. That being said, it still seems
> worse than having a mechanism to indicate that a type really is an array
> and can be syntactically used as such, no?
>

I'm not sure. ISTM that there is a reasonable workaround and that the
alternative might significantly complicate the generics proposal. The
authors aren't trying to address every possible generics use case,
especially when it's possible to work around the problem, and I like that
approach :)

I suppose if the Slice method gets reasonably inclined the compiler could
> do good things.
>
> I think I’m in favor of this proposal in addition to my proposal that
> allows a type to be declared as an array and to thus be used syntactically
> as an array.
>
>
>> The second proposal feels almost identical to what I proposed. Can you
>>> help me understand how it differs?
>>>
>>
>> It is indeed a similar approach. The main difference (beyond the somewhat
>> simpler dequeue implementation itself) is that my New method returns a
>> concrete type, not an interface. This means that it's easier to jump to the
>> definition of its method implementations, potentially more performant
>> because it can use direct rather than indirect calls (*), and arguably more
>> idiomatic Go. It also means it's possible to add more methods without
>> breaking backward compatibility, which is a significant benefit in my view.
>>
>>   cheers,
>> rog.
>>
>> (*) you'll still get *some* indirect calls, amortised over the buffer
>> size.
>>
>
> Ack, sure, thanks for clarifying. No quibbles from me on this front.
>
> FWIW the Alloc* methods came from some experience with these data
> structures where I want to decode a stream of structs off the network or
> something so I want pointers to zero values to then pass to Decode or
> Unmarshal. I’ll admit it feels weird without the context.
>

Note that with the concrete type return, it would be possible to add Alloc*
methods at a later stage without breaking backward compatibility.

As noted in a comment in my code, I think that it would be nice to add
similar methods to the list package too - they wouldn't have been useful
before with the interface{} value approach, but definitely are now (for
example you could have an in-element mutex).

  cheers,
rog.



>
>>
>>>
>>> On Monday, June 22, 2020 at 7:58:43 AM UTC-4, rog wrote:
>>>>
>>>> Thanks for the interesting use case, Andrew!
>>>>
>>>> I've experimented with a slightly different approach:
>>>>
>>>> https://go2goplay.golang.org/p/AkqzbWmpj6t
>>>>
>>>> It expects the caller to implement a method on the array to get a
>>>> reference to the
>>>> underlying storage, but that's fairly trivial to implement.
>>>>
>>>> I've built it on top of the "list" package from the stdlib (available
>>>> in the dev.go2go branch under src/cmd/go2go/testdata/go2path).
>>>>
>>>> I think it has the potential to be a bit more performant as the
>>>> type-hiding abstraction (Block in my example) is inside the static type, so
>>>> most calls can be direct rather than indirect.
>>>>
>>>> It's *almost* possible to ma

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

2020-06-22 Thread roger peppe
On Mon, 22 Jun 2020 at 14:26, Andrew Werner  wrote:

> Hey Rog,
>
> I think I sent you a private reply earlier. My bad. I now see what you're
> proposing in the first proposal think it makes a lot of sense.
>
> The thing that I think I had missed was this piece of magic:
> // New returns a new Dequeue instance using B as the block storage backing.
> func New(type T interface{}, *B Block(T))() *Dequeue(T) {
>
> One concern I have here is that the `Slice` method is on the array itself
> so it's possible that invoking it will copy the entire array to the stack.
> Does that concern you?
>

It won't copy the array because it's a pointer method (that's what the "*B"
means).
In fact it *must not* copy the array because then it couldn't return a
reference to it.

The second proposal feels almost identical to what I proposed. Can you help
> me understand how it differs?
>

It is indeed a similar approach. The main difference (beyond the somewhat
simpler dequeue implementation itself) is that my New method returns a
concrete type, not an interface. This means that it's easier to jump to the
definition of its method implementations, potentially more performant
because it can use direct rather than indirect calls (*), and arguably more
idiomatic Go. It also means it's possible to add more methods without
breaking backward compatibility, which is a significant benefit in my view.

  cheers,
rog.

(*) you'll still get *some* indirect calls, amortised over the buffer size.


>
> On Monday, June 22, 2020 at 7:58:43 AM UTC-4, rog wrote:
>>
>> Thanks for the interesting use case, Andrew!
>>
>> I've experimented with a slightly different approach:
>>
>> https://go2goplay.golang.org/p/AkqzbWmpj6t
>>
>> It expects the caller to implement a method on the array to get a
>> reference to the
>> underlying storage, but that's fairly trivial to implement.
>>
>> I've built it on top of the "list" package from the stdlib (available in
>> the dev.go2go branch under src/cmd/go2go/testdata/go2path).
>>
>> I think it has the potential to be a bit more performant as the
>> type-hiding abstraction (Block in my example) is inside the static type, so
>> most calls can be direct rather than indirect.
>>
>> It's *almost* possible to make this implementation use a slice-based
>> implementation of Block too (thus allowing dynamically specified block
>> sizes at the cost of an extra indirection through the linked list node).
>> That's not possible because the pointer method is invoked on the zero-value
>> of the type, so without using a global variable, there's no way for the
>> method to find out the required block size. A way to work around that is to
>> use another level of indirection instead of using pointer methods directly:
>>
>> https://go2goplay.golang.org/p/nMreEMpqXd1
>>
>> This makes me wonder whether the pointer methods restriction in the
>> generics draft proposal might not be unnecessary and perhaps not
>> necessarily a good idea. ISTM that the only reason for restricting methods
>> to pointer-only is so that they can be called on zero values, and that
>> necessarily restricts the available parameterisation to static-only (or
>> using global variables). I suspect that might turn out to be an
>> anti-pattern. Instead, using function or interface value that operates on
>> the pointer is strictly more general, I think, and doesn't suffer from that
>> problem.
>>
>>   cheers,
>> rog.
>>
>>
>> On Sun, 21 Jun 2020 at 17:43, Andrew Werner  wrote:
>>
>>> Thanks for the reply! If I read it correctly, it is already possible to
>>> specify a type constraint as an Array of a given size and so the first part
>>> of the "What I might have expected" actually does work. I noticed that it
>>> works in that it works as a type constraint but I found that types
>>> constrained that way do not support indexing or slicing. Perhaps that's
>>> just a limitation of the prototype and not the proposal.
>>>
>>> The other thing that I think I'm proposing (thanks for the correction)
>>> is a way to represent all arrays of a given type:
>>>
>>> type Array(type T) interface {
>>> type [...]T
>>> }
>>>
>>> Thanks for dealing with my very long-winded way of saying that.
>>>
>>> On Sunday, June 21, 2020 at 12:35:53 PM UTC-4, David Finkel wrote:



 On Sat, Jun 20, 2020 at 1:22 AM Andrew Werner 
 wrote:

> [The body of this email is a duplication of the README in 
> https://github.com/ajwerner/go2dequeue/
> which also contains the sample implementation]
>
> Exercise building a dequeue with the go2 Type Parameter Draft
>
> This project is an exploration with the go2go / Type Parameters -
> Design Draft
> 
> with an eye towards block-based data structures which promote access
> locality.
>
> Such data structures traditionally utilize blocks of objects laid out
> contiguously in memory. 

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

2020-06-22 Thread roger peppe
Thanks for the interesting use case, Andrew!

I've experimented with a slightly different approach:

https://go2goplay.golang.org/p/AkqzbWmpj6t

It expects the caller to implement a method on the array to get a reference
to the
underlying storage, but that's fairly trivial to implement.

I've built it on top of the "list" package from the stdlib (available in
the dev.go2go branch under src/cmd/go2go/testdata/go2path).

I think it has the potential to be a bit more performant as the type-hiding
abstraction (Block in my example) is inside the static type, so most calls
can be direct rather than indirect.

It's *almost* possible to make this implementation use a slice-based
implementation of Block too (thus allowing dynamically specified block
sizes at the cost of an extra indirection through the linked list node).
That's not possible because the pointer method is invoked on the zero-value
of the type, so without using a global variable, there's no way for the
method to find out the required block size. A way to work around that is to
use another level of indirection instead of using pointer methods directly:

https://go2goplay.golang.org/p/nMreEMpqXd1

This makes me wonder whether the pointer methods restriction in the
generics draft proposal might not be unnecessary and perhaps not
necessarily a good idea. ISTM that the only reason for restricting methods
to pointer-only is so that they can be called on zero values, and that
necessarily restricts the available parameterisation to static-only (or
using global variables). I suspect that might turn out to be an
anti-pattern. Instead, using function or interface value that operates on
the pointer is strictly more general, I think, and doesn't suffer from that
problem.

  cheers,
rog.


On Sun, 21 Jun 2020 at 17:43, Andrew Werner  wrote:

> Thanks for the reply! If I read it correctly, it is already possible to
> specify a type constraint as an Array of a given size and so the first part
> of the "What I might have expected" actually does work. I noticed that it
> works in that it works as a type constraint but I found that types
> constrained that way do not support indexing or slicing. Perhaps that's
> just a limitation of the prototype and not the proposal.
>
> The other thing that I think I'm proposing (thanks for the correction) is
> a way to represent all arrays of a given type:
>
> type Array(type T) interface {
> type [...]T
> }
>
> Thanks for dealing with my very long-winded way of saying that.
>
> On Sunday, June 21, 2020 at 12:35:53 PM UTC-4, David Finkel wrote:
>>
>>
>>
>> On Sat, Jun 20, 2020 at 1:22 AM Andrew Werner  wrote:
>>
>>> [The body of this email is a duplication of the README in 
>>> https://github.com/ajwerner/go2dequeue/
>>> which also contains the sample implementation]
>>>
>>> Exercise building a dequeue with the go2 Type Parameter Draft
>>>
>>> This project is an exploration with the go2go / Type Parameters -
>>> Design Draft
>>> 
>>> with an eye towards block-based data structures which promote access
>>> locality.
>>>
>>> Such data structures traditionally utilize blocks of objects laid out
>>> contiguously in memory. In go, today, one generally specializes such data
>>> structures which are performance critical. This is especially important in
>>> the case of reducing allocations which occur on critical paths. Using a
>>> sync.Pool can help with allocations in some cases but can be clunky to use
>>> and, well, do create more pointers for GC to worry about and don't have the
>>> access locality.
>>>
>>> Whether it's really important to have data structures which include
>>> arrays of other data structures laid out contiguously in RAM is really
>>> important is sort of orthogonal. Let's just assume that it is for now and
>>> look at how we'd do it. We only need to consider rejecting the importance
>>> of this case if we can't find a good solution or idiom to support it. The
>>> google/btree  library README links
>>> this Google Open Source Blog Post on block-based container
>>> 
>>> performance indicating it does matter. The interesting thing about that
>>> library is it hardly gets the access locality of the C++ library in the
>>> blog post it references.
>>>
>>> The challenge this library explores is to layout blocks in structures
>>> contiguously in RAM while allowing the user to have some control over that
>>> block size.
>>> This example
>>>
>>> The approach this experiment takes is to allow the users to specify the
>>> block size by providing a function to map an array type to a slice. The
>>> allows the blocks to contain a slice which references the array. The
>>> overhead to maintain the slice header is 3 words but the cost is probably
>>> less in memory and more in the optimizations the compiler will be 

Re: [go-nuts] Re: [generics] (again). Type inference is somewhat weak

2020-06-18 Thread roger peppe
Yes, I agree. It seems to have trouble inferring types when the argument is
a generic interface type.
Here's a simpler example: https://go2goplay.golang.org/p/3-aVhD6Y9R2
I think this is probably https://github.com/golang/go/issues/39661

  cheers,
rog.

On Thu, 18 Jun 2020 at 02:14, Denis Cheremisov 
wrote:

> Better example. A method to request for exacly one element from the gRPC
> bistream. A thing that is frequently needed when there're lots of bistream
> gRPC methods.
>
> https://go2goplay.golang.org/p/RQEyhRRQb0p
>
> IRL I would need to call it as
>
> resp, err := proto.ReadOne(service.Service_MethodClient,
> service.MethodRequest, service.MethodResponse)(ctx, client.Method,
> {
> …
> })
>
> instead of simple to read
>
> resp, err := proto.ReadOne(ctx, client.Method, {
> …
> })
>
> среда, 17 июня 2020 г., 19:43:35 UTC+3 пользователь Denis Cheremisov
> написал:
>>
>> https://go2goplay.golang.org/p/ObL79WVHDjw
>>
>> Need to write types explicitly although all the info needed is easily
>> accessible:
>>
>> fmt.Println(IsOK(*commonResponse, *commonError)(r))
>>
>> What I am sure is I will keep using a code generator instead of this
>> monstrosity.
>>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/6bfdcc4c-dca8-4051-b89c-65274c2f6982o%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/CAJhgacj-5v%2BvTa0zx6xU1ir_ebJC8mnYQY7HYMU0YiLYtSevJA%40mail.gmail.com.


  1   2   3   4   5   >