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.
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.