[go-nuts] Re: YAML Unmarshal changes keys

2022-04-10 Thread Sam Hughes
I skipped over to that package, and the doc says it converts from yaml to 
json, and the marshals/unmarshals. I tried changing your snippet to use 
struct tags with the key name as "json" instead of "yaml", and it 
immediately behaved as expected: https://goplay.tools/snippet/PSZtr1YErD8

While you're fine to use it like you are, the package you're using is a 
wrapper around another tool, pkg.go.dev/gopkg.in/yaml.v2, using that tool 
to convert to/from json, and then using encode/json to marshal/unmarshal. 
The benefit would be using common marshal/unmarshal handlers and one set of 
struct tags. Meanwhile, you're not interacting with both yaml and json, so 
I suggest actually changing the tool you're using to support yaml directly.

1. Simple fix: replace `yaml:""` with `json:""`
2. Better fix that might break some code: use gopkg.in/yaml.v2 instead 
of github.com/ghodss/yaml, to avoid unexpected behavior, such as what you 
observed.

On Sunday, April 10, 2022 at 11:53:57 PM UTC-5 vika...@gmail.com wrote:

> I am new to GoLang and looking to join two keys (rules) from two different 
> Yamls.
>
> I have been able to join the keys but I found that Unmarshal changes the 
> keys (example apiVersion to APIVersion, and kind to Kind).
>
> Overall, my goal is to have a valid Kubernetes YAML manifest. This is what 
> I have attempted so far https://goplay.tools/snippet/zWYDjnTeA0Q 
>
> ## 
> package main
>
> import (
> "fmt"
>
> "github.com/InVisionApp/conjungo"
> "github.com/ghodss/yaml"
> )
>
> type ClusterRole struct {
> APIVersion string `yaml:"apiVersion"`
> Kind string `yaml:"kind"`
> Metadata struct {
> Name string `yaml:"name"`
> } `yaml:"metadata"`
> Rules []struct {
> APIGroups []string `yaml:"apiGroups"`
> Resources []string `yaml:"resources"`
> Verbs []string `yaml:"verbs"`
> } `yaml:"rules"`
> }
>
> func main() {
>
> yaml1 := `
> ---
> apiVersion: rbac.authorization.k8s.io/v1
> kind: ClusterRole
> metadata:
> name: role1
> rules:
> - apiGroups:
> - ""
> resources:
> - services
> verbs:
> - create
> - delete
> - apiGroups:
> - apiregistration.k8s.io
> resources:
> - apiservices
> verbs:
> - create
> - delete
> `
>
> yaml2 := `
> ---
> apiVersion: rbac.authorization.k8s.io/v1
> kind: ClusterRole
> metadata:
> name: role2
> rules:
> - apiGroups:
> - ""
> resources:
> - secrets
> - events.k8s.io
> verbs:
> - list
> - watch
> - apiGroups:
> - metrics.k8s.io
> resources:
> - nodes
> - bindings
> verbs:
> - get
> `
>
> var role1 ClusterRole
> yaml.Unmarshal([]byte(yaml1), )
> fmt.Printf("\n## ROLE1\n %v", role1)
>
> var role2 ClusterRole
> yaml.Unmarshal([]byte(yaml2), )
> fmt.Printf("\n\n## ROLE2\n %v", role2)
>
> conjungo.Merge(, role2, nil)
>
> // Struct to Marshal
> y, err := yaml.Marshal(role1)
> if err != nil {
> fmt.Printf("\nerr: %v\n", err)
> return
> }
> fmt.Printf("\n\n## MERGED ROLE\n %v", string(y))
> }
>
>

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


[go-nuts] YAML Unmarshal changes keys

2022-04-10 Thread vika...@gmail.com
I am new to GoLang and looking to join two keys (rules) from two different 
Yamls.

I have been able to join the keys but I found that Unmarshal changes the 
keys (example apiVersion to APIVersion, and kind to Kind).

Overall, my goal is to have a valid Kubernetes YAML manifest. This is what 
I have attempted so far https://goplay.tools/snippet/zWYDjnTeA0Q 

## 
package main

import (
"fmt"

"github.com/InVisionApp/conjungo"
"github.com/ghodss/yaml"
)

type ClusterRole struct {
APIVersion string `yaml:"apiVersion"`
Kind string `yaml:"kind"`
Metadata struct {
Name string `yaml:"name"`
} `yaml:"metadata"`
Rules []struct {
APIGroups []string `yaml:"apiGroups"`
Resources []string `yaml:"resources"`
Verbs []string `yaml:"verbs"`
} `yaml:"rules"`
}

func main() {

yaml1 := `
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: role1
rules:
- apiGroups:
- ""
resources:
- services
verbs:
- create
- delete
- apiGroups:
- apiregistration.k8s.io
resources:
- apiservices
verbs:
- create
- delete
`

yaml2 := `
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: role2
rules:
- apiGroups:
- ""
resources:
- secrets
- events.k8s.io
verbs:
- list
- watch
- apiGroups:
- metrics.k8s.io
resources:
- nodes
- bindings
verbs:
- get
`

var role1 ClusterRole
yaml.Unmarshal([]byte(yaml1), )
fmt.Printf("\n## ROLE1\n %v", role1)

var role2 ClusterRole
yaml.Unmarshal([]byte(yaml2), )
fmt.Printf("\n\n## ROLE2\n %v", role2)

conjungo.Merge(, role2, nil)

// Struct to Marshal
y, err := yaml.Marshal(role1)
if err != nil {
fmt.Printf("\nerr: %v\n", err)
return
}
fmt.Printf("\n\n## MERGED ROLE\n %v", string(y))
}

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


[go-nuts] Re: Why is Go fun?

2022-04-10 Thread ben...@gmail.com
Reading the spec probably isn't the best way to experience the "fun" in any 
case. (Though the spec is worth a read once you've use the language a bit 
-- as far as specs go, it's concise and readable.)

"Fun" is quite a personal thing, but similar people often have similar 
experiences, so I'll take a stab at answering from my perspective:

Go is fun because the language is:

* Easy to learn: I learned it coming from years of Python and some C. You 
can be productive in Go in a couple of weeks. My first medium-sized project 
in Go was porting a web backend from Python to Go, and I found it a lot of 
fun (https://benhoyt.com/writings/learning-go/).
* Builds fast: even large programs compile and build in seconds (not 
minutes or hours). Go caches builds of packages that haven't changed, 
meaning the time from editing code to running it is very short, sometimes 
close to instantaneous.
* Runs fast: Go compiles to reasonably fast native code. Coming from an 
interpreted language like Python, this is great when you need to do 
something like loop over the characters in a string.
* Solid stdlib: enough quality stuff in the standard library to get a lot 
done quickly.
* Concrete focus: good Go code (like the stdlib) tends toward concrete 
types and simple patterns rather than abstract interfaces, factories, and 
deep nesting.
* Excellent tooling: "go build" builds your project with no ceremony. "go 
test ./..." runs all your tests. "go run" builds and runs a program in one 
step. The caches for the above just work.

The above is why Go is fun for me. That leaves out Go's other unique 
features (though arguably these are more "useful" than "fun"):

* Unique take on types and interfaces that doesn't result in an inheritance 
mess.
* Statically typed. For medium-sized to large projects, this really helps 
reassure you when refactoring (compared to Python, JavaScript, and so on).
* Generic slices and maps: right from Go 1 (that is, pre-Go 1.18-generics), 
Go always had type-safe growable arrays and hash tables, two of the most 
useful data structures.
* (Some) control over memory allocation. You don't usually have to worry 
about it, but when you need to reduce allocations, you can: make(), reuse 
buffers, and so on.
* Goroutines and channels. Concurrency is never easy, but at least with Go 
the primitives are built into the language and relatively straight-forward 
to learn.
* The above means functions aren't colored -- all libraries are sync, use 
"go" to make them async. See: 
https://journal.stuffwithstuff.com/2015/02/01/what-color-is-your-function/
* io.Reader and io.Writer. These are simple but amazing tools for composing 
I/O (I'm comparing to things like the vague mess that is Python's 
"file-like objects").
* Go modules. Relatively new in the scheme of things, but it's a really 
good system. (It's also well built, for example: 
https://go.dev/blog/supply-chain)
* The Go community's focus on few dependencies. So much better than the 
pain and fragility of a node_modules directory with 1500 entries.
* Easily-deployable binaries. Instead of having to ship around a big 
runtime and stdlib, to deploy a Go program, you just copy the binary to the 
target machine. (And Go 1.16's "embed" means you can even include your 
static files, templates, and so on.)
* Incredible cross-compilation. Just set two environment variables (GOOS 
and GOARCH) and type "go build", and have a macOS or Windows binary a few 
seconds later.

I'm sure others have their own lists...

-Ben


On Monday, April 11, 2022 at 8:53:55 AM UTC+12 kziem...@gmail.com wrote:

> Hello,
>
> I lack a motivation to read Go spec (long story) and I seek few stories 
> along the line "Go is fun", which it is, to motivate myself. Google didn't 
> give me any results, maybe you can tell me few reasons, why Go is fun?
>
> I feel that it is fun, but can't tell why.
>
> Best,
> Kamil Ziemian
>

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


Re: [go-nuts] Packages for Accessing .a Archives?

2022-04-10 Thread 'wagner riffel' via golang-nuts
On Sun Apr 10, 2022 at 4:23 AM CEST, jlfo...@berkeley.edu wrote:
> Other than what's in the Go distribution, I haven't been able to find any
> packages for accessing .a archives. Is there anything else out there?
> Google wasn't helpful.
>
> Cordially,
> Jon Forrest
>

I found these using https://pkg.go.dev/search?q=ar

https://pkg.go.dev/github.com/mkrautz/goar
https://pkg.go.dev/github.com/blakesmith/ar
https://pkg.go.dev/github.com/laher/argo/ar

-w

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


[go-nuts] Constant CPU usage on an idle HTTP server from Go 1.17

2022-04-10 Thread Santiago Corredoira
Hi,

On Linux, if I compile and run this simple program:

package main

import (
 "fmt"
 "net/http"
 "time"
)

type x struct{}

func (x) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 w.Write([]byte(""))
}

func main() {
sp := {
 ReadHeaderTimeout: 5 * time.Second,
 ReadTimeout: 5 * time.Second,
 WriteTimeout: 5 * time.Second,
 IdleTimeout: 30 * time.Second,
 Addr: ":8080",
 Handler: x{},
}

 fmt.Println(sp.ListenAndServe())
}

After a while I start to see constant CPU activity (1% to 7%) even when the 
server is idle.

If I run "sudo strace -f -c -p " I get constant very fast calls like:

[pid 131277] 23:42:16 nanosleep({tv_sec=0, tv_nsec=1000}, NULL) = 0
[pid 131277] 23:42:16 nanosleep({tv_sec=0, tv_nsec=1000}, NULL) = 0
[pid 131277] 23:42:16 nanosleep({tv_sec=0, tv_nsec=1000}, NULL) = 0
[pid 131277] 23:42:16 nanosleep({tv_sec=0, tv_nsec=1000}, NULL) = 0
[pid 131277] 23:42:16 nanosleep({tv_sec=0, tv_nsec=1000}, NULL) = 0


It never stops. Sometimes the CPU goes to 100% for a while and then go back 
down to 1%.. This happens only in one or two cores.

This doesn't happen with Go 1.16. I have been checking all versions and it 
starts in Go 1.17

If I run the program with go run instead of compiling and running the 
binary, I can't reproduce it.

Sometimes it starts after a couple of http calls and sometimes I do a few 
"wrk -d2 http://localhost:8080; calls to trigger it (wrk is a web stress 
tool). But as soon as it starts making the nanosleep calls, it doesn't 
stop, no matter how long the server is iddle.

If I remove the timeout values or set them to a short period, like one 
second for example, I am also not able to reproduce it. But with longer 
values it happens very quickly. I am surprised of not seing it reported.

Do you know what can be going on?

Thank you!

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


Re: [go-nuts] float exactness

2022-04-10 Thread 'wagner riffel' via golang-nuts
On Sat Apr 9, 2022 at 3:56 PM CEST, 'Jack Li' via golang-nuts wrote:
> Why literal operation is exact, variable is not?
>
> fmt.Println(0.1 + 0.2) // 0.3 exactly
> fmt.Println(x + y) // 0.30004
>

Both aren't exact because floats can't represent 0.3 exactly, they
differ because literals and constants expressions have arbitrary
precision (http://golang.org/ref/spec/#Constants), so "0.1" and "0.2"
in "0.1 + 0.2" are exact, then when the exact "0.3" result is
converted to a float64 it becomes the closest possible, You can check
this if you ask to print with more precision

x, y := 0.1, 0.2
fmt.Printf("%.17f...\n", 0.1+0.2) // 0.2...
fmt.Printf("%.17f...\n", x+y) // 0.30004...

https://go.dev/play/p/2qSfoCZGaD6

-w

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


[go-nuts] Why is Go fun?

2022-04-10 Thread Kamil Ziemian
Hello,

I lack a motivation to read Go spec (long story) and I seek few stories 
along the line "Go is fun", which it is, to motivate myself. Google didn't 
give me any results, maybe you can tell me few reasons, why Go is fun?

I feel that it is fun, but can't tell why.

Best,
Kamil Ziemian

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


Re: [go-nuts] Dynamically loading custom passes with gollvm?

2022-04-10 Thread Balamurugan Marimuthu
Yes, something like that! I basically want to run my custom pass as I 
compile using 'go build'

 But looks like llvm-goc doesn't support the -Xclang option




*$ go build -gccgoflags="-Xclang -load -Xclang 
../passes/FunctionInsertPass.so" cache_main.go# 
command-line-arguments/gollvm/install/bin/llvm-goc: error: unrecognized 
command line option '-Xclang'/gollvm/install/bin/llvm-goc: error: 
unrecognized command line option '-Xclang'*

Is there a way to load my custom pass as part of 'go build'?

Thanks!

On Sunday, April 10, 2022 at 12:14:34 AM UTC-4 Ian Lance Taylor wrote:

> On Sat, Apr 9, 2022 at 8:28 PM Balamurugan Marimuthu
>  wrote:
> >
> > I see I can invoke the following and see the steps 'go build' is doing.
> >
> > % go build -work -x mypackage.go 1> transcript.txt 2>&1
> >
> > I struggle to understand how can I load my custom pass created as a 
> shared library?
> >
> > I was looking for something like this which is done with Clang:
> > clang -Xclang -load -Xclang build/skeleton/libSkeletonPass.* something.c
> >
> > Is my understanding correct? Any help/pointers will be really helpful.
>
> Perhaps you are looking for something like
>
> go build -gccgoflags="-Xclang -load -Xclang
> build/skeleton/libSkeletonPass.*"
>
> 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/9a976aca-4c5d-4074-a19d-f843e8b5ca63n%40googlegroups.com.


Re: [go-nuts] Self-referential generics?

2022-04-10 Thread Shawn Smith
Thanks! This seems obvious now just looking at it, but it was stumping me.

I might add for someone that may see this later, in the future it *might*
not be needed to do it this way, if all you really just want {Int | Float |
Rat} as future versions are supposed to let us use methods in such
constrained types if a method is present in all the types, like Cmp in this
case, but I'm not sure if it clear that >1.18 will handle this particular
case where it is only the same method signature if you note that the param
type is the same as the method receiver type.

On Sun, Apr 10, 2022 at 11:23 AM Axel Wagner 
wrote:

> You can use
>
> type Comparable[T any] interface {
> Cmp(other T) int
> }
>
> then *big.Int implements `Comparable[*big.Int]` and you can write
>
> func cmpSort[T Comparable[T]](x []C) { … }
>
> On Sun, Apr 10, 2022 at 7:48 PM Shawn Smith  wrote:
>
>> // ... imagine some comparison sort algorithm
>>
>> func cmpSort[C Cmpable](x []C) {
>> for i, val := range x {
>> if i == 0 {
>> continue
>> }
>> _ = val.Cmp(x[i-1])
>> }
>> }
>>
>> // Cmpable should include big.Int, big.Float, big.Rat, by virtue of their
>> Cmp methods. So how do i define this better?
>>
>> type Cmpable interface {
>> Cmp(other any) int
>> }
>> // TODO: how do i replace "any" with "this type". "Cmpable" doesn't work
>> as that would be any Cmpable, not THIS Cmpable.
>>
>> --
>> You received this message because you are subscribed to the Google Groups
>> "golang-nuts" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to golang-nuts+unsubscr...@googlegroups.com.
>> To view this discussion on the web visit
>> https://groups.google.com/d/msgid/golang-nuts/4f167deb-bf63-43db-9ec9-c4c451c14d09n%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/CAMC8FUo%2BCA9ODLz%3D6crU8Xn-gww%3Dadcc0EmZ8LPRsocb4mJ8YQ%40mail.gmail.com.


Re: [go-nuts] Generic arguments in recursive functions

2022-04-10 Thread Ian Lance Taylor
On Sun, Apr 10, 2022, 11:42 AM Aidan Hahn  wrote:

> Hello Ian,
>
> I think some of your confusion may be because the function is poorly
> named. In some cases the Node generic may store another Node in the generic
> Inner field.
> In this case I want my preorder traversal to also traverse the list in the
> Inner field. "TreePreTraverse" would be a better name.
>
> func (n *Node[any]) TreePreTraverse(f func(*Node[any])) {
>


Maybe I didn't emphasize this, but don't write Node[any].  That doesn't
make sense.  That is saying that the type parameter is named "any".  Write
Node[T] or something similar.

Ian



tmpN := interface{}(n)
> if tmpN, ok := tmpN.(*Node[*Node[any]]); ok {
> tmpN.Inner.TreePreTraverse(f)
> } else {
> f(n)
> }
>
> if n.Next != nil {
> n.Next.TreePreTraverse(f)
> }
> }
>
> Additionally, I notice that you set the "Next" field to *Node[T] mirroring
> the type of the parent Node, but part of my goal with this exercise is to
> be able to have a list of elements of varying type. If I set the generic
> type for the Next field to 'T' then the list has to be homogeneous.
>
> Ignoring the weird corner case, I am just wondering why f, unchanged,
> cannot be passed into a recursion of the function that it is an argument to.
>
> Thanks,
> Ava
> On Saturday, April 9, 2022 at 9:13:31 PM UTC-7 Ian Lance Taylor wrote:
>
>> On Sat, Apr 9, 2022 at 8:28 PM Aidan Hahn  wrote:
>> >
>> > I am playing with the generics that were added in go 1.18 and noticed
>> an odd discrepancy that I have not been able to find an authoritative
>> answer to. Consider the following data type, as well as the function
>> defined for it:
>> >
>> > type Node[T any] struct {
>> > Inner T
>> > Next *Node[any]
>> > }
>> >
>> > func (n *Node[any]) ListPreTraverse(f func(*Node[any])) {
>> > tmpN := interface{}(n)
>> > if tmpN, ok := tmpN.(*Node[*Node[any]]); ok {
>> > tmpN.Inner.ListPreTraverse(f)
>> > } else {
>> > f(n)
>> > }
>> > n.Next.ListPreTraverse(f)
>> > }
>> >
>> > This function is a simple attempt to iterate across a generic linked
>> list and call a function on each node in the list (although in this case it
>> may behave more like a tree if inner stores another node). When I went to
>> compile this code I encountered the following error:
>> >
>> > test.go:64:25: cannot use f (variable of type func(*Node[any])) as type
>> func(*Node[any]) in argument to n.Next.ListPreTraverse
>> >
>> > To me at least it seems that all the information to validate that the
>> argument fits the type specified in the function call is there, defined in
>> the function header. What am I missing?
>>
>> The error message is confusing because the "any" used in
>> ListPreTraverse is shadowing the "any" used in Node. See
>> https://go.dev/doc/faq#types_in_method_declaration. You want to write
>>
>> func (n *Node[T]) ListPreTraverse(f func(*Node[T])) {
>>
>> But then you will see that your code has an instantiation cycle,
>> violating the restriction described at
>>
>> https://go.googlesource.com/proposal/+/refs/heads/master/design/43651-type-parameters.md#generic-types:
>>
>> "A generic type can refer to itself in cases where a type can
>> ordinarily refer to itself, but when it does so the type arguments
>> must be the type parameters, listed in the same order. This
>> restriction prevents infinite recursion of type instantiation."
>>
>> I don't really understand what you are trying to do here. The type
>> assertion doesn't make sense to me. Perhaps this is the code you
>> want:
>>
>> type Node[T any] struct {
>> Inner T
>> Next *Node[T]
>> }
>>
>> func (n *Node[T]) ListPreTraverse(f func(*Node[T])) {
>> f(n)
>> if n.Next != nil {
>> n.Next.ListPreTraverse(f)
>> }
>> }
>>
>> 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/019beabf-a1f5-4aeb-96d4-c121ae3c2252n%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/CAOyqgcX2gGAsJ_W%3D36RU%2BfwZO54DFY6tNGrj8RB-fV75%3D_T-sg%40mail.gmail.com.


Re: [go-nuts] Generic arguments in recursive functions

2022-04-10 Thread Aidan Hahn
Hello Ian,

I think some of your confusion may be because the function is poorly named. 
In some cases the Node generic may store another Node in the generic Inner 
field.
In this case I want my preorder traversal to also traverse the list in the 
Inner field. "TreePreTraverse" would be a better name.

func (n *Node[any]) TreePreTraverse(f func(*Node[any])) {
tmpN := interface{}(n)
if tmpN, ok := tmpN.(*Node[*Node[any]]); ok {
tmpN.Inner.TreePreTraverse(f)
} else {
f(n)
}

if n.Next != nil {
n.Next.TreePreTraverse(f)
}
}

Additionally, I notice that you set the "Next" field to *Node[T] mirroring 
the type of the parent Node, but part of my goal with this exercise is to 
be able to have a list of elements of varying type. If I set the generic 
type for the Next field to 'T' then the list has to be homogeneous.

Ignoring the weird corner case, I am just wondering why f, unchanged, 
cannot be passed into a recursion of the function that it is an argument to.

Thanks,
Ava
On Saturday, April 9, 2022 at 9:13:31 PM UTC-7 Ian Lance Taylor wrote:

> On Sat, Apr 9, 2022 at 8:28 PM Aidan Hahn  wrote:
> >
> > I am playing with the generics that were added in go 1.18 and noticed an 
> odd discrepancy that I have not been able to find an authoritative answer 
> to. Consider the following data type, as well as the function defined for 
> it:
> >
> > type Node[T any] struct {
> > Inner T
> > Next *Node[any]
> > }
> >
> > func (n *Node[any]) ListPreTraverse(f func(*Node[any])) {
> > tmpN := interface{}(n)
> > if tmpN, ok := tmpN.(*Node[*Node[any]]); ok {
> > tmpN.Inner.ListPreTraverse(f)
> > } else {
> > f(n)
> > }
> > n.Next.ListPreTraverse(f)
> > }
> >
> > This function is a simple attempt to iterate across a generic linked 
> list and call a function on each node in the list (although in this case it 
> may behave more like a tree if inner stores another node). When I went to 
> compile this code I encountered the following error:
> >
> > test.go:64:25: cannot use f (variable of type func(*Node[any])) as type 
> func(*Node[any]) in argument to n.Next.ListPreTraverse
> >
> > To me at least it seems that all the information to validate that the 
> argument fits the type specified in the function call is there, defined in 
> the function header. What am I missing?
>
> The error message is confusing because the "any" used in
> ListPreTraverse is shadowing the "any" used in Node. See
> https://go.dev/doc/faq#types_in_method_declaration. You want to write
>
> func (n *Node[T]) ListPreTraverse(f func(*Node[T])) {
>
> But then you will see that your code has an instantiation cycle,
> violating the restriction described at
>
> https://go.googlesource.com/proposal/+/refs/heads/master/design/43651-type-parameters.md#generic-types
> :
> "A generic type can refer to itself in cases where a type can
> ordinarily refer to itself, but when it does so the type arguments
> must be the type parameters, listed in the same order. This
> restriction prevents infinite recursion of type instantiation."
>
> I don't really understand what you are trying to do here. The type
> assertion doesn't make sense to me. Perhaps this is the code you
> want:
>
> type Node[T any] struct {
> Inner T
> Next *Node[T]
> }
>
> func (n *Node[T]) ListPreTraverse(f func(*Node[T])) {
> f(n)
> if n.Next != nil {
> n.Next.ListPreTraverse(f)
> }
> }
>
> 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/019beabf-a1f5-4aeb-96d4-c121ae3c2252n%40googlegroups.com.


Re: [go-nuts] Self-referential generics?

2022-04-10 Thread 'Axel Wagner' via golang-nuts
You can use

type Comparable[T any] interface {
Cmp(other T) int
}

then *big.Int implements `Comparable[*big.Int]` and you can write

func cmpSort[T Comparable[T]](x []C) { … }

On Sun, Apr 10, 2022 at 7:48 PM Shawn Smith  wrote:

> // ... imagine some comparison sort algorithm
>
> func cmpSort[C Cmpable](x []C) {
> for i, val := range x {
> if i == 0 {
> continue
> }
> _ = val.Cmp(x[i-1])
> }
> }
>
> // Cmpable should include big.Int, big.Float, big.Rat, by virtue of their
> Cmp methods. So how do i define this better?
>
> type Cmpable interface {
> Cmp(other any) int
> }
> // TODO: how do i replace "any" with "this type". "Cmpable" doesn't work
> as that would be any Cmpable, not THIS Cmpable.
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/4f167deb-bf63-43db-9ec9-c4c451c14d09n%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/CAEkBMfFCEkYasOXPu6WNzerHKbJsDeVRfnccL0GzeXX36P_SFw%40mail.gmail.com.


[go-nuts] Self-referential generics?

2022-04-10 Thread Shawn Smith
// ... imagine some comparison sort algorithm

func cmpSort[C Cmpable](x []C) {
for i, val := range x {
if i == 0 {
continue
}
_ = val.Cmp(x[i-1])
}
}

// Cmpable should include big.Int, big.Float, big.Rat, by virtue of their 
Cmp methods. So how do i define this better?

type Cmpable interface {
Cmp(other any) int 
}
// TODO: how do i replace "any" with "this type". "Cmpable" doesn't work as 
that would be any Cmpable, not THIS Cmpable.

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


Re: [go-nuts] Structured configuration in Go

2022-04-10 Thread Andrew Pillar
> I think there are two big advantages to making your application
> consume either plain JSON or YAML configs:
> 1. Everyone is familiar with them
> 2. You can use a more advanced tool like cue or jsonnet to generate
> them

I can see why people would prefer JSON, and I think it's fine for
storing configuration that is edited by the program itself. I don't
think JSON is a very good interface for humans however as it can be
surprisingly verbose at times.

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


Re: [go-nuts] Structured configuration in Go

2022-04-10 Thread Brian Candler
Cue (and jsonnet) come into their own when building large systems built out 
of multiple components; they can create configs for multiple applications 
derived from a shared top-level configuration.  However, the applications 
themselves don't have to understand cue or jsonnet, since both those can 
spit out vanilla JSON.

I think there are two big advantages to making your application consume 
either plain JSON or YAML configs:
1. Everyone is familiar with them
2. You can use a more advanced tool like cue or jsonnet to generate them

I prefer YAML because it's more amenable to direct human management (it 
allows comments, and is less fussy about commas), whilst still being 
compatible with machine-generated JSON configs.

On Saturday, 9 April 2022 at 22:19:07 UTC+1 Andrew Pillar wrote:

> > Out of interest, have you come across CUE?
>
> > 
> I have heard of it, but not explored it in depth. At a glance it seems
> too heavyweight for what I wanted.
>

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


Re: [go-nuts] Statically Typed Context

2022-04-10 Thread Christian von Kietzell
Hi Adam,

thanks for that article. I really like the idea and will try it on one of my
next projects.


Cheers,
Chris

On Thu, Apr 07, 2022 at 01:33:49PM -0700, 'Adam Berkan' via golang-nuts wrote:
> Khan Academy Engineering Blog Post:  
> https://blog.khanacademy.org/statically-typed-context-in-go/
> 
> Khan Academy has been porting our backend from Python to Go.  One thing we 
> hoped to get from it was fewer uses of implicit global resources and 
> request data.  We looked at explicitly passing everything as parameters, or 
> hiding things in the context.
> 
> In the end we decided to extend the context interface to provide access to 
> these global & request elements.  This gives us strongly typed interfaces, 
> with less verbosity than writing every parameter out.
> 
> func DoTheThing(
> ctx interface {
> context.Context
> RequestContext
> DatabaseContext
> HttpClientContext
> SecretsContext
> LoggerContext
> },
> thing string,
> ) {...}
> 
> I've written a whole blog post about the idea, our motivations, and our 
> experience with it.  There's also some sample code available showing the 
> different approaches we considered: https://github.com/Khan/typed-context/
> 
> I realize this is not a wholly uncontroversial idea, but I'd appreciate any 
> feedback.
> 
> Adam
> 
> -- 
> You received this message because you are subscribed to the Google Groups 
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/golang-nuts/2a1928ab-051b-492b-b4a1-154602d4067cn%40googlegroups.com.


-- 
Nothing to see here. Move along.

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