The author argues that Go's context.Context
is overused and often misused as a dumping ground for arbitrary values, leading to unclear dependencies and difficult-to-test code. Instead of propagating values through Context
, they propose using explicit function parameters, promoting clearer code, better separation of concerns, and easier testability. They contend that using Context
primarily for cancellation and timeouts, its intended purpose, would streamline code and improve its maintainability.
This 2017 blog post by Andrey Tarantsov argues vehemently for the removal of the context
package from Go in a hypothetical "Go 2." The author's primary contention is that context.Context
solves a problem that shouldn't exist in the first place: cleanly canceling operations and passing request-scoped values. Tarantsov asserts that these issues are symptoms of a larger, underlying problem: Go's inadequate support for proper dependency injection.
The author begins by acknowledging the widespread use and perceived necessity of context.Context
, but quickly pivots to criticizing its pervasive nature. He argues that its ubiquity is not a sign of good design but rather a band-aid solution for a deeper flaw. The post likens context.Context
to global variables, stating that while they might seem convenient initially, they ultimately lead to tightly coupled, difficult-to-test, and error-prone code.
Tarantsov elaborates on the two main uses of context.Context
: cancellation and passing request-scoped values. He criticizes cancellation for obscuring control flow, making it challenging to understand where and when an operation might be canceled. He provides examples of how error handling and explicit cancellation mechanisms within function calls would be cleaner and more transparent. Regarding request-scoped values, the author argues that passing these values as explicit function arguments is a superior approach, promoting clear dependencies and better testability.
The core of the author's argument revolves around the concept of dependency injection. He posits that if Go had robust, built-in support for dependency injection, the need for context.Context
would evaporate. He envisions a scenario where dependencies, including cancellation signals and request-scoped values, would be injected explicitly into functions and structs, eliminating the need for an omnipresent context object. This would, according to the author, lead to more modular, testable, and understandable code.
Tarantsov concludes by acknowledging the difficulty of removing context.Context
from the language, especially considering its widespread adoption. However, he maintains that for a hypothetical "Go 2," seriously considering its removal and focusing on proper dependency injection mechanisms would significantly benefit the language's long-term health and maintainability. He expresses hope that the Go community would prioritize more robust dependency injection features, ultimately rendering context.Context
obsolete.
Summary of Comments ( 126 )
https://news.ycombinator.com/item?id=42777625
HN commenters largely agree with the author's premise that
context.Context
in Go is overused and often misused for dependency injection or as a dumping ground for miscellaneous values. Several suggest that structured concurrency, improved error handling, and better language features for cancellation and deadlines could alleviate the need forcontext
in many cases. Some argue thatcontext
is still useful for request-scoped values, especially in server contexts, and shouldn't be entirely removed. A few commenters express concern about the practicality of removingcontext
given its widespread adoption and integration into the standard library. There is a strong desire for better alternatives, rather than simply discarding the existing mechanism without a replacement. Several commenters also mention the similarities betweencontext
overuse in Go and similar issues with dependency injection frameworks in other languages.The Hacker News post discussing the blog post "Context should go away for Go 2" contains a significant number of comments engaging with the author's proposition of removing the
context
package from Go. Several commenters offer compelling perspectives both for and against the idea.A recurring theme is the acknowledgement that
context
solves a real problem, particularly around cancellation and deadlines in long-running operations. Some comments express frustration with the pervasiveness ofcontext
and its impact on code readability and function signatures. They argue it has become an almost mandatory parameter, even in situations where it might not be strictly necessary.One commenter suggests that the verbosity and "boilerplate" introduced by
context
might be mitigated by language-level features, proposing syntax sugar or implicit passing of context. Another echoes this sentiment, wishing for a more elegant solution integrated into the language itself. This desire for a more streamlined approach to cancellation and deadlines without the explicit passing ofcontext
is a prominent thread in the discussion.Several comments delve into the specifics of how
context
is used and misused. One points out the common practice of passingcontext.Background()
when no actual context is needed, highlighting this as a symptom of the package's overuse. Another discusses the difficulties in testing withcontext
, suggesting that mocking and managing context values in tests adds complexity.Some commenters push back against the author's proposal, arguing that removing
context
entirely would be detrimental. They highlight its importance in managing resources and preventing leaks in long-running operations. They also point out that while it might be annoying at times,context
provides a standardized and relatively efficient way to handle cancellation and deadlines, which would be difficult to replace.A few comments explore alternative approaches to context management, including proposals for libraries or language features that could achieve similar functionality with less verbosity. One commenter suggests a potential solution involving implicit context propagation based on function call chains.
The overall sentiment seems to be a mixed bag. While many acknowledge the drawbacks of
context
and express a desire for a more elegant solution, there's also a recognition of its value and the challenges in replacing it entirely. The discussion highlights the tension between the practicality ofcontext
and the desire for cleaner, less verbose code in Go.