DI is generally used to solve one of two problems that are pretty much unique to Java:
Passing a function
If you will pardon my English: What a load of bullshit.
I'm sure it can be used for that as well (i.e. in implementing the delegation pattern, due to lack of delegates and first class functions), but saying that is what it all that is good for simply makes you look inexperienced.
For any system with a reasonable complexity you will find yourself wanting to separate your code into modules. It might be that you want to thoroughly implement SOC (seperation of concerns), it might be that you want your code to be more flexible (i.e. be able to replace a file-store with a db-store later) or simply that you realize that your system is so big, that you need to be able to work with components separately to be able to properly test your modules.
Decoupling initialization from memory allocation
First you criticise Java, then you bring up a point which (usually) is not a very big concern in garbage-collected languages.
Maybe you mean "controlling initialization" which is crucial for testable code, but given how your first point is completely off base I'm not really sure I would give you the benefit of the doubt.
DI is primarily a euphemism for programming in XML
You can implement DI without any XML. And no, for reference, I don't do Java.
I know you can implement it with out XML, I do DI all day long with functions. I just don't call it DI, I call it passing functions. When people talk about DI they're generally talking about using a DI framework. My point is that the concept is trivial enough to implement in the language itself and doesn't require a framework to help 'manage' it.
What problems can be solved with DI that can't be solved by passing a function? Or 'controlling initialization'
Allocation issues are present in GC languages because of the overhead of GC when you could just reinitialize an existing piece of memory. (You also get to keep your L1/L2 caches hot by not initializing new memory when old will do) Allocation has non-trivial costs. This is why using the methods that allow you to pass a byte[] buffer are often more efficient than those that allocate their own buffer. And we're not even getting into the fragmentation that can occur when you're rapidly allocating memory and some of that memory is locked by the OS so it can't be collected.
How is it that DI frameworks are necessary for large code bases yet most operating systems don't have DI frameworks?
When most people writing OO code have a problem, they think 'I know I'll use a DI Framework', now they have two problems.
DI is about passing all that is needed through parameters instead of creating it or using globals - this is completely independent from the type of arguments passed - you can pass functions or scalars or objects or whatever. Of course all that passed stuff is still needed to be created somewhere - so DI is also about having a factory of objects - it creates a lot of objects - but creation alone should be simple (and indeed frequently it can even be automated by using a DI framework).
You ask: "What problems can be solved with DI that can't be solved by passing a function?" - OK, I never thought about it from that side - but how about the problem of globals? How do you solve it by using function passing? Let's say you have a global database connection - if you modify it and pass that connection (or more frequently objects created from it) as a parameter to all code that needs it - that is DI. How function passing fits here?
I know you can implement it with out XML, I do DI all day long with functions.
Non-sequitur. Most .Net DI frameworks (as opposed to DI in Java, or DI without a framework) use configuration in code. This is generally much more readable and flexible than config in XML. Only some of them use functions for some things.
What problems can be solved with DI that can't be solved by passing a function?
Any non-trivial interface implementation will have more than one function.
Let's say I have a core library which defines lots of possible actions for my application. This application will need to work with other applications although only one at a time (in my case, trough COM), however the operations which needs to be done in these applications remain the same. Applications, not one. Operations, not one.
Obviously this calls for a common interface (in a statically typed language) so that the you can make Application-proxy classes which handles the application interaction in a similar way.
Once you have those implemented as classes you typically pass those around, for instance via the constructor when setting up your instance. Even without a DI-framework this is DI.
For this case "passing a function around" would be very impractical as you would have to pass several functions around. You would have to make sure all functions were created at the same time, with closures referencing the same application COM instances etc.
In fact, passing functions around here would make your solution more complex and error-prone with little benefit what so ever.
Don't get me wrong: I love what function-passing enables. I've written tons of code where function-passing is used to simplify the solution and make it more reusable, more elegant and generally better to work with. Being able to pass functions is awesome.
That said, function passing can be considered a primitive and it's not one which solves all problems. DI is for when your problem domain is bigger, more complex and function-passing would be you were only allowed to pass primitive objects (int,string,etc) around as opposed to sending class-instances around.
They are very, very different and if you can't see that difference, you really should step back and take another look.
Allocation issues are present in GC languages because of the overhead of GC when you could just reinitialize an existing piece of memory
Sure. But your argument that this was one of "two" reasons to use DI is most certainly false. I've never seen anyone advocate DI because of memory issues. This is simply not an argument.
How is it that DI frameworks are necessary for large code bases yet most operating systems don't have DI frameworks?
Because you don't need a DI-framework to implement DI in your code. If you think DI needs "frameworks", you are obviously missing the core point about it: It's a way to structure your code.
Totally agree with you re: DI as a way to structure your code.
I tend to start with function passing and yeah, when it gets to 5 functions you start putting them in a class or other structure that allows you to pass them as a unit. I like using tuples to pass gobs functions because it works better with type-inference in F#
I've just never heard it referred to as DI except in OO (Java) circles.
> First you criticise Java, then you bring up a point which (usually) is not a very big concern in garbage-collected languages.
Of course it is for a number of reasons (instance sharing or reusing, caches, registries, ...), and most GC'd languages (significantly, not Java or C#) give separate access to these two operations (allocating an instance and initializing it).
See Ruby (new/initialize), Python (__new__/__init__), Obj-C (alloc, init), etc...
Passing a function
If you will pardon my English: What a load of bullshit.
I'm sure it can be used for that as well (i.e. in implementing the delegation pattern, due to lack of delegates and first class functions), but saying that is what it all that is good for simply makes you look inexperienced.
For any system with a reasonable complexity you will find yourself wanting to separate your code into modules. It might be that you want to thoroughly implement SOC (seperation of concerns), it might be that you want your code to be more flexible (i.e. be able to replace a file-store with a db-store later) or simply that you realize that your system is so big, that you need to be able to work with components separately to be able to properly test your modules.
Decoupling initialization from memory allocation
First you criticise Java, then you bring up a point which (usually) is not a very big concern in garbage-collected languages.
Maybe you mean "controlling initialization" which is crucial for testable code, but given how your first point is completely off base I'm not really sure I would give you the benefit of the doubt.
DI is primarily a euphemism for programming in XML
You can implement DI without any XML. And no, for reference, I don't do Java.