3
(define (orderedTriples n)
(set! i n)
(set! j n)
(set! k n)
(while (>= i 0)
   (while (>= j 0)
     (while (>= k 0)
       (printf "(~a, ~a, ~a)" i j k) 
       (set! k (- k 1))) 
     (set! j (- j 1))) 
  (set! i (- i 1))))

So my issue is...I am confused as to how to make while loops work in scheme (I'm very new to this so excuse the syntax if I am WAY off). I typed while into here just for the purpose of working through a problem and to show what I am trying to accomplish. Could anyone help me with a simple recursion example or nested recursion?

ellie0414
  • 83
  • 1
  • 3
  • 8

3 Answers3

6

Depending on the Scheme interpreter in use, there are several ways to implement the required loops. For example, in Racket it's as simple as using iterations and comprehensions:

(define (orderedTriples n)
  (for* ([i (in-range n -1 -1)]
         [j (in-range n -1 -1)]
         [k (in-range n -1 -1)])
    (printf "(~a, ~a, ~a)" i j k)))

The style of programming shown in the question (assuming it worked) is heavily discouraged in Scheme - using mutation (the set! operation) for looping is a big no-no, that's how you'd solve the problem in a C-like language, but in Scheme in particular (and in Lisp in general) there are other constructs for implementing iteration in a program (the solution given by @TerjeD demonstrates the use of do, for instance), and even if such constructs didn't exist, a recursive solution or a solution using higher-order procedures would be preferred. For example, here's another possible solution, using nested mappings with only standard procedures (with the exception of printf, which is non-standard):

(define (range n)
  (if (negative? n)
      '()
      (cons n (range (- n 1)))))

(define (orderedTriples n)
  (for-each (lambda (i)
              (for-each (lambda (j)
                          (for-each (lambda (k)
                                      (printf "(~a, ~a, ~a)" i j k))
                                    (range n)))
                        (range n)))
            (range n)))
Óscar López
  • 232,561
  • 37
  • 312
  • 386
3

You can use the do loop, which is written like this (for the inner loop of your function):

(do ((k n (- k 1)))               ; variable, initialization, and updating form
   ((< k 0))                      ; stop condition, and optionally return value
  (printf "(~a, ~a, ~a)" i j k))  ; body forms

See http://www.schemers.org/Documents/Standards/R5RS/HTML/r5rs-Z-H-7.html#%_idx_138 for further information on the do iteration construct.

CinchBlue
  • 6,046
  • 1
  • 27
  • 58
Terje D.
  • 6,250
  • 1
  • 22
  • 30
1

If you had to, you could do this with recursion.

(define (ordered-triples n)
  (let iloop ((i n))
    (unless (negative? i)
      (let jloop ((j n))
        (unless (negative? j)
          (let kloop ((k n))
            (unless (negative? k)
              (printf "~a ~a ~a\n" i j k)
              (kloop (sub1 k))))
          (jloop (sub1 j))))
      (iloop (sub1 i)))))

Of course, it's easier to use Racket's for* loop.

to_the_crux
  • 257
  • 1
  • 6