
Ask HN: Thinking in Functional programming - justlearning
So, I am working thru the "programming clojure" book. My first lisp language.<p>I have been finding it very difficult to implement simple problems. I have become familiar with the syntax (got over the = operator typing every other place from my finger memory). While I am comfortable, I feel like I know few keywords without knowing where to use, akin to learning a new language - saying hi, bye, but unable to form a sentence. That is my ponder stop..almost pushes me into procrastination mode<p>How do I <i>Think</i> in Functional. I catch myself thinking oops(i think of classes,methods..)and i correct myself and end up with something procedural like.<p>With ref to Uncle Bob's link below , how do I think "inside out"?<p>II) instead of having another question, I thought of asking it as a sub question from the same link below - TDD in clojure. for one, I don't see a mock object ever created in clojure...please correct me.<p>I was wondering how to do "TDD" in LISPy languages.<p>http://blog.objectmentor.com/articles/2009/07/19/uncle-bob-jsps-learning-clojure
======
ntoshev
I think most functional programmers don't use TDD. Instead, they write little
functions (and macros) that do useful things and approach the problem bottom
up, constantly trying things out on the REPL and rewriting the code they have
already written.

This way of programming seems incompatible with TDD and I would recommend
practicing it in order to start thinking functional.

Paul Graham talks about it here:

<http://www.paulgraham.com/progbot.html>

I don't program in Lisp or any other functional language, but I use this style
a lot programming in Python and code ends up being pretty functional.

------
diiq
I second the call to SICP; it is, admittedly, _very_ hard to deal with not
using recursion after reading the first few chapters, but even outside of
that, it will change the way you program.

Reading SICP is like taking a freezing shower; it's a bit of a shock at first,
but afterward everything is crisp and clear. Colors are brighter and love is
lovelier after you read SICP.

Ok, maybe it's not gold-and-bunnies good, but it's pretty good, and should
help remove your cognitive stumbling block.

~~~
projectileboy
I agree, strongly. The best imperative Java code I ever wrote was after I
worked through exercises in SICP. The book just taught me new ways to think.
I'd also recommend "The Little Schemer", for the same reason.

~~~
jokull
2nd Little Schemer. Cute but hardcore.

------
apgwoz
I think I'd normally say "read SICP" but Clojure discourages recursion in
favor of it's looping constructs (due to the non-ability to optimize it on the
JVM I'm guessing).

That said, SICP will still teach you to think in terms of HOFs and functions
as abstractions, so it'll definitely help out. And it's free online, so the
only investment is time.

~~~
sctb
I believe that you can replace directly recursive tail-calls with the `recur'
special form to achieve an iterative function manually. If the function is
truly recursive, then Clojure will likely behave much as any Scheme would.

~~~
apgwoz
I haven't looked at the code that gets generated by `recur`, but I'm guessing
it creates a trampoline, and it looks a bit limiting. (e.g. you can't recur
with variadic functions) That said, probably all of the excercises in SICP
could be done with `recur` and `loop,` with a few minor changes. Thanks for
the tip.

------
jm4
I'm kind of in the same boat. There are plenty of resources for learning
Clojure, but I haven't found any that help with the transition from object
oriented programming to functional programming. I read _Programming Clojure_
and I feel like I know the language, but I'm still working on thinking in
terms of functional programming. Interestingly, _Programming in Scala_ has
helped some. The hybrid functional/object oriented approach has helped
introduce functional concepts with a language that doesn't seem so foreign. It
can be difficult to pick up a completely different language (different from
C-like languages, anyway) as well as a new programming model at the same time.
_JavaScript: The Good Parts_ is also good for the same reason.

There's also an F#/C# book scheduled to come out later this year that looks
like it might be good for learning the functional thought process:
[http://www.amazon.com/Functional-Programming-Real-World-
Exam...](http://www.amazon.com/Functional-Programming-Real-World-
Examples/dp/1933988924/ref=sr_1_2?ie=UTF8&s=books&qid=1248098702&sr=8-2)

I found this blog post from Stuart Halloway to be informative as well:
[http://blog.thinkrelevance.com/2008/9/25/pcl-clojure-
chapter...](http://blog.thinkrelevance.com/2008/9/25/pcl-clojure-chapter-17)

~~~
jm4
Stuart Halloway (author of _Programming Clojure_ ) came up with a rewrite of
Uncle Bob's bowling game: <http://github.com/stuarthalloway/clojure-
bowling/tree/master>

------
noss
The Mock objects in TDD are there so that after a test you can check that the
code under test caused side-effects in dependant objects. (At least, most of
the time this is why they exist.)

Functional programming is very much about decoupling "pure functional"
computation and side-effects. Using pattern matching you can quite easily
write a little machine that performs side-effects given different values.
These things are simple and about as useful to unit-test as accessor methods
are in oo code. Static typing checks do fine. Also, if it is broken, it tends
to be severly broken and not lead to undetected or hard-to-find bugs but
simply not work at all.

The interesting code to test is that which is given a bunch of parameters and
returns a value that would instruct the side-effectful machine about what to
do. This function can be tested with lots of inputs, and you check that it
gives the correct instructions (without executing them).

This style of programming exists in OO as well.

Another reason to use Mocks is that they are queried for values that one need
control over to rig the unit test. I.e. just a disguised parameters. FP simply
doesnt do that.

------
crc
Some generic advice:

1\. Read lots of clojure code. There is clojure-contrib which has lots of
little libraries, read through them and see how things are done.

2\. I will second the SICP suggestion, atleast the first few chapters. Bottom
up programming, building layers of abstraction, is a natural way of doing
things in the lisp world.

3\. The REPL is your friend. Having a really good working environment is
crucial to initial learning as well as later development. I would strongly
recommend taking the time to set up one of the clojure working
environments(Slime/VimClojure/Enclojure) as a first thing, if you have not
already done so.

4\. It takes a while, but it gets easier. Keep at it.

~~~
justlearning
"3. The REPL is your friend. Having a really good working environment is
crucial to initial learning as well as later development. I would strongly
recommend taking the time to set up one of the clojure working
environments(Slime/VimClojure/Enclojure) as a first thing, if you have not
already done so."

I spent substantial amount of time setting up every environment mentioned and
ended up with Clojure-Box. I have not tried emacs before; ideally, i should be
trying a new language in a known setup, but I prefer the stability of clojure
box, so i am taking my baby steps in emacs too.

~~~
crc
Been there! :). Clojure was my first lisp and I was learning emacs along with
it. Looking back, emacs was a really good investment. Also, the ability to
develop and debug through remote swank connections is so useful. Slime(with
paredit) and swank bring out the best of lisp development.

------
Confusion
You should be careful you're looking for something that doesn't exist. That
keeps you wondering why you don't find it forever. Perhaps you already have
the hang of it, but the purists are getting you down, making you think you
don't get it. In practice, there is no such thing as purely functional code,
just like there is no such thing as purely object oriented code. If you
succeed at avoiding state/mutability and side effects and end up with (less)
code that you think is easier to understand, then you are simply doing a good
job.

------
spooneybarger
a couple things that i have seen help get into a more functional state of
mind:

make everything you can immutable. find a problem where you can build most of
it without changing 'the state of the world'. function takes data, spits out
answer which is feed into the next.

refactor commonalities from part 1 by passing around functions, closures, etc
etc. all your good functional fun toys.

add your mutable core around the outside.

------
bddbbdb
Little Schemer, then SICP. For sure. As for TDD, take a look at SchemeUnit,
which I've found very handy in testing the exercises in Little Schemer.

SICP is one of the single most valuable and important texts in CS. Little
Schemer is structured as a real training regimen to get your mental muscles
ready to handle that theory.

------
jwinter
Use clojure.test for TDD. There's a bit of documentation here:

<http://java.ociweb.com/mark/clojure/article.html#Testing>

------
jganetsk
Learn how to implement integers, booleans, pairs, tuples, lists, and trees in
lambda calculus (and, more specifically, System F)... and you will be able to
think functionally.

