In other words, use a pure dependency-injection style, and ZERO globals.

I'm writing Python and some C++, and I have been doing this for maybe 5-6 years. It takes a little practice to structure your programs like this, but once you know how, it has a lot of benefits.

It's not really idiomatic in those communities either. Python and C++ Libraries use globals all the time, although I think it's becoming less common.

I guess Java programmers have been doing dependency injection for even longer. It probably became popular more than 10 years ago. But I'm not really sure how "pure" the Java ecosystem is. Singletons are banned under this style. Instead, a singleton is just an object you instantiate once in main(), and pass throughout the rest of your program.

I think the problem with Java is lack of free functions. Static methods confuse things too.

The pure-dependency injection style is basically functional programming, requiring state as an explicit parameter.

Have you found a good writeup on using Python like that? I was talking to someone the other day about this, and how it's not that idiomatic or seen as a big deal in Python especially because you can easily swap out globals from the calling / test site by e.g. setting module.Dep = MyDep so that when module's Foo class has a method bar that constructs a new Dep, it gets your MyDep instead.

I was going to write that I don't have a good pointer, but actually I think the idea is basically the "onion architecture" or "clean architecture". I don't recall if I watched all of this talk, but in general I like Brandon Rhodes' PyCon talks :

https://www.youtube.com/watch?v=DJtef410XaM

http://rhodesmill.org/brandon/slides/2014-07-pyohio/clean-ar...

I don't come from a Java background, but I think that many of these ideas originated in the Java community. They came to Python later (if at all), and it's a little funny to see Go struggling with the same thing.

I think I came at it from more of a functional programming perspective, and the style gradually converged with what people were thinking about OOP. I'm not actually of all the details about "clean architecture" and "onion architecture", but they are definitely related to dependency injection.

Basically all your effects and state can be instantiated on the "outside" in main() and passed INWARD. But I don't believe it necessarily has to be pure. I encapsulate all my state, but I don't encapsulate all my side effects, like printing to the screen.

Some people appeared to like this comment, which is somewhat related:

https://news.ycombinator.com/item?id=11841893

I'm not sure how much this will help, but here is 12K+ lines of code I wrote with zero globals:

https://github.com/oilshell/oil

The main directories to look at are core/ and osh/. The main program imports a lot of stuff and wires it together:

https://github.com/oilshell/oil/blob/master/bin/oil.py

(There is a bunch of surface messiness, but the architecture is sound.) I've also written even larger programs with zero globals.

Also, I believe that web frameworks are some of the worst offenders in terms of preventing you from using this style. I don't think I've seen a single web framework that made the handlers easily testable.

I think you may be fighting against the grain in some parts of the Python world using this style... I can do it in certain projects because I'm writing most of the code from scratch, and forking some dependencies.