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).
Most recently ive been bit by this with datadog. The Python version does some monkeypatching to inject trace info. The go version you need to inject the trace info explicitly. While the latter takes more setup, it was much easier to understand what was going on and to debug when we ran into issues.
Sounds very familiar. I was a Java developer for a long time, and in that ecosystem adding a library to your project can be enough for code to be activated and run. There are plenty of libraries where the idea is: just include it, magic stuff will happen, and everything works! That is, until it doesn't work. And then you have to try and debug all this magic stuff of how Java automatically loads classes, how these classes are created and run, and what they do. Didn't happen very often, but when it happened usually a full week was wasted with this.
I really prefer spending a bit more time to set it up myself (and learn something about what I'm using in the process) and knowing how it works, than all the implicit magic.
This is why I avoid Python. I started doing Go after looking for few solutions written and Python and I couldn’t use it.
Some magic values inside objects of recursive depth changing dynamically at the runtime. After working for some time with functional languages and languages with non-mutable structures I’m afraid of such features today.
Context is nice because it’s explicit. Even function header spills the detail. `GetXFromName(context.Context, string)` already says that this call will do some IO/remote call and might never return or be subject of cancellation.
I think it's simply survivorship bias. Thousands of people try this and fail. And occasionally you read an article like this, which is like the one in a million who managed to get lucky with their ideas and manage to make it a success. And I think they underestimate how much luck they had.
Luck is a huge factor for sure but I also think it's not as hard as you're making it out to be if you set yourself up for success.
I have four products that make money, built over the course of seven years. None of them really benefit from each other. If it was pure luck and 1/1,000 chance of success I don't think my current portfolio would be possible. (I also have a lot of failures, so I agree there's luck and risk, just not as strong as you're making it out to be)
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).
reply