Live data from Hacker News

Context should go away for Go 2 (2017)

faiface.github.io

71–80 of 176 posts

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

#71
post #66

Earlier quoted context omitted.

> React has "Context", SwiftUI has "@Environment", Emacs LISP has dynamic scope (so I heard). C# has AsyncLocal, Node.JS AsyncLocalStorage. Emacs Lisp retains dynamic scope, but it's no longer a default for some time now, in line in other Lisps that remain in use. Dynamic scope is one of the greatest features in Lisp language family, and it's sad to see it's missing almost everywhere else - where, as you noted, it's…

> against the principles behind statically-typed languages, which all hate implicit things But many statically typed languages allow throwing exceptions of any type. Contexts can be similar: "try catch" becomes "with value", "throw" becomes "get".

Yes, but then those languages usually implement only unchecked exception, as propagating error types up the call tree is seen as annoying. And then, because there are good reasons you may want to have typed error values (instead of just "any"), there is now pressure to use result types (aka. "expected", "maybe") instead - turning your return type Foo into Result.

And all that it does is making you spell out the entire exception handling mechanism explicitly in your code - not just propagating the types up the call tree, but also making every function explicitly wrapping, unwrapping and branching on Result types. The latter is so annoying that people invent new syntax to hide it - like tacking ? at the end of the function, or whatever.

This becomes even worse than checked exception, but it's apparently what you're supposed to be doing these days, so ¯\_(ツ)_/¯.

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

#72

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…

[deleted]

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

#73

Earlier quoted context omitted.

Scala has implicit contextual parameters: https://docs.scala-lang.org/tour/implicit-parameters.html .

I've always been curious about how this feature ends up in day to day operations and long term projects. You're happy with it ?

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 cause large changes in behavior (this caused a non-zero number of production issues).

They work well for anything you would use environment variables for, but a chunk of the ecosystem likes to use them for handlers (the signature being a Functor generally), which was painful

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

#74

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…

A good pitch for dynamic (context) variables is that they're not globals, they're like implicit arguments passed to all functions within the scope.

Personally I've used the (ugly) Python contextvars for:

- SQS message ID in to allow extending message visibility in any place in the code

- scoped logging context in logstruct (structlog killer in development :D)

I no longer remember what I used Clojure dynvars for, probably something dumb.

That being said, I don't believe that "active" objects like DB connection/session/transaction are good candidates for a context var value. Programmers need to learn to push side effects up the stack instead. Flask-SQLAlchemy is not correct here.

Even Flask's request object being context-scoped is a bad thing since it is usually not a problem to do all the dispatching in the view.

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

#75

Earlier quoted context omitted.

Scala has implicit contextual parameters: https://docs.scala-lang.org/tour/implicit-parameters.html .

I've always been curious about how this feature ends up in day to day operations and long term projects. You're happy with it ?

Not OP, but I briefly seconded to a team that used Scala at a big tech co and I was often frustrated by this feature specifically. They had a lot of code that consumed implicit parameters that I was trying to call from contexts they were not available.

Then again I guess it's better than a production outage because the thread-local you didn't know was a requirement wasn't available.

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

#76

> First things first, let’s establish some ground. Go is a good language for writing servers, but Go is not a language for writing servers. Go is a general purpose programming language, just like C, C++, Java or Python Really? Even years later in 2025, this never ended up being true. Unless your definition of 'general purpose' specifically excludes anything UI-related, like on desktop, web or mobile, or AI-related. I…

In an alternative timeline, had Rust 1.0 been available when Docker pivoted away from Python into Go, and Kubernetes from Java into Go, due to having Go folks pushing for the rewrite, and most likely they would have been taken by RIIR instead, nowadays spreading across Python and JavaScript ecosystem, including rewriting tools originally written in Go.

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

#78
post #67

Earlier quoted context omitted.

[flagged]

Thank you for your helpful input.

No worries, this help also generalises to any time you want to add locking/synchronisation or other overheads to a hot code path.

It’s best not to acquire a mutex and launch a goroutine to read 3 bytes of data at a time.

Also, hot tip: you can like… benchmark this. It’s not illegal.

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

#80
post #27

Earlier quoted context omitted.

Passing the current user ID/tenant ID inside ctx has been super useful for us. We’re already using contexts for cancellation and graceful termination, so our application-layer functions already have them. Makes sense to just reuse them to store user and tenant IDs too (which we pull from access tokens in the transport layer). We have DB sharding, so the DB layer needs to figure out which shard to choose. It does that…

An alternative is to add all dependencies explicitly into function argument list or object fields, instead of using them implicitly from the context, without documentation and static typing. Including logger.

> instead of using them implicitly from the context, without documentation and static typing

This is exactly what context is trying to avoid, and makes a tradeoff to that end. There's often intermediate business logic that shouldn't need to know anything about logging or metrics collection or the authn session. So we stuff things into an opaque object, whether it's a map, a dict, a magic DI container, "thread local storage", or whatever. It's a technique as old as programming.

There's nothing preventing you from providing well-typed and documented accessors for the things you put into a context. The context docs themselves recommend it and provide examples.

If you disagree that this is even a tradeoff worth making, then there's not really a discussion to be had about how to make it.

Post reply on HN