6 ms·
What I'd like to see in Go 2.0
- qaq 5y agoI have much smaller ask struct type elision in function calls
- masklinn 5y agoI have to say I’ve no idea what you mean. In function definitions I’d interpret it as type inference (and would disagree) but you specifically talk about function calls, and consider it a small change. Can you describe what you’re thinking of?
- coder543 5y agoI think I understand what they're asking for. Consider a function that takes in a struct as one of the arguments.[0] Currently, you would have to invoke it like so: svc.GetObjectWithContext(ctx, &s3.GetObjectInput{Bucket: bucket, Key: key}) But... why do you have to type "s3.GetObjectInput"? The function is taking in a concrete type (not an interface) for that argument, and there is only one possible type that you can pass in... so I agree with the person above that it should be possible to elide the type like so: svc.GetObjectWithContext(ctx, &{Bucket: bucket, Key: key}) Go already supports type elision in some places, such as... []someStruct{{Field: value}, {Field: value}} instead of having to type []someStruct{someStruct{Field: value}, someStruct{Field: value}} which would be equally pointless repetition. [0]: https://docs.aws.amazon.com/sdk-for-go/api/service/s3/#S3.GetObjectWithContext https://docs.aws.amazon.com/sdk-for-go/api/service/s3/#S3.Ge...
- morelisp 5y agoI would also love this. The current rules for when you're allowed to elide are nonsensical.
- masklinn 5y agoAh yes, that does make sense, I would agree. That Rust doesn't have that (in any context that I know of) is one of its annoyances,
- qaq 5y agoYep exactly this ^^ thank you for providing great context that I should've added to the comment in the first place!
- Seb-C 5y agoMy biggest annoyance so far is the inability (and inconsistency) to have a one-liner to get a pointer to something else than a struct. I can write x = &Foo{...} but somehow x = &42 and x = &foo() are not allowed, which forces me in some cases to declare useless variables that hurts readability.
- Eun 5y agoI would like to add proper JSON5 support. The template problem is a real problem. I used it once and it was pain and moved away instantly. I would vote for go inside go as a template system. So you can effectively write go code. With the help of yaegi[1] a go templating engine can be build e.g here[2]. [1]: https://github.com/traefik/yaegi https://github.com/traefik/yaegi [2]: https://github.com/Eun/yaegi-template https://github.com/Eun/yaegi-template
- jerf 5y agoYou don't need official Go support for JSON5. Same for templating. The templating library in the standard library isn't anything special, it's just in the standard library. If you don't like it, go get one of the dozens of others on offer. I think there's a number of language communities you can "grow up" in that teach you that things in the standard library are faster than anything else and have had more attention paid to them than anything else, like Python or Perl, because those languages are slow, and things going into the standard library have generally been converted to C. I think that because I look in my own brain and find that idea knocking about even though nobody ever said it to me directly. But that's not true in the compiled languages, of which Go is one. The vast majority of the Go standard library is written in Go. The vast majority of that vast majority isn't even written in complicated Go, it's just in Go that any Go programmer who has run through a good tutorial can read, it's not like a lot of standard libraries that are fast because they are written impenetrably. (Although the standard library may have subtle performance optimizations because it chooses this way of writing it in Go rather than that way, it's still almost entirely straightforward, comprehensible code.) If you want JSON5 or a different template library, go get or write one. The Go encoding/json or text/template don't use any special access or have any magical compiler callouts you can't access in a library or anything else; if you grab JSON5 library (if such a thing exists), you've got as much support for it as JSON or text/template. It's even often good that it's not in the standard library. I've been using the YAML support a lot lately. The biggest Go YAML library is on major version 3, and both of the jumps from 1 to 2 and 2 to 3 were huge, and would have been significantly inhibited if v1 was in the standard library and the backwards compatibility promise applied. v1 definitely resembles encoding/json, but that's missing a lot of things for YAML. If Go "supported YAML" by having v1 in the standard library, everybody would be complaining that it didn't support it well, and by contrast, asking anyone to jump straight to the v3 interface would be an insanely tall ask to do on the first try without any experimentation in the mean time. And I'm not even 100% sure there won't be a v4.
- da39a3ee 5y agoCan someone explain this one? I couldn't see why go gave this result. > What is the value of cp? If you said [A B C], sadly you are incorrect. The value of cp is actually: [C C C]
- makapuf 5y agoin the loop, you set cp[i] to a reference to the variable value. value is the same variable through the loop, with different values copied inside it, first A then B then C. So at the end you have cp having three times a reference to value, with the last value in it, namely C.
- masklinn 5y agoThe "trap" of the snippet is that `cp` is an array of pointers. What it shows is that Go doesn't have a `value` per iteration, it has a single `value` for the entire loop which it updates for each iteration. This means if you store a pointer to that, you're going to store a pointer to the loop variable which gets updated, and thus at the end of the loop you'll have stored a bunch of pointers to the last item. This is most commonly an issue when creating a closure inside a loop, as the closure closes over the binding, and since Go has a single binding for the entire loop all the closures will get the same value.
- lanstin 5y agoThis has suprised me twice, once in my own code where i ended up ot really understand the problem but just mutated the code till it worked and then later when I was helping someone with their code and the way they structured the question made the still suprising answer memorable. A fix wouldn't be unwelcome but it seems it would have a good chance to cause performance regression - a lot more allocated values maybe on a lot of inner loops. I guess escape analysis might help avoid the allovations in the general case. ?
- masklinn 5y ago> A fix wouldn't be unwelcome but it seems it would have a good chance to cause performance regression - a lot more allocated values maybe on a lot of inner loops. I guess escape analysis might help avoid the allovations in the general case. ? It seems unlikely unless the code is already incorrect (aka you're closing over or otherwise leaking the iteration variable). But regardless of how I dislike the current loop's scoping this is a significant semantics change so it would obviously have to be opt-in (and it would hopefully come alongside making range loops less crummy e.g. with an actual iterator interface).
- rowanseymour 5y agoHardly important but I hope that in parts of the std lib where they added support for contexts by adding a `FooContext` func for every `Foo` and latter just calls the former with `context.Background()`.. we can just have `Foo` that takes a context argument.
- JulianMorrison 5y ago> Alternatively, Go 2.0 could implement "frozen" global variables A more general change would be to implement the "var" and "val" distinction that exists in some languages. const x = 1 // x is a compile time alias for the untyped abstract number 1 var x := 1 // define x at runtime to be (int)1, x is mutable val x := 1 // define x at runtime to be (int)1, x is immutable Then the globals can be defined with "val".
- maerF0x0 5y agocould be interesting, however I'd hope for something more visually distinctive that val/var as it took about 2-3 reads for me notice what was even the diff between L2 and L3.
- catlifeonmars 5y agoHow about `mut var`? Edit: this likely wouldn’t fly as it would be completely backwards incompatible
- JulianMorrison 5y agoFair point. "value" and "var" then, perhaps?
- maerF0x0 5y agoperhaps, the real details would get hammered out in a proposal.
- tapirl 5y agoNo need to invent a new keyword, it is ok to just use "const": https://github.com/go101/go101/wiki/An-immutable-value-proposal-to-let-Go-support-final-exported-values https://github.com/go101/go101/wiki/An-immutable-value-propo...
- JulianMorrison 5y agoNo, they are very different conceptually. - A const is an abstracted value. - A variable is an allocated piece of memory.
- conaclos 5y agoAbout the optimization of the regex package: a talk is scheduled tomorrow [0] to FOSDEM 2022. [0] https://fosdem.org/2022/schedule/event/go_finite_automata/ https://fosdem.org/2022/schedule/event/go_finite_automata/
- hpx7 5y ago> Go's templating packages should support compile time type checking. Does anyone know of a decent type safe templating package out there (for any language)?
- Strom 5y agoReact with TypeScript. Very popular and unlike Go's templates has proper type checking.
- AtroxDev 5y agoFrom Rob Pike on reddit regarding this post[0]: The and and or functions in the template packages do short-circuit, so he's got one thing already. It was a relatively recent change, but it's there. Non-deterministic select is a critical detail of its design. If you depend on a deterministic order of completion of tasks, you're going to have problems. Now there are cases where determinism might be what you want, but they are peculiar. And given Go's general approach to doing things only one way, you get non-determinism. A shorthand syntax for trial communication existed. We took it out long ago. Again, you only need one way to do things, and again, it's a rare thing to need. Not worth special syntax. Some of the other things mentioned may be worth thinking about, and some of them have already (a logging interface for instance), and some we just got wrong (range). But overall this seems like a list of things driven by a particular way of working that is not universal and discounts the cost of creating consensus around the right solutions to some of these problems. Which is not to discount the author's concerns. This is a thoughtful post. 0: https://old.reddit.com/r/golang/comments/s58ico/what_id_like_to_see_in_go_20/hsvv99z/ https://old.reddit.com/r/golang/comments/s58ico/what_id_like...
- dewey 5y ago> Again, you only need one way to do things, and again, it's a rare thing to need. Not worth special syntax. This really is one of the parts I like the most about Go. It really makes so many things simpler. Discussing code, tutorials and writing it. Every time I'm trying to do something in JS I have to figure out why every guide has a different way of achieving the same thing and what are the implementation differences.
- nightowl_games 5y agoIt'd be nice if he had at least hinted towards what 'the way' is for this problem.
- cle 5y agoIt’s in the article he’s responding to.
- 5y ago
- maccard 5y agoThis is a great post, and I agree with much of what he said (range shouldn't copy - I would love a range that iterates by const-reference by default, to lift a phrase from C++). Deterministic select I hard disagree with. The code in the blog post is race-y, and needs to be fixed, not select. If anything, making select deterministic will introduce _more_ subtle bugs when developers rely on that behavior only to find out in the real world that things aren't necessarily as quick as they are in development.
- sethvargo 5y agoHow would you fix that code?
- assbuttbuttass 5y agoI would write the author's example as follows: for ctx.Err() == nil { select { case <-ctx.Done(): return nil case thing := <-thingCh: // Process thing... case <-time.After(5*time.Second): return errors.New("timeout") } } The extra check for ctx.Err before the select statement easily resolves the author's issue.
- sethvargo 5y agoIt really doesn't though. It handles the case where the context might have expired or be cancelled, but there's still a race when entering the select between the ctx.Done() and reading from thingCh. You may end up processing one additional unit of work. In situations where the exit condition is channel-based, this won't work. Additionally, this would only work if you had one predominant condition and that condition was context-based. If you have multiple ordered conditions upon which you want to exit, I can't think of how you'd express that as a range.
- assbuttbuttass 5y agoI'm not sure what you mean. There's always going to be a race condition between ctx.Done and thingCh, just depending on whether there's data available. This race condition is unavoidable. I guess you're thinking of "what if thingCh and ctx.Done activate simultaneously?" There's no real difference between happening simultaneously and happening one after another. As for your other point, you can just write code like select { case x := <-conditionA: return x default: } select { case x := <-conditionB: return x default: } ... But I've personally never needed code like this.
- mieubrisse 5y agoI'd add one more to this list: proper enum types. We use enums heavily to force devs who use our code into good choices, but the options are currently: 1) Use int-type enums with iota: no human-readable error values, no compile-time guard against illegal enum values, no exhaustive `switch`, and no autogenerated ValidEnumValues for validation at runtime (we instead need to create ValidEnumValues and remember to update it every time a new enum value is added). 2) Use string-type enums: human-readable error values, but same problems with no compile-time guards, exhaustive switch, or validation at runtime. 3) Use struct-based enums per https://threedots.tech/post/safer-enums-in-go/ https://threedots.tech/post/safer-enums-in-go/ : human-readable error values and an okay compile-time check (only the all-default-values struct or the values we define), but it still doesn't have exhaustive switch, is a complex pattern so most people don't know to use it, and suffers from the mutable `var` issues the post author detailed. To my naive eye, it seems like a built-in, compile time-checked enum type with a FromString() function would help the community tremendously.
- rplnt 5y ago> no exhaustive `switch` This is what linters will do for you by default. > we instead need to create ValidEnumValues and remember to update it every time a new enum value is added Code generators are first class citizens in go, and writing an icky but reliable test won't be too hard either.
- cle 5y agoPersonally I’ve run into more problems with strict enum types in distributed systems in a team setting, than I have with Go’s lack of them. In that setting, strict enums are usually over-strict and eventually you back yourself into a corner in terms of being able to roll out new enum values. When there’s no clear winner in terms of tradeoffs, I prefer to leave it out of the language like Go has done.
- mseepgood 5y ago> strict enums are usually over-strict and eventually you back yourself into a corner in terms of being able to roll out new enum values. Yes, they are poison for the evolution of a public API.
- bstpierre 5y agoSerious question: what are the odds that go 2 ends up like python 3 and it takes the world over a decade of pain to migrate? (I like both python and go, and I’m still maintaining a sizable body of py2 code.) “Backwards compatibility forever” seems like unnecessary shackles, and the language should be able to grow — I’ve seen some nice proposals for improvements. I just wonder what the strategy is going to be for migrating code from go1 to go2 and how painful that’s going to be.
- lolive 5y agoNot a Go développer here, but let’s take the example of Java when it got (for example) generics or functional features. There was NO going back. These were so fundamental improvements that the past was absolutely outdated as soon as those new features were available. May be the same thing will happen for Go
- chris_overseas 5y agoWhile I agree with what you're saying, that's not the GP's point. They're talking about backwards compatibility, i.e. old code running on new versions. Java has been extraordinarilly good at that (maybe too much so), with the possible exception of Java 9. Try running Java 1.0 code on JDK 17 and it'll probably run fine. Try running Python 2 code on Python 3 and you're generally going to be in for a very rocky ride.
- masklinn 5y agoNot sure how relevant that is, the old code worked fine in post-generics Java.
- lolive 5y agoTechnically yes. But, to me, the question is how developpers are changed by a given paradigm shift. It happened with generics, it happens with functional programming. So an evolution in the language can just make its past versions instantly outdated. [afaiu, python 3 did not do that. But my point is to say that it can happen.]
- randallsquared 5y agoThe issue with the order of range seems like using the same name for satisfying a different requirement: in a template, you're much more likely to want the value than the index, so it makes sense that a looping construct with a single parameter would be putting the value in that parameter. In a loop in normal code, you're more likely to want to do math on the index. So, I'd say the problem is more about punning the name of these two behaviors than the behavior itself being bad.
- masklinn 5y ago> In a loop in normal code, you're more likely to want to do math on the index. It really is not, no. The number of loops using `enumerate` (or working on range / indices directly) in Python or Rust are a small fraction of those just iterating the sequence itself. That would be even more so for Go, which has no higher-level data-oriented utilities (e.g. HOFs or comprehensions, which would usually replace a number of non-indexed loops, and would thus increase the ratio of indexed to non-indexed loops).
- t43562 5y agoEveryone has their own gripes. Modules are what cause me the most pain in Go - especially where they're in github and I need to fork them and now change all the code that references them. I don't know if the problems are even tractable because the way it all works is so incredibly complicated and any change would break a lot. I would like to remove all the "magic" that's built-in for specific SCMS/repository hosting services and have something that operates in a simple and predictable manner like C includes and include paths (although obviously I don't like preprocessing so not that). As for the language, I like the range reference idea but my own minor pet peeve is an issue with pre-assignment in if-statements etc which makes a neat feature almost useless: // This is nice because err only exists within the if so we don't have to // reuse a variable or invent new names both of which are untidy and have potential // to cause errors (esp when copy-pasting): if err := someoperation(); err != nil; { // Handle the error } // This however won't work: func doThing() string { result := "OK" if result, err := somethingelse(); err != nil { // result does not need to be created but err does so we cannot do this. return "ERROR" } return result } I don't have any good ideas about how to change the syntax unfortunately.
- fastest963 5y agoYou should be able to use "replace" to use your forked module instead of the original and you don't have to change anything.
- jatone 5y agounfortunately replace is not supported well with modules. and they are hell bent on not supporting it well.
- cube2222 5y agoI've been doing forks of modules and using replace to use them in my code base extensively. I had 0 problems, it works marvelously. If you're doing some kind of global find/replace on fork, then something's definitely not right.
- vasergen 5y agoNot go developer, just curious about the language and ecosystem and really like it. For me would be nice to have more functional features. For example - explicitly say that a variable is mutable / immutable, preferably have immutability by default. Also native support for map/filter/reduce/etc. Those are good abstraction and it is easier to read than `for loops`, since you don't need to look over shoulders all the time. Guess latest would be easier to add since there is support for generics already.
- jerf 5y ago"Also native support for map/filter/reduce/etc." Native support for them in the context of the existing Go spec will be coming with the next release. To reserve the right to evolve the native support before committing it to the backwards compatibility promise, it will initially appear in the https://pkg.go.dev/golang.org/x/exp https://pkg.go.dev/golang.org/x/exp external repository, but that is the official Go repo for things either too unstable to be included in the standard library, or still experimental. General expectation is it'll be in the standard library in the release after that. It won't be in the standard library, but it's as official as it can be beyond that. I carefully phrased that with "in the context of the existing Go spec", because I think expectations of this support are wildly out of whack with the reality. It's still going to be a very unpleasant style to work in, with many and manifold problems: http://www.jerf.org/iri/post/2955 http://www.jerf.org/iri/post/2955 . I think people will be crazy to turn to that style in Go. Go wasn't just missing generics to support this style, it was missing many things, and "solving" the generics problem still leaves it missing many things.
- mountainriver 5y agoI would really love to see default parameters and struct values. I jump between Python and Go in my day job and Go is a much better language overall but things like this make it painful
- Jeff_Brown 5y agoDefault parameters have always struck me as dangerous. (And for my day job I use Python.)
- mountainriver 5y agoI always hear this argument but I’ve never seen it be dangerous in my day to day. We deal with defaults all the time in programming and it’s generally fine
- geenat 5y agoThis is also my #1. Parameter / Option ergonomics. The current best practice of "functional options" and long function chains results in far too many function stubs ... its a minimum of 3 extra lines per parameter. Parameter structs require a whole extra struct... Borrowing optional / named parameters from Python would cut down length and complexity of Go code drastically.
- geenat 5y agoI'd like to see ergonomics improvements, particularly to function parameters. The current best practice of "functional options" and long function chains results in far too many function stubs ... its a minimum of 3 extra lines per parameter. Parameter structs require a whole extra struct. Suggestion: Just borrow named / optional parameters from Python. It would cut down length and complexity of Go code drastically.
- tgv 5y agoWhat would you need those for? For checking exhaustive type switches? Seems like an extra keyword on "interface" would do the trick.
- deleted 5y ago[deleted]
- exdsq 5y agoIs this comment meant for this article? I can't for the life of me grok what you mean!
- mariusor 5y agoTo expand on the logging improvements, I would like to see a `context.WithLogger` context function, to allow cross package passing of a common logger instance.
- the_gipsy 5y agoProper sum types, if only for proper error handling. The if err != nil dance is extremely verbose and error prone with consecutive checks.
- Jeff_Brown 5y agoThat could also alleviate the no-exhaustive-enum-checking problem mentioned in another top-level comment.
- sdevonoes 5y agoA better template library would be a killer feature. Similar to what PHP has been since forever; the ability to write HTML using all the Go language's features.
- sdevonoes 5y agoI would add: an extended standard library for "common stuff". I don't want to import a third-party library nor write my own "utils.go" to do: func contains(s []int, e int) bool { for _, a := range s { if a == e { return true } } return false }
- Mawr 5y agoIf you need to look up or worse, delete, a value in a slice, then you probably shouldn't be using a slice in the first place. You probably want to replace your slice with a set.
- arccy 5y agosoon-ish https://cs.opensource.google/go/x/exp/+/master:slices/slices.go;l=121 https://cs.opensource.google/go/x/exp/+/master:slices/slices...
- rank0 5y agoI think Golang is awesome, but I have two major gripes that I hope can be fixed: Dependency management: Go mods is a dumpster fire. `go get` and `go install` is finicky and inconsistent across systems. It's difficult to import local code as a dependency. Using mods with replace feels like a shitty hack, and requires me to maintain a public repo for something I may not want to be public. I end up using ANOTHER hack that replaces mod references to private repos and I have to mess with my git config to properly authenticate. I've never used another language that made it so difficult to import local code. Rust's cargo is so much easier to use! Sane dynamic json parsing: Having to create a perfectly specified struct for every single json object I need to touch is terrible UX. Using `map[string]interface{}` is just gross. Again, I think Go should copy the existing rust solution from serde. With serde, I define the struct I need, and when I parse an object, the extra fields just get thrown out. If anyone thinks I'm misunderstanding something, please enlighten me. I hope reasonable solutions already exist and I just haven't found them yet.
- CamouflagedKiwi 5y agoWhat you describe for JSON is already the case in Go; the stdlib json parser does simply throw out any extra fields on deserialisation.
- morelisp 5y agoIn fact it's difficult-to-impossible to get the opposite (only json.Decoder supports a strict mode, and as soon as one intermediate type implements UnmarshalJSON it stops getting propagated).
- tyree731 5y ago> It's difficult to import local code as a dependency. Using mods with replace feels like a shitty hack, and requires me to maintain a public repo for something I may not want to be public. I end up using ANOTHER hack that replaces mod references to private repos and I have to mess with my git config to properly authenticate. With regards to this concern at least go 1.18 is adding workspaces, which should help (https://sebastian-holstein.de/post/2021-11-08-go-1.18-features/ https://sebastian-holstein.de/post/2021-11-08-go-1.18-featur...).
- itgkbcdfhb 5y agoI want golang to stay as minimal as possible. I think of go as 2020s version of C. If you want all the madness of templating, reflection and (arguably) needless features can some privileged PhD student out there please make 2020s C++… go++?
- ternaryoperator 5y agoMine would be a much larger collections library. Having come to go from Java and finding that the standard go library has no trees, no stack, no skip list, etc. was quite a surprise. Possibly the advent of generics will stimulate development of a more robust standard collections library.
- christophilus 5y agoIt does have a doubly-linked list which can easily serve as a stack, though. And it has a heap which is a poor man's replacement for some uses of tree. I've found that I can get quite a bit farther with the built-in Go slices, maps, and lists than I thought. But yeah. Now that generics are in, I do hope they add a handful of common collections. [0] https://pkg.go.dev/container/list@go1.17.6 https://pkg.go.dev/container/list@go1.17.6 [1] https://pkg.go.dev/container/heap@go1.17.6 https://pkg.go.dev/container/heap@go1.17.6 [2] https://pkg.go.dev/container/ring@go1.17.6 https://pkg.go.dev/container/ring@go1.17.6
- pipeline_peak 5y agoI’ve heard Go program’s execution performance is near Java. Is this true because I can’t think of anything more useless than that.
- honkycat 5y agoWhat I would like to see: - Enun Types - A special operator to cut down on `if err != nil { return err }` and just return at that point. - Named arguments, and optional params with defaults - Default values on structs - ...macros? We already have `go generate ./...` ( edit: Removed unformatted source code )
- Jeff_Brown 5y agoSum types would satisfy the first two on that list, as well as making an ergonomic optional type trivial to define.
- christophilus 5y agoThis was a surprisingly good list. Most of these kinds of articles just consist of someone bemoaning the fact that Go isn't Haskell or whatever language they like more. But this is a legitimate list of things that could and should (in my opinion) be changed without turning Go into not-Go.
- deleted 5y ago[deleted]
- synergy20 5y agoMost important items in my plate 1. a unified improved *error* in stdlib with stack trace support. 2. a unified log interface(mentioned) 3. a STL library like c++ 4. shared library support so we dont have 100 static binaries that among them each have 90% of duplicated content. go shall support shared libraries/modules officially.
- cpeterso 5y agoTwo Go 2 proposals that interested me were: * nillability annotations: https://github.com/golang/go/issues/49202 https://github.com/golang/go/issues/49202 * Change int from a machine word size (int32 or int64) to arbitrary precision (bigint): https://github.com/golang/go/issues/19623 https://github.com/golang/go/issues/19623 Sadly the nillability annotations were rejected because they weren't backwards compatible. The bigint change is also unlikely to be accepted because the issue is already five years old and there are concerns about performance.
- usrbinbash 5y agoIf this was implemented: func foo(a, b int) int { return a * b } At compile time, what is the return type of foo? Answer: Unknown. The compiler has no way of determining if the resulting type will be small or big int. This has to be taken into account not just in foo, but in every function calling foo, and every function that is called with the return of foo as a param. One of the best things about golang, is how little "magic" there is. Everything that happens is immediately obvious from the code. An int that is upgraded to a completely different type when it reaches certain values, goes directly counter to that; it would be hidden behaviour, not immediately obvious from the code. Should golang have a builtin arbitrary sized integer type? Maybe. Using math/big can become cumbersome. But a much better solution would be to introduce a new builtin type like `num`
- crnkofe 5y agoOddly enough the list doesn't resonate much with me. I'd love to see better mocking support. Doing mock.On("fun name", ...) is so backwards, confusing and brittle. It's also a great source of confusion for teammates when tests fail. I miss better transaction management. I regularly juggle db, transactions and related interfaces and it's a continuous pain. Then there's the "workaround" for enforcing interface implementation: _ InterfaceType = &struct . This could be easily part of struct def. rather than having it in var section. As was mentioned by others doing x := 5 only to later do JsonField: &x is just a waste of intellectual firepower. Maybe this can be alleviated by generics but the lang should be able to make this a one liner.