Decent enough explanation of recursion. Why not take it further and produce a more general solution? In JavaScript I'd write something like this: function recurseBetween(start, end, callback) { // Create a recursive function // which checks the limits and calls the supplied callback var recursiveCallback = function(i) { // Call the original callback callback(i); // If we're at the end, stop if(i >= end) { return; } e…
Here's a completely abstracted version, but I'm certain it's less clear to use ;) function recurseBetween(initial, hasEnded, modify, callback) { // Overwrite the callback with a recursive version: var recursiveCallback = function(i) { // Call the original callback callback(i); // If we're at the end, stop if(hasEnded(i)) { return; } else { // Else increment and recurse recursiveCallback(modify(i)); } }; // Start recu…
(define (unfold p f g seed)
(if (p seed)
'()
(cons (f seed) (unfold p f g (g seed)))))
And how you would call it to print "Hello world!" 100 times: (unfold (lambda (x) (> x 100))
(lambda (x) (display "Hello world"))
(lambda (x) (+ x 1))
1)
'p' is your predicate. It determines when to stop unfolding. It takes the current value ('seed') and returns a boolean that's True when you're done. It's your 'hasEnded'.'f' is what to do for each 'seed' value. In this case, it ignores the current value and just prints "Hello world". It's your 'callback'.
'g' maps each 'seed' value to the next 'seed' value. It's your 'modify'.
'seed' is the initial state for the unfold. It's your 'initial'.
-----
There are a couple other caveats to do with this being an expression rather than a statement, but it doesn't really matter right now. There are a million other cool things about unfolds (and folds, and other higher-order functions), but I'm not sure I could conscionably point you in the right direction since they lead to dangerous places.
Speaking of which, here is an unfold in Haskell, where it may (may) be clearer:
unfold p f g seed | p seed = []
| otherwise = x:xs
where
x = f seed
xs = unfold p f g (g seed)
sequence_ $ unfold (>100) (const $ print "Hello world!") (+1) 1
I say 'an' unfold, because there are a whole bunch of cool ways to do it (and some of them look nothing like this).