Home > front end >  What is the closest equivalent to a for-loop in Racket-sdp?
What is the closest equivalent to a for-loop in Racket-sdp?

Time:01-18

Is recursion the only way to write something like a for-loop in the Racket dialect sdp ("Schreibe dein Programm!"), in which "(for)" isn't a thing or is there a more "efficient" or simpler way to do so?

What would the closest equivalent to the C loop for(i = 0 , i < 100, i ) look like in Racket-sdp code?

How I did this up until now was:

(: my-loop (natural -> %a))
(define my-loop
    (lambda (i)
        (cond
            [(< i 100) (my-loop (  i 1))] ; <-- count up by one till 99 is reached
            [else "done"] ; <-- end
        )))

(my-loop 0)

EDIT:

It's more of a general question. If I were to write lets say a raket library which contains a general function, that might be used like this:

(for 0 (< i 100) (  i 1) (func i))

in my programs which is a for-loop that runs with a given function as it's "body", would there be a way to implement this properly?

CodePudding user response:

[Professor of the mentioned course here.]

Recursion indeed is the only way to express iterated computation in the Racket dialect we are pursuing. (Yes, that's by design.)

Still, higher-order functions (and recursion) provide all you need to create your own "loop-like control structures". Take the following HOF, for example, which models a repeat-until loop:

(: until ((%a -> boolean) (%a -> %a) %a -> %a))
(define until
  (lambda (done? f x)
    (if (done? x)
        x
        (until done? f (f x)))))

Note that the until function is tail-recursive. You can expect it to indeed behave like a loop at runtime — a clever compiler will even translate such a function using plain jump instructions. (We'll discuss the above in the upcoming Chapter 12.)

CodePudding user response:

You can make a high-order for-loop. Here is an simple example:

(define (for start end f)
  (define (loop i)
    (when (< i end)
      (f i)
      (loop (  i 1))))
  (loop start))

(for 0 10 (λ (i) (displayln i)))

You can make this more general if you use a next function instead of ( i 1) and use a while-predicate? function instead of (< i end).

  • Related