This page shows the source for this entry, with WebCore formatting language tags and attributes highlighted.


Handling Dependencies in Functional Languages


Out of curiosity, I looked up how dependency injection works in functional languages. I stumbled upon this amazing article series---<a href="" author="Scott Wlaschin" source="F# for Fun and Profit">Six approaches to dependency injection</a> ---that presents five different techniques---from very simple and easily applicable to more complex, but potentially robust. The article series applies various abstraction techniques to a program that reads input, processes it, and writes it out again. The reading and writing are impure operations and should be abstracted away to make it easier to reason about and test the actual program logic. The <a href="">first article</a> details <i>Dependency Retention</i> (hard-code everything; appropriate for scripts and POC projects) and <i>Dependency Rejection</i> (make an impure/pure/impure sandwich that collects program logic in a testable "middle"). The next article covers <a href="">Dependency parameterization</a> (passing as parameters and using partial application in a separate abstraction layer). These are all pretty usable techniques. The next two articles---<a href="">The Reader Monad</a> and <a href="">Dependency interpretation</a>---are more...involved. With both, you end up writing a description of your program that you can then execute by passing in the appropriate parameters. The dependencies are separate from the logic---in kind of in a separate layer---but there are drawbacks to these approaches. For one, they are quite complex and require everyone on the team to understand the patterns very well. This is an example of the program description using the <c>Reader</c> monad. <img src="{att_link}f_code.png" href="{att_link}f_code.png" align="none" scale="50%"> The <a href="">final article</a> applies all of these techniques to a slightly more complex problem domain, namely a user-profile update that receives an update request, reads from a database, compares data to determine updates, and sends an email to confirm address changes. This is complex enough that we can see how the techniques scale. As expected, the more complicated but functionally pure <i>Reader Monad</i> and <i>Dependency Interpretation</i> examples take up 2/3 of the implementation and explanation (with the later taking 50% all on its own). All in all, this is impressive work that answered my question superbly. Highly recommended. I've only very lightly summarized the pros and cons and descriptions above. The original author does a superb job of explaining these in much more detail---without repeating himself.