Here's an alternative that I think is clearer and more concise:
fibn =: (-&2 +&$: -&1)^:(1&<) M."0
Compare with the more canonical (pseudo-code) definition:
fib(n) = fib(n-1) + fib(n-2) if n > 2 else n
First, instead of [ ` c @. (>&1) @. (>&1) that gerund uses is better to use ^:(1&<) . For f(n) if cond(n) else n using the conjunction ^: more idiomatic; ^:0 means "do nothing", and ^:1 means "do it once", so the goal is clear. @. better suited for non-trivial behavior.
Secondly, using the & bond / compose connection greatly simplifies the train. Reusing [: and ] rather confusing and opaque. Refactoring using & combines related operations: first, split n into two, namely n-2 and n-1 , and secondly, add fibn these two numbers.
And finally, "0 for list processing and M. for memoizing. M. quite important in terms of performance, since a simple implementation of the canonical definition will over-call fib(2) . You can get your cake (simple definition) and eat it ( good performance) with built-in eternal reminder.
The source for this specific definition is f0b on this page .
source share