
Writing unit tests is reinventing functional programming in non-functional languages - jamongkad
http://www.erlang.org/pipermail/erlang-questions/2009-February/041969.html
======
akeefer
I'd say that it's true that the closer you get to pure functional programming
(no state or side effects), the more unit testable your code becomes.

I'd have to take issue, however, with the author's implication that Java
programmers who unit tests are idiots who don't realize they're reinventing
the wheel. Good developers in any language recognize the importance of
avoiding side effects, isolating parts of the system from each other
(including minimizing state), etc. It shouldn't come as a surprise to anyone
that testable code has some common characteristics across all programming
languages. There are differences unique to the language as well, though, and
unit testing in Java also tends to involve use of things like interfaces and
polymorphism that are distinctly OO concepts as well.

And of course, unit testing isn't just for those "overly complicated" Java
applications; it's for any type of system in any language. The author seems to
me to imply that somehow unit testing is uniquely a requirement of Java
systems that Erlang systems somehow don't need.

~~~
10ren
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?

~~~
joe_the_user
I 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
Starting 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. )_

------
nostrademons
This actually is what drew me to functional programming in the first place.
I'd recently been on a unit testing kick, and figured that if you get rid of
mutable state and have function outputs depend only upon inputs, your code
suddenly becomes much easier to unit test.

------
arebop
Referential integrity in code-under-test is convenient for unit testing, so
unit tests encourage (re)discovery of functional style by programmers who are
working in non-functional languages.

But unit tests also have value in programs that are written in functional
languages and in a functional style. Unit tests reinforce essential properties
of the program and thereby formalize the accidental/essential boundary. They
can provide guidance about how API elements are intended to be used together.
They can present elements and properties of a program in an order that is best
for explanation (they can be a crude form of literate programming). So, it's
wrong to reduce unit testing to functional programming.

------
neilk
Look up the technique of "dependency injection" sometime. This is all the rage
among Java consultants, their favorite technique to make things testable. It's
an elaborately disguised way of saying "let's rewrite this function so it
obtains all its state from the caller". In other words, functional
programming.

In cases where passing the same list of initialized objects up and down the
call stack becomes tedious, Google's Java people have invented frameworks like
Guice. This makes dependency injection appear to happen by magic.

~~~
vlisivka
Dependency Injection allows to assemble program on the fly. It allows to
assemble programs written in different styles, including functional.

Look at Spring Dependency Injection Framework for example. It supports lot of
libraries, which are written in traditional style.

~~~
DannoHung
I don't mean to be snarky, but that sounds a lot like passing a closure and
maybe some other state in.

I don't really agree with the OP's point in any case. Even if I have an
entirely purely functional library, I still need to unit test it to make sure
it does what I think it will and that it observes the edge cases I _know_ of
correctly and further so that I can regress it if I need to make changes,
maybe for performance reasons at some point.

I mean, it is nice to reduce state in your code as much as possible, but its
not always practical or efficient. I think it's great that people are getting
more excited about Functional Programming because I believe that there are a
lot of great techniques that become available when you understand it, but all
that imperative knowledge is still going to have its place at the end of the
day. After all, writing an in-place quicksort is always going to end up
involving imperative directions to the computer!

~~~
niv
Maybe you should try reading a bit about dependency injection. It is a
declarative way to assembly pieces of software (in this case, objects) that
have no knowledge of each other. You can do it manually, but this is an easier
way to do it.

------
jcbozonier
So... I am an avid TDD/Unit Test/BDD guy. I've been gravitating towards BDD
lately and honestly I don't DI everything. Really if I'm just BDD-ing a layer
I just need to DI the fringe dependencies, the things that would cause me to
be dependent on other whole systems or sub-systems (think File I/O, Active
Directory, Web Services, etc). My object still contains a lot of state.

I think saying that unit tests cause us to reinvent FP is a bit of a stretch.
I do think that saying that unit testing causes us to write better code and we
borrow heavily from many programming paradigms (DBC, FP, OOP, DSLs, etc) in
order to write that better code.

~~~
lacker
I think you have overdosed on acronyms.

~~~
darkxanthos
So... I am an avid Test Driven Development/Unit Test/Behavior Driven
Development guy. I've been gravitating towards Behavior Driven Development
lately and honestly I don't Dependency Inject everything. Really if I'm just
Behavior Driven Develop-ing a layer I just need to inject the fringe
dependencies, the things that would cause me to be dependent on other whole
systems or sub-systems (think File Input/Output, Active Directory, Web
Services, etcetera). My object still contains a lot of state.

I think saying that unit tests cause us to reinvent functional programming is
a bit of a stretch. I do think that saying that unit testing causes us to
write better code and we borrow heavily from many programming paradigms
(Design By Contract, Functional Programming, Object Oriented Programming,
Domain Specific Languages, etcetera) in order to write that better code.

:)

------
sdp
Interesting point, although I would argue that writing unit tests is more like
reinventing Design by Contract.

~~~
gnaritas
Not really, contracts can't send in invalid data to see what happens and
ensure the proper actions are taken.

Contracts don't prevent the need for tests, they simply augment them.
Contracts only state assumptions about how code should behave, but they don't
make sure those assumptions are correct, only tests can do that.

~~~
wlievens
Upvoted you after some baffoon voted you down for no apparent reason.

Seems like downvoting because of disagreement is getting more and more popular
these days.

------
jaspertheghost
I really like functional languages while others hate it, but I don't think
functional languages will take off by itself. The reason why functional
languages don't work is that they're they wrong metaphor. Object oriented
programming works because it fits the user model of how to describe actions
and the world.

Features of functional languages will influence PL (Ruby, EMCA script,
Python), server paradigms (map reduce), but I don't think it'll ever go
mainstream by itself.

------
drubio
Better put 'functional programming is reinventing the way unit tests are
written'. Its extremely easier to 'think of' and create unit tests on business
logic that avoids using state and mutable data, as do all functional
languages.

On the other hand, this is pretty much offset because structuring a program (
the one on which the tests will be performed) using a pure functional style is
very hard, especially when its syntax/compiler doesn't enforce it.

Languages like Java which have fields, getter/setter methods and similar
syntax are mine-fields for introducing state and mutable data. Erlang really
forces you to think in functional style given its 'message passing' style, so
unit tests are a snap. In Java and other non-functional languages unit tests
would be just as easy, the problem is avoiding state and mutable data.

Though I would still argue the effort forgone in unit testing, still needs to
be invested designing the actual business logic taking care it doesn't
introduce state and mutable data(non-functional behavior).

------
gaius
Loads of "modern" stuff - unit testing, design patterns, continuous
integration, aspect-oriented programming, etc - is people trying to retrofit
FP ideas back onto OO code.

This is far, far more work than just using a functional language in the first
place!

------
donw
This will sound like a trollish comment, but can anyone point to a modern web-
app written in a purely functional language?

I'm curious how several design problems, such as DB access and authentication,
have been handled...

~~~
kragen
There are some things linked from
[http://www.haskell.org/haskellwiki/Practical_web_programming...](http://www.haskell.org/haskellwiki/Practical_web_programming_in_Haskell)
but I don't know if they're Modern. Maybe they're Postmodern or Futurist or
something.

~~~
joe_the_user
Or maybe they just seem rather, uh, _simple_. If you are saying you this is a
serious programming language, shouldn't you be able to show several large,
complex and commonly used application - _by now_?

I, too, studied fp in grad school, fifteen years ago now. "Where's the beef"
can seem like a cheap but if you have ... beef, it should be easily answered.

------
ibsulon
I appreciate side effect programming, but I really think the java criticism is
unwarranted. The first thing I think of is: "How do you do a CRUD app in your
functional language?"

I enjoyed ML when we were doing it in school. However, I've only worked on one
application that could be translated easily to the functional paradigm. The
rest have parts that would be well suited to functional programming, but the
rest of the program is one giant side effect. Monads aren't the answer there,
they're a workaround.

~~~
joe_the_user
A LOT of "ordinary programming" is moving some messy bits of information from
one place to another, taking into account some messy cases and occasionally
putting information into a third, messy place.

This kind of programming has little mathematical content and little similarity
to the canonical factorial example that every functional programming language
LOVES to give.

Here, functional programming seems to lose its elegant minimalism. Indeed,
when you have a bunch of arbitrary, (meaning random) cases and conditions, no
language can make your code elegant and minimal since your code must contain
the information in the cases and random information is incompressible.

I mean, how would you write a WIN32 GUI in a functional language?

Show me otherwise but I haven't _seen_ the good argument for functional
programming languages as general purpose languages and so the folks dumping
Java don't really seem very much better.

~~~
jrockway
_I mean, how would you write a WIN32 GUI in a functional language?_

Just like you would in any other language?

Functional programming is not different from any other type of programming. It
makes some things easier, but other things are about the same.

I think a GUI app would be easier in, say, Haskell, than Java, for a number of
reasons. The lack of global state will make threading easy, which keeps the
GUI responsive. Abstractions like functional reactive programming will make
the app's implementation cleaner. Finally, if you do it right, most of your
app won't depend on the GUI, and will be very easy to test. (You can do that
last one in any language, of course.)

Assuming your application does something useful, implementing the
algorithmically complex part will be simpler as well.

Anyway, you can't understand the advantages of functional programming from
reading some comments on a social news site. You actually need to try writing
the application -- then you can see exactly what the benefits are, and whether
or not _you_ care about them. If you don't want to invest any effort in
learning, well, that's another issue entirely. (And is really the reason why
many people don't all switch to Haskell. Learning something new is scary!)

------
richcollins
There is no reason that side effects have to be difficult to debug. You can
think of the lookup chain for a variable as being part of a data structure
being passed in to a function. It is just as easy to design a convoluted data
structure that gets passed in to a function as it is to design a convoluted
object hierarchy.

The difference is that you can't get implicit lookups for free in an fp
language unless you implement something like messageSend(name, obj, args).

------
apgwoz
This is unrelated to the post, but I noticed that instead of removing the
email addresses from the thread, they've replaced them with images that are
using a vary standard looking monospace font. I would think that any program
that mentions "OCR" (including the 20 minute template matching hack you could
do in Python with PIL), would be able to harvest addresses from it...

------
llimllib
I'll have to tell those haskell guys to throw quickcheck away then, since they
don't need unit testing...

~~~
sketerpot
Did you just read the headline? Maybe a better phrasing would be "The need for
unit testing is causing OOP guys to write in a functional programming style."

