(defn pascal []
(iterate (fn [row]
(map +' `(0 ~@row) `(~@row 0)))
[1]))
Or if you're going for maximum concision:
(defn pascal []
(->> [1] (iterate #(map +' `(0 ~@%) `(~@% 0)))))
To expand on this: the higher-order-function perspective is to look at your original definition and realize something like: "I'm actually just computing a function f
on an initial value, and then calling f
again, and then f
again...". That's a common pattern, and so there's a function defined to cover the boring details for you, letting you just specify f
and the initial value. And because it returns a lazy sequence, you don't have to specify n
now: you can defer that, and work with the full infinite sequence, with whatever terminating condition you want.
For example, perhaps I don't want the first n
rows, I just want to find the first row whose sum is a perfect square. Then I can just (first (filter (comp perfect-square? sum) (pascal)))
, without having to worry about how large an n
I'll need to choose up front (assuming the obvious definitions of perfect-square?
and sum
).
Thanks to fogus for an improvement: I need to use +'
rather than just +
so that this doesn't overflow when it gets past Long/MAX_VALUE
.