Static _state_ is evil, or any state for that matter. Pure functions FTW. Its funny, I use static private methods a lot for this reason, to signal that they don't have side effects.
Private static method can call public static causing some side-effects. Private static function can also do some in-place modifications on passed objects. I like the idea of methods clearly treated as doing no state transitions.
This kind of generalisation is simply wrong. You can't make any useful with just pure functions. You need to have some point of entry that has some form of state. I agree that we should strive to minimize state though.
@@markovcdIsn’t the math library useful? Isn’t a JSON marshaller useful? There are many usecases for static functions. Constants are also great! As said in this thread, the only evil here is global state which should be replaced by dependency injection when possible.
Every large system has state. The trick is a design to manage it and not to leak it into the core business logic. Declarative functional design is the way to go for the latter.
One use I really like for static methods is to extract the pure helper functions in a piece of business logic and then run unit tests against those static functions. Reason being that, as long as they are pure, they are by far the easiest things to test. You don't need to set up any state, it's just basic input/output testing. If I then need to test the stateful parts of the code, I tend to favor integration tests.
What you call integration are my unit tests. Unit testing as in behaviour level if much more maintainable and efficient to do than technical unit test or implementation detail unit tests
@@captainnoyaux That depends wildly on your tooling and stack. My integration tests typically just involve a test-container for my database. Sometimes there's a message queue involved as well. Quite maintainable. Avoids mocks.
Horror story where I am the authro, when I was in the game development industry the singleton pattern was a big thing, GameManager, LevelManager, *Manager where al singletons, in they were implemented as static type that holds an single instance inside (so, it has a global state). It was really an unpleasant experience, changing one line breaks everything, global state was hard to manage. Luckily (or not..) we had no tests (which I think is still very common in game dev) so determinism wasn't a big of an issue. With time the singleton just became a god class that has everything and referenced from everywhere!!!
i'm always curious about these stories from game dev. everyone always hates on singletons, global state, or god classes for game dev, but literally no one ever shows a full blown non-demo proper game without.
@@CodeOpinionWhat do you think of (custom) smart enums? I personally enjoy very much using them, since they are quite versatile and simplify my code a lot. Do you think they might have any drawbacks though?
Horror story working on a web app which has some of the legacy desktop functions hoisted up to a web service. Now we have multiple web session threads running through the legacy code which was never tested to be thread-safe. Static object variables (at class level) are being changed by parallel web sessions leading to intermittent race condition bugs. Only option is to sync lock the public methods causing scalability issues. So static state can be an issue in multi-threading situations. My understanding of static methods is all threads which pass through the method have their own copy of the local variables declared within the method...but the state of static variables declared on the class is shared, leading to such issues.
I have seen two critical issues in the last few months which were a result of improper use of static variables. Despite that, I totally agree with the nuanced take that they are perfectly fine when used appropriately.
Something to be aware of when you're using static stuff is that you are creating a dependency to that static object without the advantage of using dependency injection.
I built quite a few websites with a severe misuse of static objects in the early 2000's, and apart from two or three occasions - i got away with it! Long live the internet :)
I fall under the mentality that non constant static variables should be configurable by some file or environment variable eventually, if not immediately.
In the Globals Cache example, does it really matter that it is static or not? If for example we inject non static dependency via constructor (as I guess that would be alternative method) we still have the problem that we cannot be sure what is the state 😅 isn’t it more about knowing how the dependency works under the hood?
It's not a problem until you want to enhance it or change it. If you want to have a decorator, for example, that will be invisible if you're using dependency injection but will require refactoring all usages for the static call.
I wish it wasn't so "hard" to create pure static functions in c#, as it's not the default. But thinking about it, functions just taking parameters is in and of itself simpler than a class getting the parameter injected, possibly sharing that parameter over different methods. Then because classes are used, mutable state is just around the corner. Really miss the simplicity when comparing it against languages that don't force you into classes, like typescript, f#, rust, haskell etc
This "static is bad" mentality makes me so angry. Static variables are globals, okay you don't like those, fine. But static methods? Static methods are just functions. *Every* piece of functionality you have should be a static method (function!!!) until you have a *good reason* to attach it to an object. Attaching behaviour to a class before you have a reason to leads to some of the worst designs I've ever had to deal with, like objects with no member variables that you for some reason need to instantiate and allocate just so that you can do a simple calculation (0:13 is a nice example of such a useless object), or member methods that do not need to be member methods. People! Member methods have an invisible 'this' parameter! If you are not using that, THEN DON'T MAKE THAT A MEMBER METHOD, MAKE IT STATIC FFS. You will guaranteed want to use that functionality in a situation where you do not have access to the object that you made it a member method of. Why? BECAUSE THE OBJECT YOU ATTACHED IT TO PLAYS NO ROLE IN WHAT THAT METHOD DOES.
You can just as easily have none deterministic / thread unsafe instance methods? IMHO static variables are foremost a potential memory leak, and static methods difficult to mock.
extension methods are just sugar syntax that are more similar to Partial implementations than Singletons and static methods/members. When you call an extension method you call it on an instance of the class you "extend" and handle instance data, not global data (unless you use other global resources)
@@madsxcva extension methods are just static methods with syntactic sugar. You can call them just like normal static methods. There's nothing stopping you from mutating static state in them etc. You just have to be aware that users will not be able to mock it out (without monkeypatching) so be careful what you do in it.
Static variables are bad 99% of the time. Fact. Static methods are fine as long as they are pure (i.e. functions) and are a natural fit for FP. In oop methods inherently take every piece of state in scope of the object as implicit arguments. This means there's no real way to replace those arguments w/o inheritance, which conflicts with static. So yeah, they are kind of bad in this context.
@@sanhomealex he showed an example in the video. The `now()` type functionality is shared global mutable state i.e. the system clock. It makes code unpredictable and difficult to understand. Google "are static variables bad" and read the first result. This is a well-accepted and supported position.