Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Would you accept that a Haskell function could depend on the streams that are bound into it? Not an individual datum, but the stream itself. I'd argue 'yes', in the same sense that you could depend on some model or factory in OO land. The leap is in the paradigm, functional vs OO.

Behaviors in BEST are a functional programming construct—they project streams of data into a return value. Note that Behaviors are automatically re-evaluated every time one of their dependent States change, which introduces this 'stream' functionality.

I'd argue that these streams are dependencies and that they're being injected into these functions (hence DI,) but honestly, at this point we're just bike-shedding about terminology :-).

I do want to make sure, though, that this functionality is properly communicated, as the State-Behavior relationship is the crux of our framework's design.



Nope, that's still just passing in data, from the point of view of the function receiving the data. Passing data to a function is just a regular old function call.

However, you could consider that the caller of the function could have had the stream injected, depending on the perspective of the rest of the application.

For instance in pseudocode:

    useData = (data) ->
        munge(data) + calculate(data)

    setupPipeline = (input, output) ->
        input
            .pipe cleanup
            .pipe useData
            .pipe format
            .pipe output

    application = ->
        setupPipeline stdin, stdout

    test = ->
        setupPipeline mockInput, mockOutput
Notice how I've included the test case to illustrate how the dependency injection enables testability, which is critical to understanding the concept. Without DI, the setupPipeline method would take no parameters and explicitly hook to stdin/stdout.

Contrast this example with the standard case of regular-old-data-passing:

    useData = (data) ->
        munge(data) + calculate(data)

    application = ->
        useData stdin.getInt()

    test = ->
        assert.equal -1, useData 42
        assert.equal 0, useData 100
        assert.equal 1, useData 99
Note how inversion of control is not necessary to unit test this function, which is the indication that there is no dependency injection going on there.

If you were using dependency injection for the behaviors, it would imply that the injection is not strictly necessary, and you could instead write the function with a hard dependency. Since the behavior just takes data that whole idea is nonsensical. What would it bind to? Nothing. It's just taking data.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: