3 ms·
Two things: 1. This is overly simplistic. What happens if your IO and logic are by necessity interleaved? Grab X out of DB, grab Y or Z out of DB depending on
by daxfohl 10y ago
Two things:
1. This is overly simplistic. What happens if your IO and logic are by necessity interleaved? Grab X out of DB, grab Y or Z out of DB depending on X's value, etc.? The whole thing just reeks of "ideal case".
2. This is overly complex. All that really needs to be said here is "pull out your pure code when possible". There's nothing special about F# to enable that. The logic in "tryAcceptComposition" is just a function calling other functions; you can do that in C# or even C. The only advantage F# adds here is the piping syntax, which to me only serves to make the code more obtuse. But I guess you couldn't write a three-part series about a single "extract pure function" op.
(This brings up an interesting thought: ReSharper should come up with a way to let you highlight a function and extract the "obviously pure" tidbits automatically).
- yawaramin 10y agoYou may find it interesting to go over a similar conversation I had with the post author a few days ago https://github.com/ploeh/ploeh.github.com/commit/f89c405e92b69c4dfcc65c336a0ff4528f50f029#commitcomment-20681176 https://github.com/ploeh/ploeh.github.com/commit/f89c405e92b...
- daxfohl 10y agoI'll have to learn more about free monads. In general I love F# for doing domain modeling and logic, but I still find OO-style DI better for organizing "services". I've followed ploeh and scott wlaschin for some time and all my attempts to use their DI concepts in my own real-world code have led to code that's less intelligible than IoC with no tangible benefit. It's not for lack of trying, and I think not for lack of intelligence. It just never worked for me. If free monads could provide something better than standard DI, and (and this is a big caveat) still retain decent editor integration (autocomplete, go-to-declaration/implementation), then I'd check it out. But my gut feeling says that it'll end up being a leaky abstraction that will need undue patching up just to maintain it.
- willtim 10y agoF# uses .NET classes and objects for a module system, so your use of Objects for "services" is not surprising. An OCaml programmer is much less likely to miss Objects and DI frameworks, as OCaml has a powerful module system (i.e. module functors). Free Monads can reify an effectful computation, giving flexibility on how it is interpreted. But they are not really a substitute for a good module system.
- daxfohl 10y agoOut of curiosity, OCaml also has traditional classes/interfaces/objects, right? If so, then how do you decide when to use those versus module functors?
- willtim 10y agoAFAIK no one uses Objects in OCaml as the module system is sufficiently powerful. The Mirage project is a good example of using OCaml module functors to specialise components.
- yawaramin 10y agoModules and functors are able to contain type definitions, while classes/objects are not. This makes modules practically much more useful for abstraction.
- daxfohl 10y agoOkay I think I get free monads now. They seem pretty awesome, essentially letting you plug in an interpreter for the function you're going to run. I can see high-level how this would appear to be a great generic DI option--you set up an "interpreter" to handle the statements in your function however you want: for reals, for test, for reals with logging, etc. And automagically everything gets executed exactly how you want with no additional cruft. What makes me cautious about the concept though is that e.g. `do_x_and_y()` would be interpreted differently than `do_x(); do_y()`, even if they were fundamentally the same. While "so what?" is a perfectly valid response, that little tidbit just makes me feel like, while FM's are a very cool abstraction for something, it's not really ideal for DI. It's just something meant for a different level. The article "The Wrong Abstraction" comes to mind.
- codedokode 10y agoHaving 3 dependencies is pretty typical. The dependencies may have their own dependencies too. The special thing about F# is a partial function application that is probably missing in C#.
- daxfohl 10y agoI like the idea of partial application, but in practice I often find it more trouble than it's worth. I find myself spending too much time worrying about "which order to declare function params to allow for greatest utilization of partial application in these different contexts", which ultimately is orthogonal to "write this function, call this function, check in my code", and often makes the code's intention less apparent rather than moreso. I like it in certain purely functional data crunching routines, where it is idiomatic and can often make the code more generic and more intentional, but I've never had much luck doing DI this way. YMMV.
- Roboprog 10y agoIn case of emergency, break glass :-) Wrong language, but here is an example of a mechanism to partially apply the trailing arguments, rather than the more customary leading arguments: http://ramdajs.com/docs/#partialRight http://ramdajs.com/docs/#partialRight And finally, if something in the middle is the thing that needs to be nailed down, you can simply write a one liner function to provide the fixed thing and pass in the rest. (not really PFA any more at that point, but it will get the job done)