3 ms·
> I pretty much agree with all of this. It's easy to disagree with someone who portrays an enemy which doesn't exist. I disagree with this piece everywhere it
by josteink 9y ago
> I pretty much agree with all of this.
It's easy to disagree with someone who portrays an enemy which doesn't exist.
I disagree with this piece everywhere it manages to land somewhere concrete, where its claims can be verified and assessed.
> But if we go deeper, why does the core library have side effects
Let's not get ahead of ourselves in theoretical, non-applied functional programming.
As even Haskellers recognize, all computing would be meaningless if there ultimately was no side effects. In fact, we use computers for their "side-effects".
Sometimes you need side-effects. And sometimes you unit-tests are great way of automatically verifying that you have the right side-effects.
- lmm 9y agoSide effects are by definition outside the thing itself, so they're not really amenable to unit testing; you have to use integration tests.
- bonesss 9y agoJust... small point, but: side effects can be encapsulated, abstracted, and injected to create testable code in "side-effect" heavy situations. Complex running dialog with a hardware serial device, for example, could be rearchitected as a component that has a clear-text dialog with a serial device proxy. This would create functional, side-effect free, testable units of code while also maintaining rich side effects in production (handled by pure integration tests). Essentially: if you _have_ to use an integration test you should almost always be refactoring into something that you handle with unit tests in conjunction with your integration tests. Otherwise you're leaving maintenance developers with too much risk when making changes and no clear separation of your domain model from your application code.
- lmm 9y ago> side effects can be encapsulated, abstracted, and injected to create testable code in "side-effect" heavy situations. Absolutely, but at that point you're moving the side effect out to the boundary and separating it from the logic. Then you can unit-test the logic away from the side effect (but the test of the side effect itself still has to be an integration test).
- BlackFly 9y agoclass AccessCountedInteger { private final int value; private int accessCount = 0; AccessCountedInteger(int value) { this.value = value; } public int getValue() { accessCount++; return value; } public int getAccessCount() { return accessCount; } } This unit has side effects on the method getValue() that impact what is returned by getAccessCount(). While it is contrived, if you are making something following the builder pattern, you will in general have a lot of side effects from all of the methods called on the final build() method. This is quite amenable to unit testing.
- lmm 9y agoThat is not the kind of side effect that Haskellers would acknowledge as necessary (and I'd see it as a bad idea). We can call it a "side effect" but I think there's a qualitative difference between that and something like file I/O or async.
- mempko 9y agoWhy in the hell would you write a unit test in your contrived example? I mean look at it!
- tome 9y ago> In fact, we use computers for their "side-effects". We use computers for their effects. "Side-effects" are things that happen by accident, or incidentally, when we were trying to do something else.
- oblio 9y agoI think his point is that from the functional perspective I/O is a side effect, since you're mutating state. But for almost normal beings the I/O is the thing that actually matters, not the twiddling of bits in computer memory.
- tome 9y agoQuite the opposite. In Haskell I/O is an explicit effect. In impure languages I/O is something that happens as a side effect of just calling a function.