Schemeで二重のループってどうやるの?

あるリストについて二重のループを実行したい。
例えば Python で書くとこういうこと。

def loop_double(lis):
    for i in lis:
        for j in lis:
            print [i, j]

loop_double([1, 2, 3])
takatoh@nightschool $ python loop_double.py
[1, 1]
[1, 2]
[1, 3]
[2, 1]
[2, 2]
[2, 3]
[3, 1]
[3, 2]
[3, 3]

すごく簡単そうに見えるけど、Scheme でやってみたらどうやるのかわからなくて悩んだ。ググっても Scheme の二重ループの例は見当たらない。
で、結局こう書いた。

(define loop-double
  (lambda (lis)
    (letrec ((f (lambda (l1 l2)
      (if (null? l1)
          '()
          (append (map (lambda (x)
                    (cons (car l1) (list x))) l2)
            (f (cdr l1) l2))))))
            (f lis lis))))

(for-each print (loop-double '(1 2 3)))

Scheme らしく、ループの中で処理を実行するんじゃなくて引数のリストを返す手続きにしてみた。それはいいんだけど、内側では map を使ってるんで厳密には二重ループじゃないよな。

takatoh@nightschool $ gosh loop-double.scm
(1 1)
(1 2)
(1 3)
(2 1)
(2 2)
(2 3)
(3 1)
(3 2)
(3 3)

まあ、ほしい結果は得られたんでとりあえずは良しとするか。
でもホントはどうやったらいいんだろう?