This is an introductory article to RSA.
All the code snippets of this page are live and interactive powered by the klipse plugin :
Live : The code is executed in your browser Interactive : You can modify the code and it is evaluated as you typeIt will work only if your browser supports EcmaScript6 arrow functions .
Begin with the end in mindThe end result of this article is the recursive implementation of the factorial function without using neither names nor loops.
Here is the code:
->(f){ f[f] }[->(func){ ->(n) { n == 0 ? 1 : n * func[func][n-1]} }][19]As you can check, no mention of any names.
At first, it feels like magic.
Now, we are going to show the 4 step process that leads to this wonderful piece of code.
(We were inspired by this long but awesome article by Mike Vanier .)
The process Step 0: recursive functionLet’s start with the recursive implementation of factorial :
$factorial = ->(n) { (n === 0) ? 1 : n * $factorial[n - 1] } $factorial[10] Step 1: simple generatorLet’s write a function that is a generator of the factorial function:
$factorial_gen = ->(f) { ->(n) {(n === 0) ? 1 : n * f[n - 1]} } nilOne one hand, factorial_gen is not recursive.
On the other hand, factorial_gen is not the factorial function.
But the interesting thing is that if we pass factorial to factorial_gen it returns the factorial function:
$factorial_gen[$factorial][19]Before going on reading make sure you understand why it is true that:
$factorial_gen[factorial] is equivalent to $factorial Step 2: weird generatorNow, we are going to do something very weird: instead of using func , we are going to use (func func) . Like this:
$factorial_weird = ->(f) { ->(n) {(n === 0) ? 1 : n * f[f][n - 1]} } nilThe funny thing now is that if we apply factorial_weird to itself we get the factorial function:
$factorial_weird[$factorial_weird][19]Before going on reading make sure you understand why it is true that:
$factorial_weird[factorial_weird] is equivalent to factorial Step 3: Recursion without namesNow, let’s write down the application of factorial_weird to itself, using the body of factorial_weird instead of its name:
$factorial_no_names = ->(f) { ->(n) {(n === 0) ? 1 : n * f[f][n - 1]} }[->(f) { ->(n) {(n === 0) ? 1 : n * f[f][n - 1]} }] $factorial_no_names[19]And we got a recursive implementation of factorial without using any names!
We gave it a name just for the convenience of using it.
As you can check, this is a completely valid implementation of factorial :
(1..11).map(&$factorial_no_names).to_aDo you understand why this is equivalent to the code we shown in the beginning of the article?
->(f){ f[f] }[->(func){ ->(n) { n == 0 ? 1 : n * func[func][n-1]} }][19]Can you write your own implementation of other recursive functions without names?
Share in the comments your implementation for:
Fibonacci Quicksort max minIn ournext article, we are going to show the Y combinator in action in ruby .