Live data from Hacker News

Context should go away for Go 2 (2017)

faiface.github.io

121–130 of 176 posts

Re: Context should go away for Go 2 (2017)

#121

This is about an explicit argument of type "Context". I'm not a Go user, and at first I thought it was about something else: an implicit context variable that allows you to pass stuff deep down the call stack, without intermediate functions knowing about it. React has "Context", SwiftUI has "@Environment", Emacs LISP has dynamic scope (so I heard). C# has AsyncLocal, Node.JS AsyncLocalStorage. This is one of those id…

We added exactly this feature to Arc* and it has proven quite useful. Long writeup in this thread:

https://news.ycombinator.com/item?id=11240681 (March 2016)

* the Lisp that HN is written in

Re: Context should go away for Go 2 (2017)

#122
post #114

Earlier quoted context omitted.

The documentation is probably the best resource to start with the concept and how it works / what the goals are: https://doc.rust-lang.org/edition-guide/editions/index.html For example, https://doc.rust-lang.org/edition-guide/rust-2021/warnings-p... - code that produced a lint warning in the 2018 edition produces a compiler error in the 2021 edition. That would be something that can't be done in a backwards compatibl…

As stated before, the documentation in both languages was already consulted. It did not clear up how Rust is any different than Go in this regard. Consider a simple example from the Go documentation: Support for numeric underscores, which was not a part of the original language and later included in a 'new edition' of Go. i := 10_000_000 Using the 1.13 or later version of the gc compiler, if your go.mod specifies any…

Sorry to have disappointed you. I don't walk, talk, or sleep either Rust or Go, but was trying to provide some resources to help in case you hadn't seen them yet.

One difference I noticed in the docs is in the Go Reference it says the "go" line of the "go.mod" has to be greater than or equal to the go line of all that modules dependencies, if the go line is 1.21 or higher, so a module for 1.21 can't depend on a module for 1.22 [1]

That restriction doesn't apply for Rust, a library using the 2015 edition can use a dependency that uses the 2018 edition, for example.

That's just one difference I noticed in the implementation. The goals seem very similar if not the same

[1] https://go.dev/doc/modules/gomod-ref#go

Re: Context should go away for Go 2 (2017)

#123

> If you use ctx.Value in my (non-existent) company, you’re fired This is such a bad take. ctx.Value is incredibly useful for passing around context of api calls. We use it a lot, especially for logging such context values as locales, ids, client info, etc. We then use these context values when calling other services as headers so they gain the context around the original call too. Loggers in all services pluck out v…

Let me try to take the other side: `ctx.Value` is an `any -> any` kv store that does not come with any documentation, type checking for which key and value should be available. It's quick and dirty, but in a large code base, it can be quite tricky to check if you are passing too many values down the chain, or too little, and handle the failure cases. What if you just use a custom struct with all the fields you may ne…

Because you should wrapp that in a type safe function. You should not use the context.GetValue() directly but use your own function, the context is just a transport mechanism.

Re: Context should go away for Go 2 (2017)

#124
post #85
post #73

Earlier quoted context omitted.

As a veteran of a large scala project (which was re-written in go, so I'm not unbiased), no. I was generally not happy. This was scala 2, so implicit resolution lookup was a big chunk of the problem. There's nothing at the call site that tells you what is happening. But even when it wasn't hidden in a companion object somewhere, it was still difficult because every import change had to be scrutinized as it could caus…

> There's nothing at the call site that tells you what is happening. A decent IDE highlights it at the call site. It's definitely an abusable feature, but I find it very useful. In most other languages you end up having to have completely invisible parameters (e.g. database session bound to the thread) because it would be too cumbersome to pass them explicitly. In Scala you have a middle ground option between complet…

I'm not sure what you consider a decent scala ide, but it was a problem with IntelliJ in several of our code bases, and I'd have to crawl the implicit resolution path.

I eventually opted to desugaring the scala completely, but we were already on the way out of scala by that point

Re: Context should go away for Go 2 (2017)

#125
post #114

Earlier quoted context omitted.

As stated before, the documentation in both languages was already consulted. It did not clear up how Rust is any different than Go in this regard. Consider a simple example from the Go documentation: Support for numeric underscores, which was not a part of the original language and later included in a 'new edition' of Go. i := 10_000_000 Using the 1.13 or later version of the gc compiler, if your go.mod specifies any…

Sorry to have disappointed you. I don't walk, talk, or sleep either Rust or Go, but was trying to provide some resources to help in case you hadn't seen them yet. One difference I noticed in the docs is in the Go Reference it says the "go" line of the "go.mod" has to be greater than or equal to the go line of all that modules dependencies, if the go line is 1.21 or higher, so a module for 1.21 can't depend on a modul…

Thanks for trying. But it is the "which is very different to what go has now settled on" that we are trying to get to the bottom of. It appears from your angle that you also conclude that Go has settled on the very same thing, frivolous implementation details aside. Hopefully phire will still return to dumb it down for us.

Re: Context should go away for Go 2 (2017)

#126
post #96

Earlier quoted context omitted.

> It’s not my job to provide you with alternative code. That’s your job. It is not your job to tell me "that is wrong", yet you do it because it's easy. Suggesting an alternative (not necessarily providing the code) is less easy, so you don't wanna do it. That's fine. I just want you to be aware that the former without the latter is pretty much useless.

It is also easy to tell you that you’re wrong if you were to post that you use your forehead to hammer nails into a post. Posting detailed instructions on how to identify, purchase and utilise a hammer isn’t something I need to do, and doesn’t negate the correctness of the initial “don’t do that”.

You've been missing the point of bheadmaster's posts, which (as it seems to me) was to show that "you can compose context-aware code with context-oblivious code (by passing context.Background()), and vice versa with no problems". Bheadmaster gave some proof of concept code showing how to do that. The code might be somewhat inefficient, but that doesn't invalidate the point. If you think there's a more efficient way to compose context-aware code with context-oblivious code, then the best way to make that case would be to explain how to do so.

Re: Context should go away for Go 2 (2017)

#127
post #123

Earlier quoted context omitted.

Let me try to take the other side: `ctx.Value` is an `any -> any` kv store that does not come with any documentation, type checking for which key and value should be available. It's quick and dirty, but in a large code base, it can be quite tricky to check if you are passing too many values down the chain, or too little, and handle the failure cases. What if you just use a custom struct with all the fields you may ne…

Because you should wrapp that in a type safe function. You should not use the context.GetValue() directly but use your own function, the context is just a transport mechanism.

If it is just a transport mechanism, why use context at all ant not a typed struct?

Re: Context should go away for Go 2 (2017)

#128

> It’s very similar to thread-local storage. We know how bad of an idea thread-local storage is. Non-flexible, complicates usage, composition, testing. I kind of do wish we had goroutine local storage though :) Passing down the context of the request everywhere is ugly.

I like explicit over implicit. I will take passing down context (in the sense of the concept, not the specific Go implementation) explicitly everywhere over implicit ("put it somewhere and I'll trust I can [probably, hopefully] get it back later") any day of the week.

I've seen plenty of issues in Java codebases where there was an assumption some item was in the Thread Local storage (e.g. to add some context to a log statement or metric) and it just wasn't there (mostly because code switched to a different thread, sometimes due to a "refactor" where stuff was renamed in one place but not in another).

Re: Context should go away for Go 2 (2017)

#129

> If you use ctx.Value in my (non-existent) company, you’re fired This is such a bad take. ctx.Value is incredibly useful for passing around context of api calls. We use it a lot, especially for logging such context values as locales, ids, client info, etc. We then use these context values when calling other services as headers so they gain the context around the original call too. Loggers in all services pluck out v…

Let me try to take the other side: `ctx.Value` is an `any -> any` kv store that does not come with any documentation, type checking for which key and value should be available. It's quick and dirty, but in a large code base, it can be quite tricky to check if you are passing too many values down the chain, or too little, and handle the failure cases. What if you just use a custom struct with all the fields you may ne…

> `ctx.Value` is an `any -> any`

It did not have to be this way, this is a shortcoming of Go itself. Generic interfaces makes things a bit better, but Go designers chose that dumb typing at first place. The std lib is full of interface {} use iteself.

context itself is an after thought, because people were building thread unsafe leaky code on top of http request with no good way to easily scope variables that would scale concurrently.

I remember the web session lib for instance back then, a hack.

ctx.Value is made for each go routine scoped data, that's the whole point.

If it is an antipattern well, it is an antipattern designed by go designers themselves.

Re: Context should go away for Go 2 (2017)

#130

This is about an explicit argument of type "Context". I'm not a Go user, and at first I thought it was about something else: an implicit context variable that allows you to pass stuff deep down the call stack, without intermediate functions knowing about it. React has "Context", SwiftUI has "@Environment", Emacs LISP has dynamic scope (so I heard). C# has AsyncLocal, Node.JS AsyncLocalStorage. This is one of those id…

Thread local storage means all async tasks (goroutines) must run in the same thread. This isn't how tasks are actually scheduled. A request can fan out, or contention can move parts of the computation between threads, which is why context exists. Furthermore in Go threads are spun up at process start, not at request time, so thread-local has a leak risk or cleanup cost. Contexts are all releasable after their process…

A more correct term is "goroutine-local" storage, which Go _already_ has. It's used for pprof labels, they are even inherited when a new Goroutine is started.
Post reply on HN