4 ms·
I agree that avoiding side effects and global state is a well-known practice (and OO languages have access modifiers, like private, to support it). It's not uni
by 10ren 18y ago
I agree that avoiding side effects and global state is a well-known practice (and OO languages have access modifiers, like private, to support it). It's not unique to functional programming.
Interesting to me was that the reasoning of the article was strikingly close to Dijkstra's "Goto considered harmful", and it makes me wonder if there is some small step that OO languages could take to automatically enforce testable code, in the way that structured programming made gotos safer.
The problem is that side-effects and global state are very useful for making some problems simpler - which is why Erlang has its transactional database mnesia, and Lisp is not purely functional.
Is there a way to structure side-effect/global state to make it entirely testable, without destroying the benefits?
- eru 18y agoMonads are one attempt at solving this problem.
- joe_the_user 18y agoI can't see an argument that Erlang is automatically tested in the body of the link. Perhaps I missed something. All I read was the usual arguments for functional programming - which has some merits but ... whatever. Where is the unit testing connection?
- 10ren 18y agoStarting from the 5th last paragraph: The funny thing is that the OOP world have found one way to manage the complexity and the code-bases that grow ugly: They are using unit tests, and practice the art of writing testable code. ("Testable code" is something that is simple to write unit tests for. )
- akeefer 18y agoThat's also generally the reasoning behind mocks, dependency injection, etc. used by OO unit testing. If something is supposed to, say, update something in the database, you abstract out an interface to the database and mock it out in your tests, and then use interaction tests to verify that your code is calling the right methods on your database abstraction. Of course, it's kind of turtles all the way down, and you then have to test that your production implementation of that database abstraction does, in fact, call through to the database. And of course, there are the ever-raging holy wars in the tdd community around interaction testing versus state testing, and that level of abstraction and mockage can sometimes (in my opinion) make the code harder to follow, so it's always about tradeoffs. But whatever the language you're in, encapsulating side effects and state as much as possible is going to be the way forward, using whatever tools are at your disposal. Some languages tend to make it easier to do that (or harder to avoid doing that) than others.