Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>The standard way to do looping in Scheme is to use tail recursion. In fact, let's say you have this loop:</p> <pre><code>(do ((a 0 b) (b 1 (+ a b)) (i 0 (+ i 1))) ((&gt;= i 10) a) (eprintf "(fib ~a) = ~a~%" i a)) </code></pre> <p>This actually get macro-expanded into something like the following:</p> <pre><code>(let loop ((a 0) (b 1) (i 0)) (cond ((&gt;= i 10) a) (else (eprintf "(fib ~a) = ~a~%" i a) (loop b (+ a b) (+ i 1))))) </code></pre> <p>Which, further, gets macro-expanded into this (I won't macro-expand the <code>cond</code>, since that's irrelevant to my point):</p> <pre><code>(letrec ((loop (lambda (a b i) (cond ((&gt;= i 10) a) (else (eprintf "(fib ~a) = ~a~%" i a) (loop b (+ a b) (+ i 1))))))) (loop 0 1 0)) </code></pre> <p>You should be seeing the <code>letrec</code> here and thinking, "aha! I see recursion!". Indeed you do (specifically in this case, tail recursion, though <code>letrec</code> can be used for non-tail recursions too).</p> <p><em>Any</em> iterative loop in Scheme can be rewritten as that (the named <code>let</code> version is how loops are idiomatically written in Scheme, but if your assignment won't let you use named <code>let</code>, expand one step further and use the <code>letrec</code>). The macro-expansions I've described above are straightforward and mechanical, and you should be able to see how one gets translated to the other.</p> <hr> <p>Since your question asked how about variadic functions, you can write a variadic function this way:</p> <pre><code>(define (sum x . xs) (if (null? xs) x (apply sum (+ x (car xs)) (cdr xs)))) </code></pre> <p>(This is, BTW, a horribly inefficient way to write a <code>sum</code> function; I am just using it to demonstrate how you would send (using <code>apply</code>) and receive (using an improper lambda list) arbitrary numbers of arguments.)</p> <hr> <h3>Update</h3> <p>Okay, so here is some general advice: you will need two loops:</p> <ol> <li>an outer loop, that goes through the range levels (that's your variadic stuff)</li> <li>an inner loop, that loops through the numbers in each range level</li> </ol> <p>In each of these loops, think carefully about:</p> <ol> <li>what the starting condition is</li> <li>what the ending condition is</li> <li>what you want to do at each iteration</li> <li>whether there is any state you need to keep between iterations</li> </ol> <p>In particular, think carefully about the last point, as that is how you will nest your loops, given an arbitrary number of nesting levels. (In my sample solution below, that's what the <code>cur</code> variable is.)</p> <p>After you have decided on all these things, you can then frame the general structure of your solution. I will post the basic structure of my solution below, but you should have a good think about how you want to go about solving the problem, before you look at my code, because it will give you a good grasp of what differences there are between your solution approach and mine, and it will help you understand my code better.</p> <p>Also, don't be afraid to write it using an imperative-style loop first (like <code>do</code>), then transforming it to the equivalent named <code>let</code> when it's all working. Just reread the first section to see how to do that transformation.</p> <p>All that said, here is my solution (with the specifics stripped out):</p> <pre><code>(define (n-loop proc . ranges) (let outer ((cur ???) (ranges ranges)) (cond ((null? ranges) ???) (else (do ((i (caar ranges) (+ i 1))) ((&gt;= i (cadar ranges))) (outer ??? ???)))))) </code></pre> <p>Remember, once you get this working, you will still need to transform the <code>do</code> loop into one based on named <code>let</code>. (Or, you may have to go even further and transform both the outer and inner loops into their <code>letrec</code> forms.)</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload