(let loop ((rule))

In Scheme, there are no looping or iteration constructs, so to sum the numbers from 1 to 10, you might write this:

(let loop ((i 1)
	   (sum 0))
  (if (= i 10)
    sum ; we're done, return the sum
    (loop (+ i 1) (+ sum i))))

Dorai Sitaram refers to this as "named let". It's pretty wierd to look at at first: it looks like a recursive call, and it is (albeit a tail call). But once I'd written a few loops this way, I quit thinking of it as a recursive call and it felt like a loop construct.

— Gordon Weakliem at permanent link

Comments

(let loop ((rule))

Are you sure its not Dorai Sitaram?



I share your sentiment though. In fact, I now think tail recursion is one of the most natural looping constructs there is.



But for things like the above, its handy to have shortcuts. That's why I also like Common Lisp's LOOP macro, despite its ugly non-Lispy syntax. The above example could be rendered as:



(loop for i from 1 below 10 sum i)

Dirk Gerrits at

(let loop ((rule))

No looping constructs?  What about do, from R5RS 4.2.4?



(do ((i 1 (+ i 1))

  (acc 0 (+ acc i)))

  ((>= i 10) acc))



Sometimes do is convenient, but it's certainly no equivalent of Common Lisp's LOOP.



It would be more reasonable to say that the looping constructs can all just be syntactic sugar for function calls and proper tail recursion and can be implemented as simple macros.

T. Kurt Bond at

(let loop ((rule))

Yes, Dirk, that was a typo, I've corrected the spelling.  Thanks for the correction, Kurt.  I should disclaim all this by saying that I'm a Scheme newbie.  After I posted, I realized that there's for-each and map, which are ways of iterating over a list.

Gordon Weakliem at

comments are now closed on this post