One of the nice things about functional languages is that you’re closer to the mathematical underpinnings of computer programming. Now, maybe you don’t like maths, but then you’ll have to learn to live with a necessary evil, for trying to be serious about programming without taking the plunge into abstract thinking is like wanting to be an astronomer without writing down a single equation. In my experience, both in the industry and as a CS teacher, the ability of abstraction is the most useful and, unfortunately, hardest to find quality when it comes to programming.
I entered the functional programming world some years ago through a golden gate: SICP. It was an amazing journey full of magical moments: recursion, higher-order functions, generics, lazy evaluation, metacircular interpreters, compilers… a journey i have reedited many times afterwards… i still watch a SICP lecture now and then instead of taking my TV to the repair shop.
Among those moments, one that i specially recall is my first encounter with Church Numerals. I remember staring blankly for quite a while to the code in exercise 2.6:
(define zero (lambda (f) (lambda (x) x)))
(define (add-1 n)
(lambda (f) (lambda (x) (f ((n f) x)))))
And then something clicked in, and i’ve been amazed ever since. Of course, Church numerals are just the tip of the iceberg: from there i went to learn Lambda Calculus, and realized that there were powerful and deep principles at play underneath that fun hacking hobby of mine.
Things can get pretty hairy from here. If you think that the above lambda tricks are old hat and not worth such a fuss, take a look at the impressive fireworks of Oleg’s with Lambda Calculus, Scheme and Haskell, including negative numbers, substraction and division: i’m sure you will find them much more fun.